Files
libreoffice/sw/source/core/doc/doccomp.cxx

1850 lines
57 KiB
C++
Raw Normal View History

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2000-09-18 23:08:29 +00:00
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
2000-09-18 23:08:29 +00:00
*
* Copyright 2000, 2010 Oracle and/or its affiliates.
2000-09-18 23:08:29 +00:00
*
* OpenOffice.org - a multi-platform office productivity suite
2000-09-18 23:08:29 +00:00
*
* This file is part of OpenOffice.org.
2000-09-18 23:08:29 +00:00
*
* 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.
2000-09-18 23:08:29 +00:00
*
* 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).
2000-09-18 23:08:29 +00:00
*
* 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.
2000-09-18 23:08:29 +00:00
*
************************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sw.hxx"
2000-09-18 23:08:29 +00:00
#include <hintids.hxx>
2001-09-27 12:42:58 +00:00
#include <tools/list.hxx>
#include <vcl/vclenum.hxx>
#include <editeng/crsditem.hxx>
#include <editeng/colritem.hxx>
#include <editeng/boxitem.hxx>
#include <editeng/udlnitem.hxx>
2000-09-18 23:08:29 +00:00
#include <doc.hxx>
#include <docary.hxx>
#include <pam.hxx>
#include <ndtxt.hxx>
#include <redline.hxx>
#include <undobj.hxx>
2001-09-27 12:42:58 +00:00
#include <section.hxx>
#include <tox.hxx>
#include <docsh.hxx>
#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
#include <com/sun/star/document/XDocumentProperties.hpp>
2000-09-18 23:08:29 +00:00
using namespace ::com::sun::star;
2000-09-18 23:08:29 +00:00
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 ); }
};
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()
: pIndex( 0 ), pChangedFlag( 0 ), nSttLineNum( 0 )
2000-09-18 23:08:29 +00:00
{
}
CompareData::~CompareData()
{
2002-05-13 11:14:05 +00:00
delete[] pIndex;
delete[] pChangedFlag;
2000-09-18 23:08:29 +00:00
}
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;
}
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, ULONG )
2000-09-18 23:08:29 +00:00
{
}
void CompareData::ShowDelete( const CompareData&, ULONG, ULONG, ULONG )
2000-09-18 23:08:29 +00:00
{
}
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
};
int i;
2000-09-18 23:08:29 +00:00
pDataArr = new _HashData[ nSize ];
pDataArr[0].nNext = 0;
pDataArr[0].nHash = 0,
pDataArr[0].pLine = 0;
for( i = 0; primes[i] < nSize / 3; i++)
2000-09-18 23:08:29 +00:00
if( !primes[i] )
{
pHashArr = 0;
return;
}
nPrime = primes[ i ];
pHashArr = new ULONG[ nPrime ];
memset( pHashArr, 0, nPrime * sizeof( ULONG ) );
}
Hash::~Hash()
{
2002-05-13 11:14:05 +00:00
delete[] pHashArr;
delete[] pDataArr;
2000-09-18 23:08:29 +00:00
}
void Hash::CalcHashValue( CompareData& rData )
{
if( pHashArr )
{
for( ULONG n = 0; n < rData.GetLineCount(); ++n )
{
const CompareLine* pLine = rData.GetLine( n );
OSL_ENSURE( pLine, "wo ist die Line?" );
2000-09-18 23:08:29 +00:00
ULONG nH = pLine->GetHashValue();
ULONG* pFound = &pHashArr[ nH % nPrime ];
ULONG i;
for( i = *pFound; ; i = pDataArr[i].nNext )
2000-09-18 23:08:29 +00:00
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;
2000-09-18 23:08:29 +00:00
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;
2000-09-18 23:08:29 +00:00
}
{
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;
ULONG n;
for( n = nLen / 64; ( n = n >> 2 ) > 0; )
2000-09-18 23:08:29 +00:00
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 ] )
{
ULONG j;
2000-09-18 23:08:29 +00:00
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
{
ULONG consec;
2000-09-18 23:08:29 +00:00
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();
ULONG n;
for( n = 0; n < nLen; ++n )
2000-09-18 23:08:29 +00:00
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
2000-09-18 23:08:29 +00:00
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 );
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 iz = 0; iz < 2; ++iz )
2000-09-18 23:08:29 +00:00
{
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;
}
}
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;
2001-09-27 12:42:58 +00:00
ULONG PrevIdx( const SwNode* pNd );
ULONG NextIdx( const SwNode* pNd );
2000-09-18 23:08:29 +00:00
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( BOOL bUseDocInfo );
2000-09-18 23:08:29 +00:00
};
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:
2001-09-27 12:42:58 +00:00
{
String sStr( GetText() );
for( xub_StrLen n = 0; n < sStr.Len(); ++n )
( nRet <<= 1 ) += sStr.GetChar( n );
}
2000-09-18 23:08:29 +00:00
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:
2001-09-27 12:42:58 +00:00
{
const SwSectionNode& rSNd = (SwSectionNode&)rNode;
const SwSection& rSect = rSNd.GetSection();
if( CONTENT_SECTION != rSect.GetType() || rSect.IsProtect() )
pNd = rNode.EndOfSectionNode();
}
2000-09-18 23:08:29 +00:00
break;
}
return *pNd;
}
BOOL SwCompareLine::Compare( const CompareLine& rLine ) const
{
return CompareNode( rNode, ((SwCompareLine&)rLine).rNode );
}
2010-01-13 13:03:53 +01:00
namespace
{
static String SimpleTableToText(const SwNode &rNode)
{
String sRet;
const SwNode* pEndNd = rNode.EndOfSectionNode();
SwNodeIndex aIdx( rNode );
while (&aIdx.GetNode() != pEndNd)
{
if (aIdx.GetNode().IsTxtNode())
{
if (sRet.Len())
{
sRet.Append( '\n' );
}
sRet.Append( aIdx.GetNode().GetTxtNode()->GetExpandTxt() );
}
aIdx++;
}
return sRet;
}
}
2000-09-18 23:08:29 +00:00
BOOL SwCompareLine::CompareNode( const SwNode& rDstNd, const SwNode& rSrcNd )
{
if( rSrcNd.GetNodeType() != rDstNd.GetNodeType() )
return FALSE;
2000-09-18 23:08:29 +00:00
BOOL bRet = FALSE;
switch( rDstNd.GetNodeType() )
2000-09-18 23:08:29 +00:00
{
case ND_TEXTNODE:
2000-09-18 23:08:29 +00:00
bRet = CompareTxtNd( (SwTxtNode&)rDstNd, (SwTxtNode&)rSrcNd );
break;
case ND_TABLENODE:
2000-09-18 23:08:29 +00:00
{
const SwTableNode& rTSrcNd = (SwTableNode&)rSrcNd;
const SwTableNode& rTDstNd = (SwTableNode&)rDstNd;
bRet = ( rTSrcNd.EndOfSectionIndex() - rTSrcNd.GetIndex() ) ==
( rTDstNd.EndOfSectionIndex() - rTDstNd.GetIndex() );
2010-01-13 13:03:53 +01:00
// --> #i107826#: compare actual table content
if (bRet)
{
bRet = (SimpleTableToText(rSrcNd) == SimpleTableToText(rDstNd));
}
// <--
2000-09-18 23:08:29 +00:00
}
break;
case ND_SECTIONNODE:
2000-09-18 23:08:29 +00:00
{
2001-09-27 12:42:58 +00:00
const SwSectionNode& rSSrcNd = (SwSectionNode&)rSrcNd,
& rSDstNd = (SwSectionNode&)rDstNd;
const SwSection& rSrcSect = rSSrcNd.GetSection(),
& rDstSect = rSDstNd.GetSection();
SectionType eSrcSectType = rSrcSect.GetType(),
eDstSectType = rDstSect.GetType();
switch( eSrcSectType )
{
case CONTENT_SECTION:
bRet = CONTENT_SECTION == eDstSectType &&
rSrcSect.IsProtect() == rDstSect.IsProtect();
if( bRet && rSrcSect.IsProtect() )
{
// the only have they both the same size
bRet = ( rSSrcNd.EndOfSectionIndex() - rSSrcNd.GetIndex() ) ==
( rSDstNd.EndOfSectionIndex() - rSDstNd.GetIndex() );
}
break;
2000-09-18 23:08:29 +00:00
2001-09-27 12:42:58 +00:00
case TOX_HEADER_SECTION:
case TOX_CONTENT_SECTION:
if( TOX_HEADER_SECTION == eDstSectType ||
TOX_CONTENT_SECTION == eDstSectType )
{
// the same type of TOX?
const SwTOXBase* pSrcTOX = rSrcSect.GetTOXBase();
const SwTOXBase* pDstTOX = rDstSect.GetTOXBase();
bRet = pSrcTOX && pDstTOX
&& pSrcTOX->GetType() == pDstTOX->GetType()
&& pSrcTOX->GetTitle() == pDstTOX->GetTitle()
&& pSrcTOX->GetTypeName() == pDstTOX->GetTypeName()
// && pSrcTOX->GetTOXName() == pDstTOX->GetTOXName()
;
}
break;
case DDE_LINK_SECTION:
case FILE_LINK_SECTION:
bRet = eSrcSectType == eDstSectType &&
rSrcSect.GetLinkFileName() ==
rDstSect.GetLinkFileName();
break;
}
2000-09-18 23:08:29 +00:00
}
break;
case ND_ENDNODE:
bRet = rSrcNd.StartOfSectionNode()->GetNodeType() ==
rDstNd.StartOfSectionNode()->GetNodeType();
2010-01-13 13:03:53 +01:00
// --> #i107826#: compare actual table content
if (bRet && rSrcNd.StartOfSectionNode()->GetNodeType() == ND_TABLENODE)
{
bRet = CompareNode(
*rSrcNd.StartOfSectionNode(), *rDstNd.StartOfSectionNode());
}
// <--
break;
2000-09-18 23:08:29 +00:00
}
return bRet;
}
String SwCompareLine::GetText() const
{
String sRet;
switch( rNode.GetNodeType() )
{
case ND_TEXTNODE:
sRet = ((SwTxtNode&)rNode).GetExpandTxt();
break;
case ND_TABLENODE:
{
2010-01-13 13:03:53 +01:00
sRet = SimpleTableToText(rNode);
2000-09-18 23:08:29 +00:00
sRet.InsertAscii( "Tabelle: ", 0 );
}
break;
case ND_SECTIONNODE:
2001-09-27 12:42:58 +00:00
{
sRet.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "Section - Node:" ));
const SwSectionNode& rSNd = (SwSectionNode&)rNode;
const SwSection& rSect = rSNd.GetSection();
switch( rSect.GetType() )
{
case CONTENT_SECTION:
if( rSect.IsProtect() )
sRet.Append( String::CreateFromInt32(
rSNd.EndOfSectionIndex() - rSNd.GetIndex() ));
break;
case TOX_HEADER_SECTION:
case TOX_CONTENT_SECTION:
{
const SwTOXBase* pTOX = rSect.GetTOXBase();
if( pTOX )
sRet.Append( pTOX->GetTitle() )
.Append( pTOX->GetTypeName() )
// .Append( pTOX->GetTOXName() )
.Append( String::CreateFromInt32( pTOX->GetType() ));
}
break;
case DDE_LINK_SECTION:
case FILE_LINK_SECTION:
sRet += rSect.GetLinkFileName();
break;
}
}
2000-09-18 23:08:29 +00:00
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();
xub_StrLen nStt;
xub_StrLen nEnd;
for( nStt = 0, nEnd = Min( nDEnd, nSEnd ); nStt < nEnd; ++nStt )
2000-09-18 23:08:29 +00:00
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;
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
aCpyPam.GetDoc()->CopyRange( aCpyPam, *aPam.GetPoint(),
false );
2000-09-18 23:08:29 +00:00
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;
}
}
2001-09-27 12:42:58 +00:00
ULONG SwCompareData::NextIdx( const SwNode* pNd )
{
if( pNd->IsStartNode() )
{
const SwSectionNode* pSNd;
if( pNd->IsTableNode() ||
( 0 != (pSNd = pNd->GetSectionNode() ) &&
( CONTENT_SECTION != pSNd->GetSection().GetType() ||
pSNd->GetSection().IsProtect() ) ) )
pNd = pNd->EndOfSectionNode();
}
return pNd->GetIndex() + 1;
}
ULONG SwCompareData::PrevIdx( const SwNode* pNd )
{
if( pNd->IsEndNode() )
{
const SwSectionNode* pSNd;
if( pNd->StartOfSectionNode()->IsTableNode() ||
( 0 != (pSNd = pNd->StartOfSectionNode()->GetSectionNode() ) &&
( CONTENT_SECTION != pSNd->GetSection().GetType() ||
pSNd->GetSection().IsProtect() ) ) )
pNd = pNd->StartOfSectionNode();
}
return pNd->GetIndex() - 1;
}
2000-09-18 23:08:29 +00:00
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();
ULONG nSrcSttIdx = NextIdx( rSrcEndNd.StartOfSectionNode() );
2000-09-18 23:08:29 +00:00
ULONG nSrcEndIdx = rSrcEndNd.GetIndex();
ULONG nDstSttIdx = NextIdx( rDstEndNd.StartOfSectionNode() );
2000-09-18 23:08:29 +00:00
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 );
}
2001-09-27 12:42:58 +00:00
nSrcEndIdx = PrevIdx( &rSrcEndNd );
nDstEndIdx = PrevIdx( &rDstEndNd );
2000-09-18 23:08:29 +00:00
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;
// #i65201#: These SwPaMs are calculated smaller than needed, see comment below
2000-09-18 23:08:29 +00:00
}
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 )
2001-09-27 12:42:58 +00:00
{
if( nOffset )
pLineNd = &((SwCompareLine*)pLine)->GetEndNode();
else
pLineNd = &((SwCompareLine*)pLine)->GetNode();
}
2000-09-18 23:08:29 +00:00
else
{
pLineNd = &rDoc.GetNodes().GetEndOfContent();
nOffset = 0;
}
SwNodeIndex aInsPos( *pLineNd, nOffset );
SwNodeIndex aSavePos( aInsPos, -1 );
((SwCompareData&)rData).rDoc.CopyWithFlyInFly( aRg, 0, aInsPos );
2001-09-27 12:42:58 +00:00
rDoc.SetModified();
2000-09-18 23:08:29 +00:00
aSavePos++;
// #i65201#: These SwPaMs are calculated when the (old) delete-redlines are hidden,
// they will be inserted when the delete-redlines are shown again.
// To avoid unwanted insertions of delete-redlines into these new redlines, what happens
// especially at the end of the document, I reduce the SwPaM by one node.
// Before the new redlines are inserted, they have to expand again.
SwPaM* pTmp = new SwPaM( aSavePos.GetNode(), aInsPos.GetNode(), 0, -1, pDelRing );
2000-09-18 23:08:29 +00:00
if( !pDelRing )
pDelRing = pTmp;
if( pInsRing )
{
SwPaM* pCorr = (SwPaM*)pInsRing->GetPrev();
if( *pCorr->GetPoint() == *pTmp->GetPoint() )
{
SwNodeIndex aTmpPos( pTmp->GetMark()->nNode, -1 );
*pCorr->GetPoint() = SwPosition( aTmpPos );
}
2000-09-18 23:08:29 +00:00
}
}
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( BOOL bUseDocInfo )
2000-09-18 23:08:29 +00:00
{
SwPaM* pTmp = pDelRing;
// Bug #83296#: get the Author / TimeStamp from the "other"
// document info
USHORT nAuthor = rDoc.GetRedlineAuthor();
DateTime aTimeStamp;
SwDocShell *pDocShell(rDoc.GetDocShell());
DBG_ASSERT(pDocShell, "no SwDocShell");
if (pDocShell) {
uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
pDocShell->GetModel(), uno::UNO_QUERY_THROW);
uno::Reference<document::XDocumentProperties> xDocProps(
xDPS->getDocumentProperties());
DBG_ASSERT(xDocProps.is(), "Doc has no DocumentProperties");
if( bUseDocInfo && xDocProps.is() ) {
String aTmp( 1 == xDocProps->getEditingCycles()
? xDocProps->getAuthor()
: xDocProps->getModifiedBy() );
util::DateTime uDT( 1 == xDocProps->getEditingCycles()
? xDocProps->getCreationDate()
: xDocProps->getModificationDate() );
Date d(uDT.Day, uDT.Month, uDT.Year);
Time t(uDT.Hours, uDT.Minutes, uDT.Seconds, uDT.HundredthSeconds);
DateTime aDT(d,t);
if( aTmp.Len() )
{
nAuthor = rDoc.InsertRedlineAuthor( aTmp );
aTimeStamp = aDT;
}
}
}
2000-09-18 23:08:29 +00:00
if( pTmp )
{
SwRedlineData aRedlnData( nsRedlineType_t::REDLINE_DELETE, nAuthor, aTimeStamp,
aEmptyStr, 0, 0 );
2000-09-18 23:08:29 +00:00
do {
// #i65201#: Expand again, see comment above.
if( pTmp->GetPoint()->nContent == 0 )
{
pTmp->GetPoint()->nNode++;
pTmp->GetPoint()->nContent.Assign( pTmp->GetCntntNode(), 0 );
}
// --> mst 2010-05-17 #i101009#
// prevent redlines that end on structural end node
if (& rDoc.GetNodes().GetEndOfContent() ==
& pTmp->GetPoint()->nNode.GetNode())
{
pTmp->GetPoint()->nNode--;
SwCntntNode *const pContentNode( pTmp->GetCntntNode() );
pTmp->GetPoint()->nContent.Assign( pContentNode,
(pContentNode) ? pContentNode->Len() : 0 );
}
// <--
rDoc.DeleteRedline( *pTmp, false, USHRT_MAX );
2000-09-18 23:08:29 +00:00
if( rDoc.DoesUndo() )
rDoc.AppendUndo( new SwUndoCompDoc( *pTmp, FALSE ));
rDoc.AppendRedline( new SwRedline( aRedlnData, *pTmp ), true );
2000-09-18 23:08:29 +00:00
} while( pDelRing != ( pTmp = (SwPaM*)pTmp->GetNext() ));
}
2000-09-18 23:08:29 +00:00
pTmp = pInsRing;
if( pTmp )
{
do {
if( pTmp->GetPoint()->nContent == 0 )
{
pTmp->GetPoint()->nNode++;
pTmp->GetPoint()->nContent.Assign( pTmp->GetCntntNode(), 0 );
}
// --> mst 2010-05-17 #i101009#
// prevent redlines that end on structural end node
if (& rDoc.GetNodes().GetEndOfContent() ==
& pTmp->GetPoint()->nNode.GetNode())
{
pTmp->GetPoint()->nNode--;
SwCntntNode *const pContentNode( pTmp->GetCntntNode() );
pTmp->GetPoint()->nContent.Assign( pContentNode,
(pContentNode) ? pContentNode->Len() : 0 );
}
// <--
} while( pInsRing != ( pTmp = (SwPaM*)pTmp->GetNext() ));
SwRedlineData aRedlnData( nsRedlineType_t::REDLINE_INSERT, nAuthor, aTimeStamp,
aEmptyStr, 0, 0 );
2000-09-18 23:08:29 +00:00
// 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( aRedlnData, *pTmp ), true) &&
2000-09-18 23:08:29 +00:00
rDoc.DoesUndo() )
rDoc.AppendUndo( new SwUndoCompDoc( *pTmp, TRUE ));
} while( pInsRing != ( pTmp = (SwPaM*)pTmp->GetNext() ));
}
}
// returnt (?die Anzahl der Unterschiede?) ob etwas unterschiedlich ist
2000-09-18 23:08:29 +00:00
long SwDoc::CompareDoc( const SwDoc& rDoc )
{
if( &rDoc == this )
return 0;
long nRet = 0;
StartUndo(UNDO_EMPTY, NULL);
BOOL bDocWasModified = IsModified();
2000-09-18 23:08:29 +00:00
SwDoc& rSrcDoc = (SwDoc&)rDoc;
BOOL bSrcModified = rSrcDoc.IsModified();
RedlineMode_t eSrcRedlMode = rSrcDoc.GetRedlineMode();
rSrcDoc.SetRedlineMode( nsRedlineMode_t::REDLINE_SHOW_INSERT );
SetRedlineMode((RedlineMode_t)(nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_SHOW_INSERT));
2000-09-18 23:08:29 +00:00
SwCompareData aD0( rSrcDoc );
SwCompareData aD1( *this );
aD1.CompareLines( aD0 );
nRet = aD1.ShowDiffs( aD0 );
if( nRet )
{
SetRedlineMode((RedlineMode_t)(nsRedlineMode_t::REDLINE_ON |
nsRedlineMode_t::REDLINE_SHOW_INSERT | nsRedlineMode_t::REDLINE_SHOW_DELETE));
aD1.SetRedlinesToDoc( !bDocWasModified );
2001-09-27 12:42:58 +00:00
SetModified();
2000-09-18 23:08:29 +00:00
}
rSrcDoc.SetRedlineMode( eSrcRedlMode );
SetRedlineMode((RedlineMode_t)(nsRedlineMode_t::REDLINE_SHOW_INSERT | nsRedlineMode_t::REDLINE_SHOW_DELETE));
2000-09-18 23:08:29 +00:00
if( !bSrcModified )
rSrcDoc.ResetModified();
EndUndo(UNDO_EMPTY, NULL);
2000-09-18 23:08:29 +00:00
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( nsRedlineType_t::REDLINE_DELETE == pDestRedl->GetType() )
2000-09-18 23:08:29 +00:00
{
// 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( nsRedlineType_t::REDLINE_INSERT == pDestRedl->GetType() )
2000-09-18 23:08:29 +00:00
{
// 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();
RedlineMode_t eOld = pDoc->GetRedlineMode();
pDoc->SetRedlineMode_intern((RedlineMode_t)(eOld | nsRedlineMode_t::REDLINE_IGNORE));
2000-09-18 23:08:29 +00:00
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
pSrcRedl->GetDoc()->CopyRange(
*const_cast<SwPaM*>(static_cast<const SwPaM*>(pSrcRedl)),
*pDestRedl->GetPoint(), false );
2000-09-18 23:08:29 +00:00
pDoc->SetRedlineMode_intern( eOld );
pDoc->DoUndo( bUndo );
pDestRedl->SetMark();
aSaveNd++;
pDestRedl->GetMark()->nNode = aSaveNd;
pDestRedl->GetMark()->nContent.Assign( aSaveNd.GetNode().GetCntntNode(),
nSaveCnt );
if( GetPrev() != this )
{
SwPaM* pTmpPrev = ((_SaveMergeRedlines*)GetPrev())->pDestRedl;
if( pTmpPrev && *pTmpPrev->GetPoint() == *pDestRedl->GetPoint() )
*pTmpPrev->GetPoint() = *pDestRedl->GetMark();
}
2000-09-18 23:08:29 +00:00
}
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( nsRedlineType_t::REDLINE_DELETE == pRedl->GetType() ||
nsRedlineType_t::REDLINE_INSERT == pRedl->GetType() )
2000-09-18 23:08:29 +00:00
{
SwComparePosition eCmpPos = ComparePosition( *pDStt, *pDEnd, *pRStt, *pREnd );
switch( eCmpPos )
{
case POS_COLLIDE_START:
2000-09-18 23:08:29 +00:00
case POS_BEHIND:
break;
case POS_INSIDE:
case POS_EQUAL:
delete pDestRedl, pDestRedl = 0;
// break; -> kein break !!!!
case POS_COLLIDE_END:
2000-09-18 23:08:29 +00:00
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;
// now modify doc: append redline, undo (and count)
pDoc->AppendRedline( pCpyRedl, true );
if( pUndo )
(pDoc->*pFn)( pUndo );
++nIns;
2000-09-18 23:08:29 +00:00
*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;
// now modify doc: append redline, undo (and count)
bool bRedlineAccepted = pDoc->AppendRedline( pDestRedl, true );
if( pUndo )
(pDoc->*pFn)( pUndo );
++nIns;
// if AppendRedline has deleted our redline, we may not keep a
// reference to it
if( ! bRedlineAccepted )
pDestRedl = NULL;
2000-09-18 23:08:29 +00:00
}
return nIns;
}
// merge zweier Dokumente
long SwDoc::MergeDoc( const SwDoc& rDoc )
{
if( &rDoc == this )
return 0;
long nRet = 0;
StartUndo(UNDO_EMPTY, NULL);
2000-09-18 23:08:29 +00:00
SwDoc& rSrcDoc = (SwDoc&)rDoc;
BOOL bSrcModified = rSrcDoc.IsModified();
RedlineMode_t eSrcRedlMode = rSrcDoc.GetRedlineMode();
rSrcDoc.SetRedlineMode( nsRedlineMode_t::REDLINE_SHOW_DELETE );
SetRedlineMode( nsRedlineMode_t::REDLINE_SHOW_DELETE );
2000-09-18 23:08:29 +00:00
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();
RedlineType_t eType = pRedl->GetType();
2000-09-18 23:08:29 +00:00
if( nEndOfExtra < nNd &&
( nsRedlineType_t::REDLINE_INSERT == eType || nsRedlineType_t::REDLINE_DELETE == eType ))
2000-09-18 23:08:29 +00:00
{
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((RedlineMode_t)(nsRedlineMode_t::REDLINE_SHOW_INSERT | nsRedlineMode_t::REDLINE_SHOW_DELETE));
SetRedlineMode((RedlineMode_t)(
nsRedlineMode_t::REDLINE_ON |
nsRedlineMode_t::REDLINE_SHOW_INSERT |
nsRedlineMode_t::REDLINE_SHOW_DELETE));
2000-09-18 23:08:29 +00:00
_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((RedlineMode_t)(nsRedlineMode_t::REDLINE_SHOW_INSERT | nsRedlineMode_t::REDLINE_SHOW_DELETE));
2000-09-18 23:08:29 +00:00
EndUndo(UNDO_EMPTY, NULL);
2000-09-18 23:08:29 +00:00
return nRet;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */