Files
libreoffice/sw/source/core/undo/undobj.cxx
Kurt Zenker b01573861c CWS-TOOLING: integrate CWS odfmetadata3
2009-09-11 Michael Stahl merge DEV300_m58
2009-09-07 Michael Stahl SwFmtFld::Modify(): do nothing on RES_OBJECTDYING
2009-08-27 Michael Stahl #i91565#, #i91566#: TextPortionEnumerationTest.java: add test document
2009-08-27 Michael Stahl #i91565#, #i91566#: add complex test: TextPortionEnumerationTest.java
2009-08-27 Michael Stahl CLiteral::initialize(): zero-length literals probably not an error
2009-08-27 Michael Stahl #i91565#, #i91566#: offapi: new InContentMetadata and MetadataField services
 adapt TextPortion for InContentMetadata
2009-08-27 Michael Stahl #i91564#: xmloff: load/store xml:id and RDFa for text:bookmark(-start).
2009-08-27 Michael Stahl #i91564#: sw core: add support for xml:id at bookmarks:
 sw::mark::Bookmark: derive from Metadatable.
 SwHistoryBookmark, SaveBookmark: store a MetadatableUndo.
 ndcopy.cxx: lcl_CopyBookmarks(): copy the xml:id.
 SwXBookmark: derive from MetadatableMixin.
2009-08-27 Michael Stahl #i91565#, #i91566#: xmloff: refactor ruby import so nested meta(-field) works:
 remove XMLRubyHint_Impl.
 XMLImpRubyContext_Impl::~XMLImpRubyContext_Impl(): insert ruby directly.
2009-08-27 Michael Stahl #i91565#, #i91566#: xmloff: fix text:meta(-field) import/export:
 new XMLTextParagraphExport::exportTextField() overload for XTextField.
 CreateAndInsertMark(): set xml:id after insertion.
 fix meta(-field) service names, bugs etc.
2009-08-27 Michael Stahl #i91565#, #i91566#: sw text formatting: paint background of meta(-field) body:
 SwFont: add member m_nMetaCount.
 txttypes.hxx: add POR_META.
 atrstck.cxx: handle RES_TXTATR_META(FIELD).
 itrform2.cxx: SwTxtFormatter::WhichTxtPor(): create new class SwMetaPortion.
2009-08-27 Michael Stahl #i91566#: sw text formatting: display meta-field prefix and suffix:
 SwAttrIter::GetAttr(): replace with call to GetTxtAttrForCharAt().
 SwTxtFormatter::NewExtraPortion(): handle meta-field prefix.
 SwTxtFormatter: new member m_nHintEndIndex.
 SwTxtFormatter::WhichFirstPortion(): call TryNewNoLengthPortion().
 SwTxtFormatter::TryNewNoLengthPortion(): new; handle suffix of meta-field.
 SwTxtFormatter::UnderFlow(): UGLY HACK: decrement m_nHintEndIndex.
 SwFldPortion: add flag m_bNoLength: portion has zero length (for suffix).
2009-08-27 Michael Stahl #i91565#, #i91566#: extend text:meta(-field) uno wrapper with XText interface:
 unoobj.hxx: new CursorType CURSOR_META.
 unoobj2.cxx: refactor SwXText implementation to ensure that when the SwXText
  belongs to a SwXMeta, content is always inserted inside the meta(-field).
 unoobj.cxx: new SwXTextCursor::ForceIntoMeta(): cursor stays in meta(-field).
 unometa.hxx: SwXMeta implements XText, forwarding to a member SwXMetaText.
 DocInsertStringSplitCR(), SwX*::attachToRange(), SwX*::DeleteAndInsert():
  use FORCEHINTEXPAND hack to ensure insert into the meta(-field) at the end.
2009-08-27 Michael Stahl #i91565#, #i91566#: add text:meta(-field) uno wrapper to sw:
 fmtmeta.hxx, fmtatr2.cxx: new class sw::MetaField, new sw::MetaFieldManager.
 doc.hxx, docnew.cxx: new SwDoc::GetMetaFieldManager().
 unocoll.hxx,.cxx: new SW_SERVICE_FIELDTYPE_METAFIELD, SW_SERVICE_TYPE_META.
 unomap.hxx,.cxx: new PROPERTY_MAP_METAFIELD.
 unoprnms.hxx: new UNO_NAME_META.
 unoport.hxx: new PORTION_META; add "InContentMetadata" prop to SwXTextPortion.
 new unometa.hxx: new class SwXMeta and SwXMetaField.
 unofield.cxx: SwXFieldEnumeration: include meta-fields.
 unoportenum.cxx: handle RES_TXTATR_META(FIELD) by using a portion list stack.
 unotext.cxx: SwXText::insertTextContent(): handle meta(-field) as attribute.
2009-08-27 Michael Stahl #i91565#, #i91566#: ndhints.cxx: remove sort number from SwTxtAttrNesting
2009-08-27 Michael Stahl #i91565#, #i91566#: add support for hints with end and CH_TXTATR to sw core:
 doc.hxx, docedt.cxx: replace SwDoc::Delete(), DeleteAndJoin(), ReplaceRange()
  with wrappers that split at left-overlapped end+CH_TXTATR hints.
 txatbase.hxx: new member SwTxtAttr::m_bHasDummyChar.
 ndtxt.hxx: rename SwTxtNode::GetTxtAttr() to GetTxtAttrForCharAt().
 ndtxt.cxx: SwTxtNode::CopyText(): copy end+CH_TXTATR hints iff copy CH_TXTATR.
 txtatr2.cxx, thints.cxx: SwTxtMeta gets a CH_TXTATR.
2009-08-27 Michael Stahl #i91565#, #i91566#: add text:meta(-field) to sw core:
 txatbase.hxx: new member SwTxtAttr::m_bNesting.
 hintids.hxx: new ids RES_TXTATR_META, RES_TXTATR_METAFIELD.
 txtatr.hxx: new base class SwTxtAttrNesting.
  new hint SwTxtMeta.
  SwTxtRuby derives from SwTxtAttrNesting.
 txtinet.hxx: SwTxtINetFmt derives from SwTxtAttrNesting.
 new header fmtmeta.hxx: new pool item SwFmtMeta. new class sw::Meta.
 ndhints.hxx, thints.cxx: new method SwpHints::TryInsertNesting().
 thints.cxx: refactoring: BuildPortions() no longer handles Ruby/Hyperlink,
  but TryInsertNesting(), which also handles meta(-field).
 SwTxtNode::InsertItem(): check if the hint is actually inserted.
 ndhints.cxx: sort nesting hints based on sort number.
 ndtxt.cxx: lcl_CopyHint(): handle copy of meta/meta-field.
2009-08-27 Michael Stahl enable expanding hints with m_bLockExpandFlag set:
 add new InsertFlag: INS_FORCEHINTEXPAND.
 add new SetAttrMode: SETATTR_FORCEHINTEXPAND.
 rename SwEditShell::Insert() to Insert2() because changed signature fails
  to compile when SwWrtShell tries to overwrite these non-virtual members...
 SwWrtShell::Insert() sets FOCEHINTEXPAND if range was selected/deleted.
 adapt SwUndoInsert to store flags.
2009-08-27 Michael Stahl change formal parameters of item insertion methods to type SetAttrMode
2009-08-27 Michael Stahl fix incorrect resetting of text attributes in SwUndoInsSection, SwUndoInserts
2009-08-27 Michael Stahl clean up SwTxtNode::CutImpl() and lcl_CopyHint()
2009-08-27 Michael Stahl rename SwDoc::Copy() to CopyRange(), and _Copy() to CopyImpl()
2009-08-27 Michael Stahl rename SwNodes::Move() to MoveRange(), and remove unused parameter
2009-08-27 Michael Stahl rename SwDoc::Move() to MoveRange()/MoveNodeRange()
2009-08-27 Michael Stahl rename SwDoc::Insert() to InsertString(), and remove sal_Unicode variant
2009-08-27 Michael Stahl rename SwDoc::Insert() to InsertPoolItem()/InsertItemSet()/InsertSwSection()
2009-08-27 Michael Stahl rename SwDoc::Replace() to ReplaceRange()
2009-08-27 Michael Stahl remove SwDoc::Overwrite() sal_Unicode variant
2009-08-27 Michael Stahl split up SwDoc::DeleteAndJoin(): factor out DeleteAndJoinWithRedline()
2009-08-27 Michael Stahl rename overloaded SwDoc::Delete() to DeleteRange()/DeleteTOXMark()
2009-08-27 Michael Stahl rename SwTxtNode::Copy() to CopyText()
2009-08-27 Michael Stahl rename SwTxtNode::Cut() to CutText(), and _Cut() to CutImpl()
2009-08-27 Michael Stahl rename SwTxtNode::Delete() to DeleteAttribute()/DeleteAttributes()
2009-08-27 Michael Stahl rename SwTxtNode::Replace() to ReplaceText(), and remove the xub_Unicode variant
2009-08-27 Michael Stahl rename SwTxtNode::Erase() to EraseText()
2009-08-27 Michael Stahl rename SwTxtNode::Insert() to InsertText(), and remove the xub_Unicode variant
2009-08-27 Michael Stahl clean up SwTxtNode::Update()
2009-08-27 Michael Stahl remove SwTxtAttr::RemoveFromPool() and make destructor non-public,
 to be invoked by new method SwTxtAttr::Destroy()
2009-08-27 Michael Stahl ensure that SwDoc::Insert() for item (set) returns success indicator:
 replace SwRegHistory constructor with method InsertItems(), returning bool.
 refactor InsAttr() so that it checks if InsertItems() succeeds.
2009-08-27 Michael Stahl move SwXTextPortionEnumeration from unoobj.hxx to unoport.hxx
2009-08-27 Michael Stahl add missing SolarMutex in SwXTextPortion methods
2009-08-27 Michael Stahl SwXTextPortion: new member m_xTextField (so the TextField property need not
  be returned indirectly via SwUnoCursorHelper).
 factor out function CreateSwXTextField().
2009-08-27 Michael Stahl SwXTextPortion: remove PORTION_CONTROL_CHAR and implementation of XTextField
2009-08-27 Michael Stahl remove obsolete hint SwTxtHardBlank and formats SwFmtHardBlank/SwFmtSoftHyph
2009-08-27 Michael Stahl clean up SwTxtAttr and friends:
 remove many accessor methods for obsolete (due to autofmt) char format items.
 remove unused flag SwTxtAttr::m_bDontMergeAttr.
 MakeRedlineTxtAttr() now dedicated function, no longer calls MakeTxtAttr().
2009-08-27 Michael Stahl remove obsolete attribute SwTxt2Lines
2009-08-27 Michael Stahl SwXTextPortionEnumeration: finish refactoring CreatePortions
 change ExportHints so it always returns a text portion for hint w/ CH_TXTATR.
 remove special case for handling end of paragraph.
 unfortunately had to refactor the fieldmarks export as well (got in the way).
2009-08-27 Michael Stahl SwXTextPortionEnumeration: refactor CreatePortions: frames export
 extract function ExportFrames() from CreatePortions().
 remove (un)dead code that calls evil MovePara(fnParaCurr, fnParaEnd)
2009-08-27 Michael Stahl clean up SwXParaFrameEnumeration
2009-08-27 Michael Stahl CollectFrameAtNode: replace SwDependArr with STL based FrameDependList_t
2009-08-27 Michael Stahl SwXTextPortionEnumeration: tweak refmark/toxmark export
 so ExportHints returns the portion for point marks
2009-08-27 Michael Stahl clean up SwXTextPortionEnumeration:
 prefix members, remove casts, replace SvWeirdArray with STL, etc.
 make CreatePortions() method a function, and remove lots of members.
 extract fieldmarks function from CreatePortions.
2009-08-27 Michael Stahl remove FOREACHUNOPAM_START/END macros
2009-08-27 Michael Stahl clean up SwXTextPortion:
 prefix members, remove casts, etc.
 remove SwXRubyPortion: replace it with another SwXTextPortion constructor
2009-08-27 Michael Stahl #i102541# SwXReferenceMark::InsertRefMark(): use flag SETATTR_DONTEXPAND
2009-08-27 Michael Stahl rename SwTxtNode::Insert to SwTxtNode::InsertHint, and
fix constness in SwTxtNode::InsertItem
2009-08-27 Michael Stahl turn SwTxtNode::MakeTxtAttr() methods into global functions in ndhints.hxx
2009-08-27 Michael Stahl remove obsolete sw/inc/bookmrk.hxx
2009-08-27 Michael Stahl pam.cxx: fix ComparePosition functions (returned wrong result in one case)
2009-08-27 Michael Stahl #i103613# only import RDF metadata on normal open of a document
2009-09-11 kz CWS-TOOLING: integrate CWS impress176
2009-09-08 20:18:24 +0200 sj  r275957 : fixed warning (shadowed variable)
2009-09-08 18:02:05 +0200 cl  r275948 : #i104315# added missing tab pages
2009-09-08 17:35:18 +0200 cl  r275947 : #i104866# fixed angle import
2009-09-08 17:32:53 +0200 cl  r275946 : #i104841# fixed angle import
2009-09-08 17:01:25 +0200 cl  r275943 : #i103935# fixed the SID_EVENTCONFIG mess
2009-09-08 14:32:57 +0200 sj  r275928 : #i104685# only comments
2009-09-07 12:37:36 +0200 sj  r275886 : #i104683# fixed import of bold/italic attributes for normal text shapes
2009-09-04 15:07:46 +0200 sj  r275808 : #104689# fixed bullet color problem
2009-09-03 15:25:07 +0200 sj  r275753 : #160200# added vertical alignment of table cells
2009-09-11 kz CWS-TOOLING: integrate CWS dv14
2009-09-10 15:16:32 +0200 sg  r276035 : #160513# updated wfs scheme to accept ports
2009-09-10 07:41:47 +0200 dv  r276019 : #i104942# Better renaming algorithmen
2009-08-31 13:41:11 +0200 dv  r275604 : #160505# Setting APP1PRODUCTNAME must not overwrite APP1PRODUCTDEF
2009-09-11 kz CWS-TOOLING: integrate CWS jl131
2009-09-02 16:42:40 +0200 jl  r275720 : #i97896#
2009-08-31 13:01:53 +0200 jl  r275599 : CWS-TOOLING: rebase CWS jl131 to trunk@275331 (milestone: DEV300:m56)
2009-07-31 14:35:30 +0200 jl  r274531 : CWS-TOOLING: rebase CWS jl131 to trunk@274203 (milestone: DEV300:m53)
2009-07-23 14:20:32 +0200 jl  r274272 : #i79839# better error text when trying to modify shared layer without having write permission, eg. unopkg add --shared, unopkg remove --shared, unopkg reinstall --shared
2009-07-22 16:38:02 +0200 jl  r274252 : #i97896# localize error message for lock file
2009-07-22 16:37:22 +0200 jl  r274251 : #i80462# unprecise wording in updatedialog
2009-07-22 16:36:06 +0200 jl  r274250 : #i97896# localize error message for lock file
2009-07-22 16:35:20 +0200 jl  r274249 : #i97896# localize error message for lock file
2009-07-22 15:07:30 +0200 jl  r274242 : #i98873# minimum java version is 1.5 since OOo 3.0
2009-09-11 kz CWS-TOOLING: integrate CWS changehc
2009-08-31 19:38:50 +0200 pl  r275633 : remove dbug printf
2009-08-31 17:41:50 +0200 pl  r275623 : CWS-TOOLING: rebase CWS changehc to trunk@275331 (milestone: DEV300:m56)
2009-07-15 19:45:46 +0200 pl  r274028 : #i35482# use HC flag to decide high contrast mode
2009-07-15 17:40:52 +0200 pl  r274020 : #i35482# use HC flag to decide high contrast mode
2009-07-15 17:39:50 +0200 pl  r274019 : #i35482# update autohc correctly in MergeSystemSettings
2009-07-15 17:38:57 +0200 pl  r274018 : #i35482# update autohc correctly in MergeSystemSettings
2009-09-11 kz CWS-TOOLING: integrate CWS notes10
2009-08-24 07:25:57 +0200 mod  r275287 : 2009-07-26 02:38:32 +0200 mod  r274343 : #i#i103645#
2009-07-26 02:01:53 +0200 mod  r274342 : #i103645#
2009-07-26 01:52:42 +0200 mod  r274341 : #i103490#
2009-07-22 08:31:48 +0200 mod  r274215 : #i103373#
2009-07-15 00:55:11 +0200 mod  r273987 : #i101419#
2009-07-14 07:07:55 +0200 mod  r273956 : #i101419#
2009-07-14 07:07:43 +0200 mod  r273955 : #i101419#
2009-07-14 07:02:10 +0200 mod  r273954 : changes from notes9
2009-07-14 06:14:25 +0200 mod  r273953 : #i103476#
2009-09-11 kz CWS-TOOLING: integrate CWS ab70
2009-09-10 15:12:54 +0200 jsk  r276034 : #i85434# - mandatory automatic update test
2009-09-10 15:11:06 +0200 jsk  r276033 : #i85434# - mandatory automatic update test
2009-09-02 09:49:24 +0200 ab  r275698 : #i85434# Dialog Import
2009-09-11 kz CWS-TOOLING: integrate CWS hb32bugs02
2009-09-02 Henning Brinkmann #i102420# revert changes
2009-08-26 Henning Brinkmann merged DEV300_m56
2009-08-19 Henning Brinkmann merged DEV300_m55
2009-08-14 Henning Brinkmann merged changes from wntmsci12
2009-08-12 Henning Brinkmann Implemented NoSpaceEdit constructor and destructor in .cxx to allow compile with debug on wntmsci12.
2009-08-12 Henning Brinkmann Added some SW_DLLPUBLIC to make compilable on wntmsci12.
2009-08-11 Henning Brinkmann #i102420# dbg_out: surround output for SwNodes with <nodes-array>.
2009-08-10 Henning Brinkmann #i102420# rewritten debug output for SwNodes.
2009-08-07 Henning Brinkmann #i102420# debug _MoveNodes: output the destination, too. Break after two iterations.
2009-08-07 Henning Brinkmann #i102420# _MoveNodes: Additionally check if destination index is inside source => false
Check if current range was already handled => loop
Debug output current range
2009-08-06 Henning Brinkmann merged DEV300_m54
2009-08-06 Henning Brinkmann added master fix
2009-08-06 Henning Brinkmann debug output for SwNodeRange
2009-08-04 Henning Brinkmann #i102844# robustness: check for NULL pointer to prevent crash
2009-08-03 Henning Brinkmann #i103475# applied patch and verified
2009-08-03 Henning Brinkmann Removed code preventing build of sw with DEBUG.
2009-09-11 convert-repo update tags
2009-09-10 kz CWS-TOOLING: integrate CWS os2port06dev300
2009-09-05 22:49:00 +0200 ydario  r275858 : #i99588# applied os2port06 diff to DEV300 tree.
2009-09-10 kz CWS-TOOLING: integrate CWS mingwport23
2009-08-29 07:07:53 +0200 tono  r275555 : i#104522: mingw port graphite
2009-08-29 07:07:26 +0200 tono  r275554 : i#104522: mingw port printf format fix
2009-09-10 kz CWS-TOOLING: integrate CWS mh232
2009-08-26 03:52:57 +0200 mh  r275385 : #i102182# FreeBSD patch
2009-08-26 03:43:20 +0200 mh  r275384 : #i101333# patch for FreeBSD
2009-08-26 03:11:20 +0200 mh  r275383 : #i39230
2009-08-26 03:07:51 +0200 mh  r275382 : #i39230# more space for initials field
2009-08-26 02:41:19 +0200 mh  r275380 : #i39230# use vos::osecurity for reading the user name
2009-08-18 22:06:00 +0200 mh  r275130 : #i104243#, line ending problem with newer perl
2009-08-18 21:53:21 +0200 mh  r275129 : #i39230# read initials via getpwnam
2009-08-18 21:34:05 +0200 mh  r275128 : enable CAIROCANVAS for Linux and Mac, #i88613#
2009-08-17 18:02:59 +0200 mh  r275067 : #i95498# make compile with gcc3
2009-09-10 kz CWS-TOOLING: integrate CWS tkr24
2009-09-07 14:31:06 +0200 is  r275898 : #160081# adding NO_LICENSE_INTO_COPYRIGHT
2009-09-10 releng #i10000# change KeyMapping to SingletonRef<framework::KeyMapping>
2009-09-11 convert-repo update tags
2009-09-10 kz CWS-TOOLING: integrate CWS os2port06dev300
2009-09-05 22:49:00 +0200 ydario  r275858 : #i99588# applied os2port06 diff to DEV300 tree.
2009-09-10 kz CWS-TOOLING: integrate CWS mingwport23
2009-08-29 07:07:53 +0200 tono  r275555 : i#104522: mingw port graphite
2009-08-29 07:07:26 +0200 tono  r275554 : i#104522: mingw port printf format fix
2009-09-10 kz CWS-TOOLING: integrate CWS mh232
2009-08-26 03:52:57 +0200 mh  r275385 : #i102182# FreeBSD patch
2009-08-26 03:43:20 +0200 mh  r275384 : #i101333# patch for FreeBSD
2009-08-26 03:11:20 +0200 mh  r275383 : #i39230
2009-08-26 03:07:51 +0200 mh  r275382 : #i39230# more space for initials field
2009-08-26 02:41:19 +0200 mh  r275380 : #i39230# use vos::osecurity for reading the user name
2009-08-18 22:06:00 +0200 mh  r275130 : #i104243#, line ending problem with newer perl
2009-08-18 21:53:21 +0200 mh  r275129 : #i39230# read initials via getpwnam
2009-08-18 21:34:05 +0200 mh  r275128 : enable CAIROCANVAS for Linux and Mac, #i88613#
2009-08-17 18:02:59 +0200 mh  r275067 : #i95498# make compile with gcc3
2009-09-10 kz CWS-TOOLING: integrate CWS tkr24
2009-09-07 14:31:06 +0200 is  r275898 : #160081# adding NO_LICENSE_INTO_COPYRIGHT
2009-09-10 releng #i10000# change KeyMapping to SingletonRef<framework::KeyMapping>
2009-09-11 14:29:45 +00:00

1391 lines
45 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2008 by Sun Microsystems, Inc.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: undobj.cxx,v $
* $Revision: 1.29.52.1 $
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org. If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sw.hxx"
#include <txtftn.hxx>
#include <fmtanchr.hxx>
#include <ftnidx.hxx>
#include <frmfmt.hxx>
#include <doc.hxx>
#include <docary.hxx>
#include <swundo.hxx> // fuer die UndoIds
#include <pam.hxx>
#include <ndtxt.hxx>
#include <undobj.hxx>
#include <rolbck.hxx>
#include <ndnotxt.hxx>
#include <IMark.hxx>
#include <mvsave.hxx>
#include <redline.hxx>
#include <crossrefbookmark.hxx>
#ifndef _UNDO_HRC
#include <undo.hrc>
#endif
#ifndef _COMCORE_HRC
#include <comcore.hrc>
#endif
#include <docsh.hxx>
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(); }
#ifndef PRODUCT
USHORT nRedlineCount;
#endif
};
SV_IMPL_PTRARR( SwUndos, SwUndo*)
SV_IMPL_PTRARR( SwRedlineSaveDatas, SwRedlineSaveDataPtr )
SwUndoIter::SwUndoIter( SwPaM* pPam, SwUndoId 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( SwUndoId nI )
: nId(nI), nOrigRedlineMode(nsRedlineMode_t::REDLINE_NONE),
bCacheComment(true), pComment(NULL)
{
}
bool SwUndo::IsDelBox() const
{
return GetId() == UNDO_COL_DELETE || GetId() == UNDO_ROW_DELETE ||
GetId() == UNDO_TABLE_DELBOX;
}
SwUndo::~SwUndo()
{
delete pComment;
}
void SwUndo::Repeat( SwUndoIter& rIter )
{
rIter.pLastUndoObj = this;
}
String SwUndo::GetComment() const
{
String aResult;
if (bCacheComment)
{
if (! pComment)
{
pComment = new String(SW_RES(UNDO_BASE + nId));
SwRewriter aRewriter = GetRewriter();
*pComment = aRewriter.Apply(*pComment);
}
aResult = *pComment;
}
else
{
aResult = String(SW_RES(UNDO_BASE + nId));
SwRewriter aRewriter = GetRewriter();
aResult = aRewriter.Apply(aResult);
}
return aResult;
}
SwUndoId SwUndo::GetEffectiveId() const
{
return GetId();
}
SwRewriter SwUndo::GetRewriter() const
{
SwRewriter aResult;
return aResult;
}
//------------------------------------------------------------
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().MoveRange( rPaM, aPos, rNds );
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->InsertText( sal_Unicode(' '), aPos.nContent,
IDocumentContentOperations::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->EraseText( aPaM.GetPoint()->nContent, 1 );
}
aPaM.SetMark();
aPaM.GetPoint()->nNode = nNodeIdx;
aPaM.GetPoint()->nContent.Assign( aPaM.GetCntntNode(), nCntIdx );
_SaveRedlEndPosForRestore aRedlRest( rInsPos.nNode, rInsPos.nContent.GetIndex() );
rNds.MoveRange( 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
*/
// --> OD 2007-10-17 #i81002# - extending method:
// delete certain (not all) cross-reference bookmarks at text node of <rMark>
// and at text node of <rPoint>, if these text nodes aren't the same.
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( nsDelCntntType::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( (nsDelCntntType::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* const pFtnHnt =
pTxtNd->GetTxtAttrForCharAt( nFtnSttIdx );
ASSERT( pFtnHnt, "kein FtnAttribut" );
SwIndex aIdx( pTxtNd, nFtnSttIdx );
pHistory->Add( pFtnHnt, pTxtNd->GetIndex(), false );
pTxtNd->EraseText( aIdx, 1 );
}
while( nPos-- && ( pFtnNd = &( pSrch = rFtnArr[ nPos ] )->
GetTxtNode())->GetIndex() >= pStt->nNode.GetIndex() )
{
xub_StrLen nFtnSttIdx = *pSrch->GetStart();
if( !(nsDelCntntType::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* const pFtnHnt =
pTxtNd->GetTxtAttrForCharAt( nFtnSttIdx );
ASSERT( pFtnHnt, "kein FtnAttribut" );
SwIndex aIdx( pTxtNd, nFtnSttIdx );
pHistory->Add( pFtnHnt, pTxtNd->GetIndex(), false );
pTxtNd->EraseText( aIdx, 1 );
}
}
}
// 2. Flys
if( nsDelCntntType::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() ) &&
(( nsDelCntntType::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* const pFlyHnt = pTxtNd->GetTxtAttrForCharAt(
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:
{
pAPos = pAnchor->GetCntntAnchor();
if( pAPos )
{
bool bTmp;
if( nsDelCntntType::DELCNT_CHKNOCNTNT & nDelCntntType )
bTmp = pStt->nNode <= pAPos->nNode && pAPos->nNode < pEnd->nNode;
else
{
if (bDelFwrd)
bTmp = rMark.nNode < pAPos->nNode &&
pAPos->nNode <= rPoint.nNode;
else
bTmp = rPoint.nNode <= pAPos->nNode &&
pAPos->nNode < rMark.nNode;
}
if (bTmp)
{
if( !pHistory )
pHistory = new SwHistory;
// Moving the anchor?
if( !( nsDelCntntType::DELCNT_CHKNOCNTNT & nDelCntntType ) &&
( rPoint.nNode.GetIndex() == pAPos->nNode.GetIndex() ) )
{
// Do not try to move the anchor to a table!
if( rMark.nNode.GetNode().GetTxtNode() )
{
pHistory->Add( *pFmt );
SwFmtAnchor aAnch( *pAnchor );
SwPosition aPos( rMark.nNode );
aAnch.SetAnchor( &aPos );
pFmt->SetFmtAttr( 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() ) &&
( pStt->nNode <= pAPos->nNode && pAPos->nNode <= pEnd->nNode ) )
{
if( !pHistory )
pHistory = new SwHistory;
if( pAPos->nNode < pEnd->nNode &&
( ( nsDelCntntType::DELCNT_CHKNOCNTNT & nDelCntntType ) ||
( pStt->nNode < pAPos->nNode || !pStt->nContent.GetIndex() ) ) )
{
// Here we identified the objects to destroy:
// - anchored between start and end of the selection
// - anchored in start of the selection with "CheckNoContent"
// - anchored in start of sel. and the selection start at pos 0
pHistory->Add( *pFmt, nChainInsPos );
n = n >= rSpzArr.Count() ? rSpzArr.Count() : n+1;
}
else if( !( nsDelCntntType::DELCNT_CHKNOCNTNT & nDelCntntType ) )
{
if( *pStt <= *pAPos && *pAPos < *pEnd )
{
// These are the objects anchored
// between section start and end position
// Do not try to move the anchor to a table!
if( rMark.nNode.GetNode().GetTxtNode() )
{
pHistory->Add( *pFmt );
SwFmtAnchor aAnch( *pAnchor );
aAnch.SetAnchor( &rMark );
pFmt->SetFmtAttr( 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;
default: break;
}
}
}
}
// 3. Bookmarks
if( nsDelCntntType::DELCNT_BKM & nDelCntntType )
{
IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
if( pMarkAccess->getMarksCount() )
{
for( USHORT n = 0; n < pMarkAccess->getMarksCount(); ++n )
{
// --> OD 2007-10-17 #i81002#
bool bSavePos = false;
bool bSaveOtherPos = false;
const ::sw::mark::IMark* pBkmk = (pMarkAccess->getMarksBegin() + n)->get();
if( nsDelCntntType::DELCNT_CHKNOCNTNT & nDelCntntType )
{
if( pStt->nNode <= pBkmk->GetMarkPos().nNode &&
pBkmk->GetMarkPos().nNode < pEnd->nNode )
bSavePos = true;
if( pBkmk->IsExpanded() &&
pStt->nNode <= pBkmk->GetOtherMarkPos().nNode &&
pBkmk->GetOtherMarkPos().nNode < pEnd->nNode )
bSaveOtherPos = true;
}
else
{
// --> OD 2009-08-06 #i92125#
bool bKeepCrossRefBkmk( false );
{
if ( rMark.nNode == rPoint.nNode &&
( IDocumentMarkAccess::GetType(*pBkmk) ==
IDocumentMarkAccess::CROSSREF_HEADING_BOOKMARK ||
IDocumentMarkAccess::GetType(*pBkmk) ==
IDocumentMarkAccess::CROSSREF_NUMITEM_BOOKMARK ) )
{
bKeepCrossRefBkmk = true;
}
}
if ( !bKeepCrossRefBkmk )
{
bool bMaybe = false;
if ( *pStt <= pBkmk->GetMarkPos() && pBkmk->GetMarkPos() <= *pEnd )
{
if( pBkmk->GetMarkPos() == *pEnd ||
( *pStt == pBkmk->GetMarkPos() && pBkmk->IsExpanded() ) )
bMaybe = true;
else
bSavePos = true;
}
if( pBkmk->IsExpanded() &&
*pStt <= pBkmk->GetOtherMarkPos() && pBkmk->GetOtherMarkPos() <= *pEnd )
{
if( bSavePos || bSaveOtherPos ||
( pBkmk->GetOtherMarkPos() < *pEnd && pBkmk->GetOtherMarkPos() > *pStt ) )
{
if( bMaybe )
bSavePos = true;
bSaveOtherPos = true;
}
}
}
// <--
// --> OD 2007-10-17 #i81002#
const bool bDifferentTxtNodesAtMarkAndPoint(
rMark.nNode != rPoint.nNode &&
rMark.nNode.GetNode().GetTxtNode() &&
rPoint.nNode.GetNode().GetTxtNode() );
// <--
if( !bSavePos && !bSaveOtherPos && bDifferentTxtNodesAtMarkAndPoint &&
dynamic_cast< const ::sw::mark::CrossRefBookmark* >(pBkmk))
{
// delete cross-reference bookmark at <pStt>, if only part of
// <pEnd> text node content is deleted.
if( pStt->nNode == pBkmk->GetMarkPos().nNode &&
pEnd->nContent.GetIndex() !=
pEnd->nNode.GetNode().GetTxtNode()->Len() )
{
bSavePos = true;
bSaveOtherPos = false;
}
// delete cross-reference bookmark at <pEnd>, if only part of
// <pStt> text node content is deleted.
else if( pEnd->nNode == pBkmk->GetMarkPos().nNode &&
pStt->nContent.GetIndex() != 0 )
{
bSavePos = true;
bSaveOtherPos = false;
}
}
}
if( bSavePos || bSaveOtherPos )
{
if( !pHistory )
pHistory = new SwHistory;
pHistory->Add( *pBkmk, bSavePos, bSaveOtherPos );
if(bSavePos &&
(bSaveOtherPos || !pBkmk->IsExpanded()))
{
pMarkAccess->deleteMark(pMarkAccess->getMarksBegin()+n);
n--;
}
}
}
}
}
pDoc->DoUndo( bDoesUndo );
}
// sicher eine vollstaendige Section im Undo-Nodes-Array
SwUndoSaveSection::SwUndoSaveSection()
: pMvStt( 0 ), pRedlSaveData( 0 ), nMvLen( 0 ), nStartPos( ULONG_MAX )
{
}
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* , 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( SwUndoId nInitId )
: SwUndo( UNDO_START ), nUserId( nInitId ), 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;
}
String SwUndoStart::GetComment() const
{
String sResult;
switch (nUserId)
{
case UNDO_START:
case UNDO_END:
sResult = String("??", RTL_TEXTENCODING_ASCII_US);
break;
default:
sResult = String(SW_RES(UNDO_BASE + nUserId));
sResult = GetRewriter().Apply(sResult);
}
return sResult;
}
SwRewriter SwUndoStart::GetRewriter() const
{
return mRewriter;
}
SwUndoId SwUndoStart::GetEffectiveId() const
{
return GetUserId();
}
void SwUndoStart::SetRewriter(const SwRewriter & rRewriter)
{
mRewriter = rRewriter;
}
// END
SwUndoEnd::SwUndoEnd( SwUndoId nInitId )
: SwUndo( UNDO_END ), nUserId( nInitId ), 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;
}
String SwUndoEnd::GetComment() const
{
String sResult;
switch (nUserId)
{
case UNDO_START:
case UNDO_END:
sResult = String("??", RTL_TEXTENCODING_ASCII_US);
break;
default:
sResult = SW_RES(UNDO_BASE + nUserId);
sResult = GetRewriter().Apply(sResult);
}
return sResult;
}
void SwUndoEnd::SetRewriter(const SwRewriter & rRewriter)
{
mRewriter = rRewriter;
}
SwUndoId SwUndoEnd::GetEffectiveId() const
{
return GetUserId();
}
SwRewriter SwUndoEnd::GetRewriter() const
{
return mRewriter;
}
/* */
// 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!" )
}
#ifndef PRODUCT
nRedlineCount = rSttPos.nNode.GetNode().GetDoc()->GetRedlineTbl().Count();
#endif
}
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, USHRT_MAX );
RedlineMode_t eOld = rDoc.GetRedlineMode();
rDoc.SetRedlineMode_intern((RedlineMode_t)(eOld | nsRedlineMode_t::REDLINE_DONTCOMBINE_REDLINES));
//#i92154# let UI know about a new redline with comment
if (rDoc.GetDocShell() && (pRedl->GetComment() != String(::rtl::OUString::createFromAscii(""))) )
rDoc.GetDocShell()->Broadcast(SwRedlineHint(pRedl,SWREDLINE_INSERTED));
//
rDoc.AppendRedline( pRedl, true );
rDoc.SetRedlineMode_intern( eOld );
}
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 &&
POS_COLLIDE_END != eCmpPos && POS_COLLIDE_START != eCmpPos )
{
pNewData = new SwRedlineSaveData( eCmpPos, *pStt, *pEnd,
*pRedl, bCopyNext );
rSData.Insert( pNewData, rSData.Count() );
}
}
if( rSData.Count() && bDelRange )
rRange.GetDoc()->DeleteRedline( rRange, false, USHRT_MAX );
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( nsRedlineType_t::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 &&
POS_COLLIDE_END != eCmpPos && POS_COLLIDE_START != 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 )
{
RedlineMode_t eOld = rDoc.GetRedlineMode();
rDoc.SetRedlineMode_intern( (RedlineMode_t)(( eOld & ~nsRedlineMode_t::REDLINE_IGNORE) | nsRedlineMode_t::REDLINE_ON ));
SwPaM aPam( rDoc.GetNodes().GetEndOfContent() );
for( USHORT n = rSData.Count(); n; )
rSData[ --n ]->RedlineToDoc( aPam );
// check redline count against count saved in RedlineSaveData object
DBG_ASSERT( (rSData.Count() == 0) ||
(rSData[0]->nRedlineCount == rDoc.GetRedlineTbl().Count()),
"redline count not restored properly" );
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;
USHORT n;
if( rCurr.Count() == rCheck.Count() )
{
bRet = TRUE;
for( 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;
}
// #111827#
String ShortenString(const String & rStr, xub_StrLen nLength, const String & rFillStr)
{
ASSERT( nLength - rFillStr.Len() >= 2, "improper arguments")
String aResult;
if (rStr.Len() <= nLength)
aResult = rStr;
else
{
long nTmpLength = nLength - rFillStr.Len();
if ( nTmpLength < 2 )
nTmpLength = 2;
nLength = static_cast<xub_StrLen>(nTmpLength);
const xub_StrLen nFrontLen = nLength - nLength / 2;
const xub_StrLen nBackLen = nLength - nFrontLen;
aResult += rStr.Copy(0, nFrontLen);
aResult += rFillStr;
aResult += rStr.Copy(rStr.Len() - nBackLen, nBackLen);
}
return aResult;
}
static bool lcl_IsSpecialCharacter(sal_Unicode nChar)
{
switch (nChar)
{
case CH_TXTATR_BREAKWORD:
case CH_TXTATR_INWORD:
case CH_TXTATR_TAB:
case CH_TXTATR_NEWLINE:
return true;
default:
break;
}
return false;
}
static String lcl_DenotedPortion(String rStr, xub_StrLen nStart,
xub_StrLen nEnd)
{
String aResult;
if (nEnd - nStart > 0)
{
sal_Unicode cLast = rStr.GetChar(nEnd - 1);
if (lcl_IsSpecialCharacter(cLast))
{
switch(cLast)
{
case CH_TXTATR_TAB:
aResult += String(SW_RES(STR_UNDO_TABS));
break;
case CH_TXTATR_NEWLINE:
aResult += String(SW_RES(STR_UNDO_NLS));
break;
case CH_TXTATR_INWORD:
case CH_TXTATR_BREAKWORD:
aResult += UNDO_ARG2;
break;
}
SwRewriter aRewriter;
aRewriter.AddRule(UNDO_ARG1,
String::CreateFromInt32(nEnd - nStart));
aResult = aRewriter.Apply(aResult);
}
else
{
aResult = String(SW_RES(STR_START_QUOTE));
aResult += rStr.Copy(nStart, nEnd - nStart);
aResult += String(SW_RES(STR_END_QUOTE));
}
}
return aResult;
}
String DenoteSpecialCharacters(const String & rStr)
{
String aResult;
if (rStr.Len() > 0)
{
bool bStart = false;
xub_StrLen nStart = 0;
sal_Unicode cLast = 0;
for (xub_StrLen i = 0; i < rStr.Len(); i++)
{
if (lcl_IsSpecialCharacter(rStr.GetChar(i)))
{
if (cLast != rStr.GetChar(i))
bStart = true;
}
else
{
if (lcl_IsSpecialCharacter(cLast))
bStart = true;
}
if (bStart)
{
aResult += lcl_DenotedPortion(rStr, nStart, i);
nStart = i;
bStart = false;
}
cLast = rStr.GetChar(i);
}
aResult += lcl_DenotedPortion(rStr, nStart, rStr.Len());
}
else
aResult = UNDO_ARG2;
return aResult;
}