2000-09-18 23:08:29 +00:00
|
|
|
/*************************************************************************
|
|
|
|
*
|
|
|
|
* $RCSfile: thints.cxx,v $
|
|
|
|
*
|
2001-11-26 10:58:29 +00:00
|
|
|
* $Revision: 1.25 $
|
2000-09-18 23:08:29 +00:00
|
|
|
*
|
2001-11-26 10:58:29 +00:00
|
|
|
* last change: $Author: ama $ $Date: 2001-11-26 11:58:29 $
|
2000-09-18 23:08:29 +00:00
|
|
|
*
|
|
|
|
* The Contents of this file are made available subject to the terms of
|
|
|
|
* either of the following licenses
|
|
|
|
*
|
|
|
|
* - GNU Lesser General Public License Version 2.1
|
|
|
|
* - Sun Industry Standards Source License Version 1.1
|
|
|
|
*
|
|
|
|
* Sun Microsystems Inc., October, 2000
|
|
|
|
*
|
|
|
|
* GNU Lesser General Public License Version 2.1
|
|
|
|
* =============================================
|
|
|
|
* Copyright 2000 by Sun Microsystems, Inc.
|
|
|
|
* 901 San Antonio Road, Palo Alto, CA 94303, USA
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License version 2.1, as published by the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
|
|
* MA 02111-1307 USA
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* Sun Industry Standards Source License Version 1.1
|
|
|
|
* =================================================
|
|
|
|
* The contents of this file are subject to the Sun Industry Standards
|
|
|
|
* Source License Version 1.1 (the "License"); You may not use this file
|
|
|
|
* except in compliance with the License. You may obtain a copy of the
|
|
|
|
* License at http://www.openoffice.org/license.html.
|
|
|
|
*
|
|
|
|
* Software provided under this License is provided on an "AS IS" basis,
|
|
|
|
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
|
|
|
|
* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
|
|
|
|
* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
|
|
|
|
* See the License for the specific provisions governing your rights and
|
|
|
|
* obligations concerning the Software.
|
|
|
|
*
|
|
|
|
* The Initial Developer of the Original Code is: Sun Microsystems, Inc.
|
|
|
|
*
|
|
|
|
* Copyright: 2000 by Sun Microsystems, Inc.
|
|
|
|
*
|
|
|
|
* All Rights Reserved.
|
|
|
|
*
|
|
|
|
* Contributor(s): _______________________________________
|
|
|
|
*
|
|
|
|
*
|
|
|
|
************************************************************************/
|
|
|
|
|
|
|
|
#ifdef PRECOMPILED
|
|
|
|
#include "core_pch.hxx"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#pragma hdrstop
|
|
|
|
|
|
|
|
#ifndef _HINTIDS_HXX
|
|
|
|
#include <hintids.hxx>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _SOT_FACTORY_HXX
|
|
|
|
#include <sot/factory.hxx>
|
|
|
|
#endif
|
2001-07-04 13:18:44 +00:00
|
|
|
#ifndef _SVX_XMLCNITM_HXX
|
|
|
|
#include <svx/xmlcnitm.hxx>
|
2000-09-18 23:08:29 +00:00
|
|
|
#endif
|
|
|
|
#ifndef _SFX_WHITER_HXX //autogen
|
|
|
|
#include <svtools/whiter.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _SFXITEMITER_HXX //autogen
|
|
|
|
#include <svtools/itemiter.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _SVX_FONTITEM_HXX //autogen
|
|
|
|
#include <svx/fontitem.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _SVX_LANGITEM_HXX //autogen
|
|
|
|
#include <svx/langitem.hxx>
|
|
|
|
#endif
|
2000-10-30 11:51:04 +00:00
|
|
|
#ifndef _SVX_EMPHITEM_HXX //autogen
|
|
|
|
#include <svx/emphitem.hxx>
|
|
|
|
#endif
|
2001-02-15 19:10:39 +00:00
|
|
|
#ifndef _SVX_CHARSCALEITEM_HXX
|
|
|
|
#include <svx/charscaleitem.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _SVX_CHARROTATEITEM_HXX
|
|
|
|
#include <svx/charrotateitem.hxx>
|
|
|
|
#endif
|
2000-09-18 23:08:29 +00:00
|
|
|
|
|
|
|
#ifndef _TXTINET_HXX //autogen
|
|
|
|
#include <txtinet.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _TXTFLCNT_HXX //autogen
|
|
|
|
#include <txtflcnt.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _FMTFLD_HXX //autogen
|
|
|
|
#include <fmtfld.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _FMTANCHR_HXX //autogen
|
|
|
|
#include <fmtanchr.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _FMTFLD_HXX //autogen
|
|
|
|
#include <fmtfld.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _FMTINFMT_HXX //autogen
|
|
|
|
#include <fmtinfmt.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _TXTATR_HXX //autogen
|
|
|
|
#include <txtatr.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _FCHRFMT_HXX //autogen
|
|
|
|
#include <fchrfmt.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _FMTFLCNT_HXX //autogen
|
|
|
|
#include <fmtflcnt.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _FMTFTN_HXX //autogen
|
|
|
|
#include <fmtftn.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _TXTTXMRK_HXX //autogen
|
|
|
|
#include <txttxmrk.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _TXTRFMRK_HXX //autogen
|
|
|
|
#include <txtrfmrk.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _TXTFTN_HXX //autogen
|
|
|
|
#include <txtftn.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _TXTFLD_HXX //autogen
|
|
|
|
#include <txtfld.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _CHARATR_HXX
|
|
|
|
#include <charatr.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _CHARFMT_HXX //autogen
|
|
|
|
#include <charfmt.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _FRMFMT_HXX //autogen
|
|
|
|
#include <frmfmt.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _FTNIDX_HXX //autogen
|
|
|
|
#include <ftnidx.hxx>
|
|
|
|
#endif
|
2000-10-23 10:58:55 +00:00
|
|
|
#ifndef _FMTRUBY_HXX
|
|
|
|
#include <fmtruby.hxx>
|
|
|
|
#endif
|
2000-11-06 17:55:06 +00:00
|
|
|
#ifndef _BREAKIT_HXX
|
|
|
|
#include <breakit.hxx>
|
|
|
|
#endif
|
2000-09-18 23:08:29 +00:00
|
|
|
#ifndef _DOC_HXX
|
|
|
|
#include <doc.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _ERRHDL_HXX
|
|
|
|
#include <errhdl.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _FLDBAS_HXX
|
|
|
|
#include <fldbas.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _PAM_HXX
|
|
|
|
#include <pam.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _NDTXT_HXX
|
|
|
|
#include <ndtxt.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _TXTFRM_HXX
|
|
|
|
#include <txtfrm.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _CALBCK_HXX
|
|
|
|
#include <calbck.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _HINTS_HXX
|
|
|
|
#include <hints.hxx> // fuer SwFmtChg
|
|
|
|
#endif
|
|
|
|
#ifndef _ROLBCK_HXX
|
|
|
|
#include <rolbck.hxx> // fuer SwRegHistory
|
|
|
|
#endif
|
|
|
|
#ifndef _DDEFLD_HXX
|
|
|
|
#include <ddefld.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _DOCUFLD_HXX
|
|
|
|
#include <docufld.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _EXPFLD_HXX
|
|
|
|
#include <expfld.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _USRFLD_HXX
|
|
|
|
#include <usrfld.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _POOLFMT_HXX
|
|
|
|
#include <poolfmt.hxx>
|
|
|
|
#endif
|
2000-10-23 10:58:55 +00:00
|
|
|
#ifndef _SWFONT_HXX
|
|
|
|
#include <swfont.hxx>
|
|
|
|
#endif
|
2000-09-18 23:08:29 +00:00
|
|
|
|
|
|
|
|
|
|
|
#ifndef PRODUCT
|
|
|
|
#define CHECK Check();
|
|
|
|
#else
|
|
|
|
#define CHECK
|
|
|
|
#endif
|
|
|
|
|
2000-11-20 15:22:08 +00:00
|
|
|
using namespace ::com::sun::star::i18n;
|
2000-09-18 23:08:29 +00:00
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
* SwTxtNode::MakeTxtAttr()
|
|
|
|
*************************************************************************/
|
|
|
|
|
|
|
|
// lege ein neues TextAttribut an und fuege es SwpHints-Array ein
|
|
|
|
SwTxtAttr* SwTxtNode::MakeTxtAttr( const SfxPoolItem& rAttr,
|
|
|
|
xub_StrLen nStt, xub_StrLen nEnd, BOOL bPool )
|
|
|
|
{
|
|
|
|
// das neue Attribut im Pool anlegen
|
|
|
|
const SfxPoolItem& rNew = bPool ? GetDoc()->GetAttrPool().Put( rAttr ) :
|
|
|
|
rAttr;
|
|
|
|
|
|
|
|
SwTxtAttr* pNew = 0;
|
|
|
|
switch( rNew.Which() )
|
|
|
|
{
|
|
|
|
case RES_CHRATR_CASEMAP:
|
|
|
|
case RES_CHRATR_COLOR:
|
|
|
|
case RES_CHRATR_CHARSETCOLOR:
|
|
|
|
case RES_CHRATR_CONTOUR:
|
|
|
|
case RES_CHRATR_CROSSEDOUT:
|
|
|
|
case RES_CHRATR_ESCAPEMENT:
|
|
|
|
case RES_CHRATR_KERNING:
|
|
|
|
case RES_CHRATR_SHADOWED:
|
|
|
|
case RES_CHRATR_AUTOKERN:
|
|
|
|
case RES_CHRATR_WORDLINEMODE:
|
|
|
|
case RES_CHRATR_UNDERLINE:
|
2001-03-15 14:59:12 +00:00
|
|
|
case RES_CHRATR_FONT:
|
|
|
|
case RES_CHRATR_CTL_FONT:
|
|
|
|
case RES_CHRATR_CJK_FONT:
|
|
|
|
case RES_CHRATR_FONTSIZE:
|
|
|
|
case RES_CHRATR_CTL_FONTSIZE:
|
|
|
|
case RES_CHRATR_CJK_FONTSIZE:
|
|
|
|
case RES_CHRATR_LANGUAGE:
|
|
|
|
case RES_CHRATR_CTL_LANGUAGE:
|
|
|
|
case RES_CHRATR_CJK_LANGUAGE:
|
|
|
|
case RES_CHRATR_POSTURE:
|
|
|
|
case RES_CHRATR_CTL_POSTURE:
|
|
|
|
case RES_CHRATR_CJK_POSTURE:
|
2000-09-18 23:08:29 +00:00
|
|
|
case RES_CHRATR_WEIGHT:
|
2001-03-15 14:59:12 +00:00
|
|
|
case RES_CHRATR_CTL_WEIGHT:
|
|
|
|
case RES_CHRATR_CJK_WEIGHT:
|
2000-10-30 11:51:04 +00:00
|
|
|
case RES_CHRATR_EMPHASIS_MARK:
|
2001-03-15 14:59:12 +00:00
|
|
|
case RES_CHRATR_NOHYPHEN:
|
|
|
|
case RES_CHRATR_BLINK:
|
|
|
|
case RES_CHRATR_BACKGROUND:
|
|
|
|
case RES_CHRATR_ROTATE:
|
|
|
|
case RES_CHRATR_SCALEW:
|
|
|
|
case RES_CHRATR_RELIEF:
|
|
|
|
pNew = new SwTxtAttrEnd( rNew, nStt, nEnd );
|
2000-10-30 11:51:04 +00:00
|
|
|
break;
|
2000-09-18 23:08:29 +00:00
|
|
|
case RES_TXTATR_CHARFMT:
|
|
|
|
{
|
|
|
|
SwFmtCharFmt &rFmtCharFmt = (SwFmtCharFmt&) rNew;
|
|
|
|
if( !rFmtCharFmt.GetCharFmt() )
|
|
|
|
rFmtCharFmt.SetCharFmt( GetDoc()->GetDfltCharFmt() );
|
|
|
|
|
|
|
|
pNew = new SwTxtCharFmt( rFmtCharFmt, nStt, nEnd );
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case RES_TXTATR_INETFMT:
|
|
|
|
pNew = new SwTxtINetFmt( (SwFmtINetFmt&)rNew, nStt, nEnd );
|
|
|
|
break;
|
|
|
|
case RES_TXTATR_FIELD:
|
|
|
|
pNew = new SwTxtFld( (SwFmtFld&)rNew, nStt );
|
|
|
|
break;
|
|
|
|
case RES_TXTATR_FLYCNT:
|
|
|
|
{
|
|
|
|
// erst hier wird das Frame-Format kopiert (mit Inhalt) !!
|
|
|
|
pNew = new SwTxtFlyCnt( (SwFmtFlyCnt&)rNew, nStt );
|
|
|
|
// Kopie von einem Text-Attribut
|
|
|
|
if( ((SwFmtFlyCnt&)rAttr).GetTxtFlyCnt() )
|
|
|
|
// dann muss das Format Kopiert werden
|
|
|
|
((SwTxtFlyCnt*)pNew)->CopyFlyFmt( GetDoc() );
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case RES_TXTATR_FTN:
|
|
|
|
pNew = new SwTxtFtn( (SwFmtFtn&)rNew, nStt );
|
|
|
|
// ggfs. SeqNo kopieren
|
|
|
|
if( ((SwFmtFtn&)rAttr).GetTxtFtn() )
|
|
|
|
((SwTxtFtn*)pNew)->SetSeqNo( ((SwFmtFtn&)rAttr).GetTxtFtn()->GetSeqRefNo() );
|
|
|
|
break;
|
|
|
|
case RES_TXTATR_HARDBLANK:
|
|
|
|
pNew = new SwTxtHardBlank( (SwFmtHardBlank&)rNew, nStt );
|
|
|
|
break;
|
2000-11-02 16:28:47 +00:00
|
|
|
case RES_CHRATR_TWO_LINES:
|
2000-11-16 20:31:21 +00:00
|
|
|
pNew = new SwTxt2Lines( (SvxTwoLinesItem&)rNew, nStt, nEnd );
|
2000-11-02 16:28:47 +00:00
|
|
|
break;
|
2000-09-18 23:08:29 +00:00
|
|
|
case RES_TXTATR_REFMARK:
|
|
|
|
pNew = nStt == nEnd
|
|
|
|
? new SwTxtRefMark( (SwFmtRefMark&)rNew, nStt )
|
|
|
|
: new SwTxtRefMark( (SwFmtRefMark&)rNew, nStt, &nEnd );
|
|
|
|
break;
|
|
|
|
case RES_TXTATR_TOXMARK:
|
|
|
|
pNew = new SwTxtTOXMark( (SwTOXMark&)rNew, nStt, &nEnd );
|
|
|
|
break;
|
|
|
|
case RES_UNKNOWNATR_CONTAINER:
|
2000-10-20 11:36:57 +00:00
|
|
|
case RES_TXTATR_UNKNOWN_CONTAINER:
|
2000-09-18 23:08:29 +00:00
|
|
|
pNew = new SwTxtXMLAttrContainer( (SvXMLAttrContainerItem&)rNew,
|
|
|
|
nStt, nEnd );
|
|
|
|
break;
|
2000-10-23 10:58:55 +00:00
|
|
|
case RES_TXTATR_CJK_RUBY:
|
|
|
|
pNew = new SwTxtRuby( (SwFmtRuby&)rNew, nStt, nEnd );
|
|
|
|
break;
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
ASSERT( pNew, "was fuer ein TextAttribut soll hier angelegt werden?" );
|
|
|
|
return pNew;
|
|
|
|
}
|
|
|
|
|
|
|
|
// loesche das Text-Attribut (muss beim Pool abgemeldet werden!)
|
|
|
|
void SwTxtNode::DestroyAttr( SwTxtAttr* pAttr )
|
|
|
|
{
|
|
|
|
if( pAttr )
|
|
|
|
{
|
|
|
|
// einige Sachen muessen vorm Loeschen der "Format-Attribute" erfolgen
|
|
|
|
SwDoc* pDoc = GetDoc();
|
2001-10-31 19:50:21 +00:00
|
|
|
USHORT nDelMsg = 0;
|
2000-09-18 23:08:29 +00:00
|
|
|
switch( pAttr->Which() )
|
|
|
|
{
|
|
|
|
case RES_TXTATR_FLYCNT:
|
|
|
|
{
|
|
|
|
// siehe auch die Anmerkung "Loeschen von Formaten
|
|
|
|
// zeichengebundener Frames" in fesh.cxx, SwFEShell::DelFmt()
|
|
|
|
SwFrmFmt* pFmt = pAttr->GetFlyCnt().GetFrmFmt();
|
|
|
|
if( pFmt ) // vom Undo auf 0 gesetzt ??
|
|
|
|
pDoc->DelLayoutFmt( (SwFlyFrmFmt*)pFmt );
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RES_TXTATR_FTN:
|
|
|
|
((SwTxtFtn*)pAttr)->SetStartNode( 0 );
|
2001-10-31 19:50:21 +00:00
|
|
|
nDelMsg = RES_FOOTNOTE_DELETED;
|
2000-09-18 23:08:29 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case RES_TXTATR_FIELD:
|
|
|
|
if( !pDoc->IsInDtor() )
|
|
|
|
{
|
|
|
|
// Wenn wir ein HiddenParaField sind, dann muessen wir
|
|
|
|
// ggf. fuer eine Neuberechnung des Visible-Flags sorgen.
|
|
|
|
const SwField* pFld = pAttr->GetFld().GetFld();
|
|
|
|
|
|
|
|
//JP 06-08-95: DDE-Felder bilden eine Ausnahme
|
|
|
|
ASSERT( RES_DDEFLD == pFld->GetTyp()->Which() ||
|
|
|
|
this == ((SwTxtFld*)pAttr)->GetpTxtNode(),
|
|
|
|
"Wo steht denn dieses Feld?" )
|
|
|
|
|
|
|
|
// bestimmte Felder mussen am Doc das Calculations-Flag updaten
|
|
|
|
switch( pFld->GetTyp()->Which() )
|
|
|
|
{
|
|
|
|
case RES_HIDDENPARAFLD:
|
|
|
|
SetCalcVisible();
|
|
|
|
// kein break !
|
|
|
|
case RES_DBSETNUMBERFLD:
|
|
|
|
case RES_GETEXPFLD:
|
|
|
|
case RES_DBFLD:
|
|
|
|
case RES_SETEXPFLD:
|
|
|
|
case RES_HIDDENTXTFLD:
|
|
|
|
case RES_DBNUMSETFLD:
|
|
|
|
case RES_DBNEXTSETFLD:
|
|
|
|
if( !pDoc->IsNewFldLst() && GetNodes().IsDocNodes() )
|
|
|
|
pDoc->InsDelFldInFldLst( FALSE, *(SwTxtFld*)pAttr );
|
|
|
|
break;
|
|
|
|
case RES_DDEFLD:
|
|
|
|
if( GetNodes().IsDocNodes() &&
|
|
|
|
((SwTxtFld*)pAttr)->GetpTxtNode() )
|
|
|
|
((SwDDEFieldType*)pFld->GetTyp())->DecRefCnt();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2001-10-31 19:50:21 +00:00
|
|
|
nDelMsg = RES_FIELD_DELETED;
|
2000-09-18 23:08:29 +00:00
|
|
|
break;
|
|
|
|
|
2001-10-31 19:50:21 +00:00
|
|
|
case RES_TXTATR_TOXMARK:
|
|
|
|
nDelMsg = RES_TOXMARK_DELETED;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RES_TXTATR_REFMARK:
|
|
|
|
nDelMsg = RES_REFMARK_DELETED;
|
|
|
|
break;
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
2001-10-31 19:50:21 +00:00
|
|
|
|
|
|
|
if( nDelMsg && !pDoc->IsInDtor() && GetNodes().IsDocNodes() )
|
|
|
|
{
|
|
|
|
SwPtrMsgPoolItem aMsgHint( nDelMsg, (void*)&pAttr->GetAttr() );
|
|
|
|
pDoc->GetUnoCallBack()->Modify( &aMsgHint, &aMsgHint );
|
|
|
|
}
|
|
|
|
|
2000-09-18 23:08:29 +00:00
|
|
|
pAttr->RemoveFromPool( pDoc->GetAttrPool() );
|
|
|
|
delete pAttr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
* SwTxtNode::Insert()
|
|
|
|
*************************************************************************/
|
|
|
|
|
|
|
|
// lege ein neues TextAttribut an und fuege es ins SwpHints-Array ein
|
|
|
|
SwTxtAttr* SwTxtNode::Insert( const SfxPoolItem& rAttr,
|
|
|
|
xub_StrLen nStt, xub_StrLen nEnd, USHORT nMode )
|
|
|
|
{
|
|
|
|
SwTxtAttr* pNew = MakeTxtAttr( rAttr, nStt, nEnd );
|
|
|
|
return (pNew && Insert( pNew, nMode )) ? pNew : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// uebernehme den Pointer auf das Text-Attribut
|
|
|
|
|
|
|
|
BOOL SwTxtNode::Insert( SwTxtAttr *pAttr, USHORT nMode )
|
|
|
|
{
|
|
|
|
BOOL bHiddenPara = FALSE;
|
|
|
|
|
|
|
|
ASSERT( *pAttr->GetStart() <= Len(), "StartIdx hinter Len!" );
|
|
|
|
|
|
|
|
if( !pAttr->GetEnd() )
|
|
|
|
{
|
|
|
|
USHORT nInsMode = nMode;
|
|
|
|
switch( pAttr->Which() )
|
|
|
|
{
|
|
|
|
case RES_TXTATR_FLYCNT:
|
|
|
|
{
|
|
|
|
SwTxtFlyCnt *pFly = (SwTxtFlyCnt *)pAttr;
|
|
|
|
SwFrmFmt* pFmt = pAttr->GetFlyCnt().GetFrmFmt();
|
|
|
|
if( !(SETATTR_NOTXTATRCHR & nInsMode) )
|
|
|
|
{
|
|
|
|
// Wir muessen zuerst einfuegen, da in SetAnchor()
|
|
|
|
// dem FlyFrm GetStart() uebermittelt wird.
|
|
|
|
//JP 11.05.98: falls das Anker-Attribut schon richtig
|
|
|
|
// gesetzt ist, dann korrigiere dieses nach dem Einfuegen
|
|
|
|
// des Zeichens. Sonst muesste das immer ausserhalb
|
|
|
|
// erfolgen (Fehleranfaellig !)
|
|
|
|
const SwFmtAnchor* pAnchor = 0;
|
|
|
|
pFmt->GetItemState( RES_ANCHOR, FALSE,
|
|
|
|
(const SfxPoolItem**)&pAnchor );
|
|
|
|
|
|
|
|
SwIndex aIdx( this, *pAttr->GetStart() );
|
|
|
|
Insert( GetCharOfTxtAttr(*pAttr), aIdx );
|
|
|
|
nInsMode |= SETATTR_NOTXTATRCHR;
|
|
|
|
|
|
|
|
if( pAnchor && FLY_IN_CNTNT == pAnchor->GetAnchorId() &&
|
|
|
|
pAnchor->GetCntntAnchor() &&
|
|
|
|
pAnchor->GetCntntAnchor()->nNode == *this &&
|
|
|
|
pAnchor->GetCntntAnchor()->nContent == aIdx )
|
|
|
|
((SwIndex&)pAnchor->GetCntntAnchor()->nContent)--;
|
|
|
|
}
|
|
|
|
pFly->SetAnchor( this );
|
|
|
|
|
|
|
|
// Format-Pointer kann sich im SetAnchor geaendert haben!
|
|
|
|
// (Kopieren in andere Docs!)
|
|
|
|
pFmt = pAttr->GetFlyCnt().GetFrmFmt();
|
|
|
|
SwDoc *pDoc = pFmt->GetDoc();
|
|
|
|
|
|
|
|
if( RES_DRAWFRMFMT == pFmt->Which() &&
|
|
|
|
pDoc->IsInHeaderFooter(
|
|
|
|
pFmt->GetAnchor().GetCntntAnchor()->nNode ) )
|
|
|
|
{
|
|
|
|
// das soll nicht meoglich sein; hier verhindern
|
|
|
|
// Der Dtor des TxtHints loescht nicht das Zeichen.
|
|
|
|
// Wenn ein CH_TXTATR_.. vorliegt, dann muss man
|
|
|
|
// dieses explizit loeschen
|
|
|
|
if( SETATTR_NOTXTATRCHR & nInsMode )
|
|
|
|
{
|
|
|
|
// loesche das Zeichen aus dem String !
|
|
|
|
ASSERT( ( CH_TXTATR_BREAKWORD ==
|
|
|
|
aText.GetChar(*pAttr->GetStart() ) ||
|
|
|
|
CH_TXTATR_INWORD ==
|
|
|
|
aText.GetChar(*pAttr->GetStart())),
|
|
|
|
"where is my attribu character" );
|
|
|
|
aText.Erase( *pAttr->GetStart(), 1 );
|
|
|
|
// Indizies Updaten
|
|
|
|
SwIndex aTmpIdx( this, *pAttr->GetStart() );
|
|
|
|
Update( aTmpIdx, 1, TRUE );
|
|
|
|
}
|
|
|
|
// Format loeschen nicht ins Undo aufnehmen!!
|
|
|
|
BOOL bUndo = pDoc->DoesUndo();
|
|
|
|
pDoc->DoUndo( FALSE );
|
|
|
|
DestroyAttr( pAttr );
|
|
|
|
pDoc->DoUndo( bUndo );
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case RES_TXTATR_FTN :
|
|
|
|
{
|
|
|
|
// Fussnoten, man kommt an alles irgendwie heran.
|
|
|
|
// CntntNode erzeugen und in die Inserts-Section stellen
|
|
|
|
SwDoc *pDoc = GetDoc();
|
|
|
|
SwNodes &rNodes = pDoc->GetNodes();
|
|
|
|
|
|
|
|
// FussNote in nicht Content-/Redline-Bereich einfuegen ??
|
|
|
|
if( StartOfSectionIndex() < rNodes.GetEndOfAutotext().GetIndex() )
|
|
|
|
{
|
|
|
|
// das soll nicht meoglich sein; hier verhindern
|
|
|
|
// Der Dtor des TxtHints loescht nicht das Zeichen.
|
|
|
|
// Wenn ein CH_TXTATR_.. vorliegt, dann muss man
|
|
|
|
// dieses explizit loeschen
|
|
|
|
if( SETATTR_NOTXTATRCHR & nInsMode )
|
|
|
|
{
|
|
|
|
// loesche das Zeichen aus dem String !
|
|
|
|
ASSERT( ( CH_TXTATR_BREAKWORD ==
|
|
|
|
aText.GetChar(*pAttr->GetStart() ) ||
|
|
|
|
CH_TXTATR_INWORD ==
|
|
|
|
aText.GetChar(*pAttr->GetStart())),
|
|
|
|
"where is my attribu character" );
|
|
|
|
aText.Erase( *pAttr->GetStart(), 1 );
|
|
|
|
// Indizies Updaten
|
|
|
|
SwIndex aTmpIdx( this, *pAttr->GetStart() );
|
|
|
|
Update( aTmpIdx, 1, TRUE );
|
|
|
|
}
|
|
|
|
DestroyAttr( pAttr );
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// wird eine neue Fussnote eingefuegt ??
|
|
|
|
BOOL bNewFtn = 0 == ((SwTxtFtn*)pAttr)->GetStartNode();
|
|
|
|
if( bNewFtn )
|
|
|
|
((SwTxtFtn*)pAttr)->MakeNewTextSection( GetNodes() );
|
|
|
|
else if ( !GetpSwpHints() || !GetpSwpHints()->IsInSplitNode() )
|
|
|
|
{
|
|
|
|
// loesche alle Frames der Section, auf die der StartNode zeigt
|
|
|
|
ULONG nSttIdx =
|
|
|
|
((SwTxtFtn*)pAttr)->GetStartNode()->GetIndex();
|
|
|
|
ULONG nEndIdx = rNodes[ nSttIdx++ ]->EndOfSectionIndex();
|
|
|
|
SwCntntNode* pCNd;
|
|
|
|
for( ; nSttIdx < nEndIdx; ++nSttIdx )
|
|
|
|
if( 0 != ( pCNd = rNodes[ nSttIdx ]->GetCntntNode() ))
|
|
|
|
pCNd->DelFrms();
|
|
|
|
}
|
|
|
|
|
|
|
|
if( !(SETATTR_NOTXTATRCHR & nInsMode) )
|
|
|
|
{
|
|
|
|
// Wir muessen zuerst einfuegen, da sonst gleiche Indizes
|
|
|
|
// entstehen koennen und das Attribut im _SortArr_ am
|
|
|
|
// Dokument nicht eingetrage wird.
|
|
|
|
SwIndex aNdIdx( this, *pAttr->GetStart() );
|
|
|
|
Insert( GetCharOfTxtAttr(*pAttr), aNdIdx );
|
|
|
|
nInsMode |= SETATTR_NOTXTATRCHR;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Wir tragen uns am FtnIdx-Array des Docs ein ...
|
|
|
|
SwTxtFtn* pTxtFtn = 0;
|
|
|
|
if( !bNewFtn )
|
|
|
|
{
|
|
|
|
// eine alte Ftn wird umgehaengt (z.B. SplitNode)
|
|
|
|
for( USHORT n = 0; n < pDoc->GetFtnIdxs().Count(); ++n )
|
|
|
|
if( pAttr == pDoc->GetFtnIdxs()[n] )
|
|
|
|
{
|
|
|
|
// neuen Index zuweisen, dafuer aus dem SortArray
|
|
|
|
// loeschen und neu eintragen
|
|
|
|
pTxtFtn = pDoc->GetFtnIdxs()[n];
|
|
|
|
pDoc->GetFtnIdxs().Remove( n );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
// wenn ueber Undo der StartNode gesetzt wurde, kann
|
|
|
|
// der Index noch gar nicht in der Verwaltung stehen !!
|
|
|
|
}
|
|
|
|
if( !pTxtFtn )
|
|
|
|
pTxtFtn = (SwTxtFtn*)pAttr;
|
|
|
|
|
|
|
|
// fuers Update der Nummern und zum Sortieren
|
|
|
|
// muss der Node gesetzt sein.
|
|
|
|
((SwTxtFtn*)pAttr)->ChgTxtNode( this );
|
|
|
|
|
|
|
|
// FussNote im Redline-Bereich NICHT ins FtnArray einfuegen!
|
|
|
|
if( StartOfSectionIndex() > rNodes.GetEndOfRedlines().GetIndex() )
|
|
|
|
{
|
|
|
|
#ifndef PRODUCT
|
|
|
|
const BOOL bSuccess =
|
|
|
|
#endif
|
|
|
|
pDoc->GetFtnIdxs().Insert( pTxtFtn );
|
|
|
|
#ifndef PRODUCT
|
|
|
|
ASSERT( bSuccess, "FtnIdx nicht eingetragen." );
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
SwNodeIndex aTmpIndex( *this );
|
|
|
|
pDoc->GetFtnIdxs().UpdateFtn( aTmpIndex);
|
|
|
|
((SwTxtFtn*)pAttr)->SetSeqRefNo();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RES_TXTATR_FIELD:
|
|
|
|
{
|
|
|
|
// fuer HiddenParaFields Benachrichtigungsmechanismus
|
|
|
|
// anwerfen
|
|
|
|
if( RES_HIDDENPARAFLD ==
|
|
|
|
pAttr->GetFld().GetFld()->GetTyp()->Which() )
|
|
|
|
bHiddenPara = TRUE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
// Fuer SwTxtHints ohne Endindex werden CH_TXTATR_..
|
|
|
|
// eingefuegt, aStart muss danach um einen zurueckgesetzt werden.
|
|
|
|
// Wenn wir im SwTxtNode::Copy stehen, so wurde das Zeichen bereits
|
|
|
|
// mitkopiert. In solchem Fall ist SETATTR_NOTXTATRCHR angegeben worden.
|
|
|
|
if( !(SETATTR_NOTXTATRCHR & nInsMode) )
|
|
|
|
{
|
|
|
|
SwIndex aIdx( this, *pAttr->GetStart() );
|
|
|
|
Insert( GetCharOfTxtAttr(*pAttr), aIdx );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ASSERT( *pAttr->GetEnd() <= Len(), "EndIdx hinter Len!" );
|
|
|
|
|
|
|
|
if ( !pSwpHints )
|
|
|
|
pSwpHints = new SwpHints();
|
|
|
|
|
|
|
|
// 4263: AttrInsert durch TextInsert => kein Adjust
|
|
|
|
pSwpHints->Insert( pAttr, *this, nMode );
|
|
|
|
|
|
|
|
// 47375: In pSwpHints->Insert wird u.a. Merge gerufen und das Hints-Array
|
|
|
|
// von ueberfluessigen Hints befreit, dies kann u.U. sogar der frisch
|
|
|
|
// eingefuegte Hint pAttr sein, der dann zerstoert wird!!
|
|
|
|
if( USHRT_MAX == pSwpHints->GetPos( pAttr ) )
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if(bHiddenPara)
|
|
|
|
SetCalcVisible();
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
* SwTxtNode::Delete()
|
|
|
|
*************************************************************************/
|
|
|
|
|
|
|
|
void SwTxtNode::Delete( SwTxtAttr *pAttr, BOOL bThisOnly )
|
|
|
|
{
|
|
|
|
if ( !pSwpHints )
|
|
|
|
return;
|
|
|
|
if( bThisOnly )
|
|
|
|
{
|
|
|
|
xub_StrLen* pEndIdx = pAttr->GetEnd();
|
|
|
|
if( !pEndIdx )
|
|
|
|
{
|
|
|
|
// hat es kein Ende kann es nur das sein, was hier steht!
|
|
|
|
// Unbedingt Copy-konstruieren!
|
|
|
|
const SwIndex aIdx( this, *pAttr->GetStart() );
|
|
|
|
Erase( aIdx, 1 );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// den MsgHint jetzt fuettern, weil gleich sind
|
|
|
|
// Start und End weg.
|
|
|
|
SwUpdateAttr aHint( *pAttr->GetStart(), *pEndIdx, pAttr->Which() );
|
|
|
|
pSwpHints->Delete( pAttr );
|
|
|
|
pAttr->RemoveFromPool( GetDoc()->GetAttrPool() );
|
|
|
|
delete pAttr;
|
|
|
|
SwModify::Modify( 0, &aHint ); // die Frames benachrichtigen
|
|
|
|
|
|
|
|
if( pSwpHints && pSwpHints->CanBeDeleted() )
|
|
|
|
DELETEZ( pSwpHints );
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
Delete( pAttr->Which(), *pAttr->GetStart(), *pAttr->GetAnyEnd() );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
* SwTxtNode::Delete()
|
|
|
|
*************************************************************************/
|
|
|
|
|
|
|
|
void SwTxtNode::Delete( USHORT nTxtWhich, xub_StrLen nStart, xub_StrLen nEnd )
|
|
|
|
{
|
|
|
|
if ( !pSwpHints )
|
|
|
|
return;
|
|
|
|
|
|
|
|
const xub_StrLen *pEndIdx;
|
|
|
|
const xub_StrLen *pSttIdx;
|
|
|
|
SwTxtAttr* pTxtHt;
|
|
|
|
|
|
|
|
for( USHORT nPos = 0; pSwpHints && nPos < pSwpHints->Count(); nPos++ )
|
|
|
|
{
|
|
|
|
pTxtHt = pSwpHints->GetHt( nPos );
|
|
|
|
const USHORT nWhich = pTxtHt->Which();
|
|
|
|
if( nWhich == nTxtWhich &&
|
|
|
|
*( pSttIdx = pTxtHt->GetStart()) == nStart )
|
|
|
|
{
|
|
|
|
pEndIdx = pTxtHt->GetEnd();
|
|
|
|
|
|
|
|
// Text-Attribute sind voellig dynamisch, so dass diese nur
|
|
|
|
// mit ihrer Start-Position verglichen werden.
|
|
|
|
if( !pEndIdx )
|
|
|
|
{
|
|
|
|
// Unbedingt Copy-konstruieren!
|
|
|
|
const SwIndex aIdx( this, *pSttIdx );
|
|
|
|
Erase( aIdx, 1 );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else if( *pEndIdx == nEnd )
|
|
|
|
{
|
|
|
|
// den MsgHint jetzt fuettern, weil gleich sind
|
|
|
|
// Start und End weg.
|
|
|
|
// Das CalcVisibleFlag bei HiddenParaFields entfaellt,
|
|
|
|
// da dies das Feld im Dtor selbst erledigt.
|
|
|
|
SwUpdateAttr aHint( *pSttIdx, *pEndIdx, nTxtWhich );
|
|
|
|
pSwpHints->DeleteAtPos( nPos ); // gefunden, loeschen,
|
|
|
|
pTxtHt->RemoveFromPool( GetDoc()->GetAttrPool() );
|
|
|
|
delete pTxtHt;
|
|
|
|
SwModify::Modify( 0, &aHint ); // die Frames benachrichtigen
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if( pSwpHints && pSwpHints->CanBeDeleted() )
|
|
|
|
DELETEZ( pSwpHints );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
* SwTxtNode::DelSoftHyph()
|
|
|
|
*************************************************************************/
|
|
|
|
|
|
|
|
void SwTxtNode::DelSoftHyph( const xub_StrLen nStart, const xub_StrLen nEnd )
|
|
|
|
{
|
|
|
|
xub_StrLen nFndPos = nStart, nEndPos = nEnd;
|
|
|
|
while( STRING_NOTFOUND !=
|
|
|
|
( nFndPos = aText.Search( CHAR_SOFTHYPHEN, nFndPos )) &&
|
|
|
|
nFndPos < nEndPos )
|
|
|
|
{
|
2001-01-30 12:41:55 +00:00
|
|
|
const SwIndex aIdx( this, nFndPos );
|
|
|
|
Erase( aIdx, 1 );
|
2000-09-18 23:08:29 +00:00
|
|
|
--nEndPos;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// setze diese Attribute am TextNode. Wird der gesamte Bereich umspannt,
|
|
|
|
// dann setze sie nur im AutoAttrSet (SwCntntNode:: SetAttr)
|
|
|
|
BOOL SwTxtNode::SetAttr( const SfxItemSet& rSet, xub_StrLen nStt,
|
|
|
|
xub_StrLen nEnd, USHORT nMode )
|
|
|
|
{
|
|
|
|
if( !rSet.Count() )
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
// teil die Sets auf (fuer Selektion in Nodes)
|
|
|
|
const SfxItemSet* pSet = &rSet;
|
|
|
|
SfxItemSet aTxtSet( *rSet.GetPool(), RES_TXTATR_BEGIN, RES_TXTATR_END-1 );
|
|
|
|
|
|
|
|
// gesamter Bereich
|
|
|
|
if( !nStt && nEnd == aText.Len() && !(nMode & SETATTR_NOFORMATATTR ) )
|
|
|
|
{
|
|
|
|
// sind am Node schon Zeichenvorlagen gesetzt, muss man diese Attribute
|
|
|
|
// (rSet) immer als TextAttribute setzen, damit sie angezeigt werden.
|
|
|
|
int bHasCharFmts = FALSE;
|
|
|
|
if( pSwpHints )
|
2000-11-06 09:43:55 +00:00
|
|
|
for( USHORT n = 0; n < pSwpHints->Count(); ++n )
|
|
|
|
if( (*pSwpHints)[ n ]->IsCharFmtAttr() )
|
|
|
|
{
|
|
|
|
bHasCharFmts = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
2000-09-18 23:08:29 +00:00
|
|
|
|
|
|
|
if( !bHasCharFmts )
|
|
|
|
{
|
|
|
|
aTxtSet.Put( rSet );
|
|
|
|
if( aTxtSet.Count() != rSet.Count() )
|
|
|
|
{
|
|
|
|
BOOL bRet = SwCntntNode::SetAttr( rSet );
|
|
|
|
if( !aTxtSet.Count() )
|
|
|
|
return bRet;
|
|
|
|
}
|
|
|
|
pSet = &aTxtSet;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( !pSwpHints )
|
|
|
|
pSwpHints = new SwpHints();
|
|
|
|
|
|
|
|
USHORT nWhich, nCount = 0;
|
|
|
|
SwTxtAttr* pNew;
|
|
|
|
SfxItemIter aIter( *pSet );
|
|
|
|
const SfxPoolItem* pItem = aIter.GetCurItem();
|
|
|
|
do {
|
|
|
|
if( pItem && (SfxPoolItem*)-1 != pItem &&
|
|
|
|
(( RES_CHRATR_BEGIN <= ( nWhich = pItem->Which()) &&
|
|
|
|
RES_CHRATR_END > nWhich ) ||
|
|
|
|
( RES_TXTATR_BEGIN <= nWhich && RES_TXTATR_END > nWhich ) ||
|
|
|
|
( RES_UNKNOWNATR_BEGIN <= nWhich && RES_UNKNOWNATR_END > nWhich )) )
|
|
|
|
{
|
|
|
|
if( RES_TXTATR_CHARFMT == pItem->Which() &&
|
|
|
|
GetDoc()->GetDfltCharFmt()==((SwFmtCharFmt*)pItem)->GetCharFmt())
|
|
|
|
{
|
|
|
|
SwIndex aIndex( this, nStt );
|
|
|
|
RstAttr( aIndex, nEnd - nStt, RES_TXTATR_CHARFMT, 0 );
|
|
|
|
DontExpandFmt( aIndex );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pNew = MakeTxtAttr( *pItem, nStt, nEnd );
|
|
|
|
if( pNew )
|
|
|
|
{
|
|
|
|
// Attribut ohne Ende, aber Bereich markiert ?
|
|
|
|
if( nEnd != nStt && !pNew->GetEnd() )
|
|
|
|
{
|
|
|
|
ASSERT( !this, "Attribut ohne Ende aber Bereich vorgegeben" );
|
|
|
|
DestroyAttr( pNew ); // nicht einfuegen
|
|
|
|
}
|
|
|
|
else if( Insert( pNew, nMode ))
|
|
|
|
++nCount;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if( aIter.IsAtEnd() )
|
|
|
|
break;
|
|
|
|
pItem = aIter.NextItem();
|
|
|
|
} while( TRUE );
|
|
|
|
|
|
|
|
if( pSwpHints && pSwpHints->CanBeDeleted() )
|
|
|
|
DELETEZ( pSwpHints );
|
|
|
|
|
|
|
|
return nCount ? TRUE : FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL lcl_Included( const USHORT nWhich, const SwTxtAttr *pAttr )
|
|
|
|
{
|
|
|
|
#ifdef DEBUG
|
|
|
|
static long nTest = 0;
|
|
|
|
++nTest;
|
|
|
|
#endif
|
|
|
|
BOOL bRet;
|
|
|
|
SwCharFmt* pFmt = RES_TXTATR_INETFMT == pAttr->Which() ?
|
|
|
|
((SwTxtINetFmt*)pAttr)->GetCharFmt() :
|
|
|
|
pAttr->GetCharFmt().GetCharFmt();
|
|
|
|
if( pFmt )
|
|
|
|
bRet = SFX_ITEM_SET == pFmt->GetAttrSet().GetItemState( nWhich, TRUE );
|
|
|
|
else
|
|
|
|
bRet = FALSE;
|
|
|
|
return bRet;
|
|
|
|
}
|
|
|
|
|
|
|
|
void lcl_MergeAttr( SfxItemSet& rSet, const SfxPoolItem& rAttr )
|
|
|
|
{
|
|
|
|
rSet.Put( rAttr );
|
|
|
|
}
|
|
|
|
|
|
|
|
void lcl_MergeAttr_ExpandChrFmt( SfxItemSet& rSet, const SfxPoolItem& rAttr )
|
|
|
|
{
|
|
|
|
if( RES_TXTATR_CHARFMT == rAttr.Which() ||
|
|
|
|
RES_TXTATR_INETFMT == rAttr.Which() )
|
|
|
|
{
|
|
|
|
// aus der Vorlage die Attribute holen:
|
|
|
|
SwCharFmt* pFmt = RES_TXTATR_INETFMT == rAttr.Which() ?
|
|
|
|
((SwFmtINetFmt&)rAttr).GetTxtINetFmt()->GetCharFmt() :
|
|
|
|
((SwFmtCharFmt&)rAttr).GetCharFmt();
|
|
|
|
if( pFmt )
|
|
|
|
{
|
|
|
|
const SfxItemSet& rCFSet = pFmt->GetAttrSet();
|
|
|
|
SfxWhichIter aIter( rCFSet );
|
|
|
|
register USHORT nWhich = aIter.FirstWhich();
|
|
|
|
while( nWhich )
|
|
|
|
{
|
|
|
|
if( ( nWhich < RES_CHRATR_END ) &&
|
|
|
|
( SFX_ITEM_SET == rCFSet.GetItemState( nWhich, TRUE ) ) )
|
|
|
|
rSet.Put( rCFSet.Get( nWhich ) );
|
|
|
|
nWhich = aIter.NextWhich();
|
|
|
|
}
|
|
|
|
#if 0
|
|
|
|
SfxItemSet aTmpSet( *rSet.GetPool(), rSet.GetRanges() );
|
|
|
|
aTmpSet.Set( pFmt->GetAttrSet(), TRUE );
|
|
|
|
/*
|
|
|
|
????? JP 31.01.95 ???? wie jetzt ???
|
|
|
|
rSet.MergeValues( aTmpSet );
|
|
|
|
|
|
|
|
// jetzt alle zusammen "mergen"
|
|
|
|
rSet.Differentiate( aTmpSet );
|
|
|
|
*/
|
|
|
|
rSet.Put( aTmpSet );
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// aufnehmen als MergeWert (falls noch nicht gesetzt neu setzen!)
|
|
|
|
#if 0
|
|
|
|
/* wenn mehrere Attribute ueberlappen werden diese gemergt !!
|
|
|
|
z.B
|
|
|
|
1234567890123456789
|
|
|
|
|------------| Font1
|
|
|
|
|------| Font2
|
|
|
|
^ ^
|
|
|
|
|--| Abfragebereich: -> uneindeutig
|
|
|
|
*/
|
|
|
|
else if( SFX_ITEM_DEFAULT == rSet.GetItemState( rAttr.Which(), FALSE ))
|
|
|
|
rSet.Put( rAttr );
|
|
|
|
else
|
|
|
|
rSet.MergeValue( rAttr );
|
|
|
|
#else
|
|
|
|
/* wenn mehrere Attribute ueberlappen gewinnt der letze !!
|
|
|
|
z.B
|
|
|
|
1234567890123456789
|
|
|
|
|------------| Font1
|
|
|
|
|------| Font2
|
|
|
|
^ ^
|
|
|
|
|--| Abfragebereich: -> Gueltig ist Font2
|
|
|
|
*/
|
|
|
|
rSet.Put( rAttr );
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
// erfrage die Attribute vom TextNode ueber den Bereich
|
|
|
|
BOOL SwTxtNode::GetAttr( SfxItemSet& rSet, xub_StrLen nStart, xub_StrLen nEnd,
|
|
|
|
BOOL bOnlyTxtAttr, BOOL bGetFromChrFmt ) const
|
|
|
|
{
|
|
|
|
if( pSwpHints )
|
|
|
|
{
|
|
|
|
/* stelle erstmal fest, welche Text-Attribut in dem Bereich gueltig
|
|
|
|
* sind. Dabei gibt es folgende Faelle:
|
|
|
|
* UnEindeutig wenn: (wenn != Format-Attribut)
|
|
|
|
* - das Attribut liegt vollstaendig im Bereich
|
|
|
|
* - das Attributende liegt im Bereich
|
|
|
|
* - der Attributanfang liegt im Bereich:
|
|
|
|
* Eindeutig (im Set mergen):
|
|
|
|
* - das Attrib umfasst den Bereich
|
|
|
|
* nichts tun:
|
|
|
|
* das Attribut liegt ausserhalb des Bereiches
|
|
|
|
*/
|
|
|
|
|
|
|
|
void (*fnMergeAttr)( SfxItemSet&, const SfxPoolItem& )
|
|
|
|
= bGetFromChrFmt ? &lcl_MergeAttr_ExpandChrFmt
|
|
|
|
: &lcl_MergeAttr;
|
|
|
|
|
|
|
|
// dann besorge mal die Auto-(Fmt)Attribute
|
|
|
|
SfxItemSet aFmtSet( *rSet.GetPool(), rSet.GetRanges() );
|
|
|
|
if( !bOnlyTxtAttr )
|
|
|
|
SwCntntNode::GetAttr( aFmtSet );
|
|
|
|
|
|
|
|
const USHORT nSize = pSwpHints->Count();
|
|
|
|
register USHORT n;
|
|
|
|
register xub_StrLen nAttrStart;
|
|
|
|
register const xub_StrLen* pAttrEnd;
|
|
|
|
|
|
|
|
if( nStart == nEnd ) // kein Bereich:
|
|
|
|
{
|
|
|
|
for( n = 0; n < nSize; ++n ) //
|
|
|
|
{
|
|
|
|
const SwTxtAttr* pHt = (*pSwpHints)[n];
|
|
|
|
nAttrStart = *pHt->GetStart();
|
|
|
|
if( nAttrStart > nEnd ) // ueber den Bereich hinaus
|
|
|
|
break;
|
|
|
|
|
|
|
|
if( 0 == ( pAttrEnd = pHt->GetEnd() )) // nie Attribute ohne Ende
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if( ( nAttrStart < nStart &&
|
|
|
|
( pHt->DontExpand() ? nStart < *pAttrEnd
|
|
|
|
: nStart <= *pAttrEnd )) ||
|
|
|
|
( nStart == nAttrStart &&
|
|
|
|
( nAttrStart == *pAttrEnd || !nStart )))
|
|
|
|
(*fnMergeAttr)( rSet, pHt->GetAttr() );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else // es ist ein Bereich definiert
|
|
|
|
{
|
|
|
|
SwTxtAttr** aAttrArr = 0;
|
|
|
|
const USHORT coArrSz = RES_TXTATR_WITHEND_END - RES_CHRATR_BEGIN +
|
|
|
|
( RES_UNKNOWNATR_END -
|
|
|
|
RES_UNKNOWNATR_BEGIN );
|
|
|
|
|
|
|
|
for( n = 0; n < nSize; ++n )
|
|
|
|
{
|
|
|
|
const SwTxtAttr* pHt = (*pSwpHints)[n];
|
|
|
|
nAttrStart = *pHt->GetStart();
|
|
|
|
if( nAttrStart > nEnd ) // ueber den Bereich hinaus
|
|
|
|
break;
|
|
|
|
|
|
|
|
if( 0 == ( pAttrEnd = pHt->GetEnd() )) // nie Attribute ohne Ende
|
|
|
|
continue;
|
|
|
|
|
|
|
|
BOOL bChkInvalid = FALSE;
|
|
|
|
if( nAttrStart <= nStart ) // vor oder genau Start
|
|
|
|
{
|
|
|
|
if( *pAttrEnd <= nStart ) // liegt davor
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if( nEnd <= *pAttrEnd ) // hinter oder genau Ende
|
|
|
|
(*fnMergeAttr)( aFmtSet, pHt->GetAttr() );
|
|
|
|
else
|
|
|
|
// else if( pHt->GetAttr() != aFmtSet.Get( pHt->Which() ) )
|
|
|
|
// uneindeutig
|
|
|
|
bChkInvalid = TRUE;
|
|
|
|
}
|
|
|
|
else if( nAttrStart < nEnd // reicht in den Bereich
|
|
|
|
)// && pHt->GetAttr() != aFmtSet.Get( pHt->Which() ) )
|
|
|
|
bChkInvalid = TRUE;
|
|
|
|
|
|
|
|
if( bChkInvalid )
|
|
|
|
{
|
|
|
|
// uneindeutig ?
|
|
|
|
if( !aAttrArr )
|
|
|
|
{
|
|
|
|
aAttrArr = new SwTxtAttr* [ coArrSz ];
|
|
|
|
memset( aAttrArr, 0, sizeof( SwTxtAttr* ) * coArrSz );
|
|
|
|
}
|
|
|
|
|
|
|
|
const SwTxtAttr** ppPrev;
|
|
|
|
if( RES_CHRATR_BEGIN <= pHt->Which() &&
|
|
|
|
pHt->Which() < RES_TXTATR_WITHEND_END )
|
|
|
|
ppPrev = (const SwTxtAttr**)&aAttrArr[
|
|
|
|
pHt->Which() - RES_CHRATR_BEGIN ];
|
|
|
|
else if( RES_UNKNOWNATR_BEGIN <= pHt->Which() &&
|
|
|
|
pHt->Which() < RES_UNKNOWNATR_END )
|
|
|
|
ppPrev = (const SwTxtAttr**)&aAttrArr[
|
|
|
|
pHt->Which() - RES_UNKNOWNATR_BEGIN
|
|
|
|
+ ( RES_TXTATR_WITHEND_END -
|
|
|
|
RES_CHRATR_BEGIN ) ];
|
|
|
|
else
|
|
|
|
ppPrev = 0;
|
|
|
|
|
|
|
|
if( !*ppPrev )
|
|
|
|
{
|
|
|
|
if( nAttrStart > nStart )
|
|
|
|
{
|
|
|
|
rSet.InvalidateItem( pHt->Which() );
|
|
|
|
*ppPrev = (SwTxtAttr*)-1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
*ppPrev = pHt;
|
|
|
|
}
|
|
|
|
else if( (SwTxtAttr*)-1 != *ppPrev )
|
|
|
|
{
|
|
|
|
if( *(*ppPrev)->GetEnd() == nAttrStart &&
|
|
|
|
(*ppPrev)->GetAttr() == pHt->GetAttr() )
|
|
|
|
*ppPrev = pHt;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
rSet.InvalidateItem( pHt->Which() );
|
|
|
|
*ppPrev = (SwTxtAttr*)-1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if( aAttrArr )
|
|
|
|
{
|
|
|
|
const SwTxtAttr* pAttr;
|
|
|
|
for( n = 0; n < coArrSz; ++n )
|
|
|
|
if( 0 != ( pAttr = aAttrArr[ n ] ) &&
|
|
|
|
(SwTxtAttr*)-1 != pAttr )
|
|
|
|
{
|
|
|
|
USHORT nWh;
|
|
|
|
if( n < (RES_TXTATR_WITHEND_END -
|
|
|
|
RES_CHRATR_BEGIN ))
|
|
|
|
nWh = n + RES_CHRATR_BEGIN;
|
|
|
|
else
|
|
|
|
nWh = n - ( RES_TXTATR_WITHEND_END -
|
|
|
|
RES_CHRATR_BEGIN ) +
|
|
|
|
RES_UNKNOWNATR_BEGIN;
|
|
|
|
|
|
|
|
if( nEnd <= *pAttr->GetEnd() ) // hinter oder genau Ende
|
|
|
|
{
|
|
|
|
if( pAttr->GetAttr() != aFmtSet.Get( nWh ) )
|
|
|
|
(*fnMergeAttr)( rSet, pAttr->GetAttr() );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
// uneindeutig
|
|
|
|
rSet.InvalidateItem( nWh );
|
|
|
|
}
|
|
|
|
__DELETE( coArrSz ) aAttrArr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if( aFmtSet.Count() )
|
|
|
|
{
|
|
|
|
// aus dem Format-Set alle entfernen, die im TextSet auch gesetzt sind
|
|
|
|
aFmtSet.Differentiate( rSet );
|
|
|
|
// jetzt alle zusammen "mergen"
|
|
|
|
rSet.Put( aFmtSet );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if( !bOnlyTxtAttr )
|
|
|
|
// dann besorge mal die Auto-(Fmt)Attribute
|
|
|
|
SwCntntNode::GetAttr( rSet );
|
|
|
|
|
|
|
|
return rSet.Count() ? TRUE : FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
int lcl_IsNewAttrInSet( const SwpHints& rHints, const SfxPoolItem& rItem,
|
2000-11-06 09:43:55 +00:00
|
|
|
const xub_StrLen nEnd )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
|
|
|
int bIns = TRUE;
|
|
|
|
for( USHORT i = 0; i < rHints.Count(); ++i )
|
|
|
|
{
|
|
|
|
const SwTxtAttr *pOther = rHints[ i ];
|
|
|
|
if( *pOther->GetStart() )
|
|
|
|
break;
|
|
|
|
|
|
|
|
if( pOther->GetEnd() &&
|
|
|
|
*pOther->GetEnd() == nEnd &&
|
2000-11-06 09:43:55 +00:00
|
|
|
( pOther->IsCharFmtAttr() || pOther->Which() == rItem.Which() ) )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
|
|
|
bIns = FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return bIns;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SwTxtNode::FmtToTxtAttr( SwTxtNode* pNd )
|
|
|
|
{
|
|
|
|
SfxItemSet aThisSet( GetDoc()->GetAttrPool(), aCharFmtSetRange );
|
|
|
|
if( GetpSwAttrSet() && GetpSwAttrSet()->Count() )
|
|
|
|
aThisSet.Put( *GetpSwAttrSet() );
|
|
|
|
|
|
|
|
if ( !pSwpHints )
|
|
|
|
pSwpHints = new SwpHints();
|
|
|
|
|
|
|
|
if( pNd == this )
|
|
|
|
{
|
|
|
|
if( aThisSet.Count() )
|
|
|
|
{
|
|
|
|
SfxItemIter aIter( aThisSet );
|
|
|
|
const SfxPoolItem* pItem = aIter.GetCurItem();
|
|
|
|
while( TRUE )
|
|
|
|
{
|
|
|
|
if( lcl_IsNewAttrInSet( *pSwpHints, *pItem, GetTxt().Len() ) )
|
|
|
|
{
|
|
|
|
pSwpHints->SwpHintsArr::Insert(
|
|
|
|
MakeTxtAttr( *pItem, 0, GetTxt().Len() ) );
|
|
|
|
GetpSwAttrSet()->ClearItem( pItem->Which() );
|
|
|
|
}
|
|
|
|
|
|
|
|
if( aIter.IsAtEnd() )
|
|
|
|
break;
|
|
|
|
pItem = aIter.NextItem();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SfxItemSet aNdSet( pNd->GetDoc()->GetAttrPool(), aCharFmtSetRange );
|
|
|
|
if( pNd->GetpSwAttrSet() && pNd->GetpSwAttrSet()->Count() )
|
|
|
|
aNdSet.Put( *pNd->GetpSwAttrSet() );
|
|
|
|
|
|
|
|
if ( !pNd->pSwpHints )
|
|
|
|
pNd->pSwpHints = new SwpHints();
|
|
|
|
|
|
|
|
if( aThisSet.Count() )
|
|
|
|
{
|
|
|
|
SfxItemIter aIter( aThisSet );
|
|
|
|
const SfxPoolItem* pItem = aIter.GetCurItem(), *pNdItem;
|
|
|
|
while( TRUE )
|
|
|
|
{
|
|
|
|
if( ( SFX_ITEM_SET != aNdSet.GetItemState( pItem->Which(), FALSE,
|
|
|
|
&pNdItem ) || *pItem != *pNdItem ) &&
|
|
|
|
lcl_IsNewAttrInSet( *pSwpHints, *pItem, GetTxt().Len() ) )
|
|
|
|
{
|
|
|
|
pSwpHints->SwpHintsArr::Insert(
|
|
|
|
MakeTxtAttr( *pItem, 0, GetTxt().Len() ) );
|
|
|
|
GetpSwAttrSet()->ClearItem( pItem->Which() );
|
|
|
|
}
|
|
|
|
aNdSet.ClearItem( pItem->Which() );
|
|
|
|
|
|
|
|
if( aIter.IsAtEnd() )
|
|
|
|
break;
|
|
|
|
pItem = aIter.NextItem();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( aNdSet.Count() )
|
|
|
|
{
|
|
|
|
SfxItemIter aIter( aNdSet );
|
|
|
|
const SfxPoolItem* pItem = aIter.GetCurItem();
|
|
|
|
while( TRUE )
|
|
|
|
{
|
|
|
|
if( lcl_IsNewAttrInSet( *pNd->pSwpHints, *pItem, pNd->GetTxt().Len() ) )
|
|
|
|
pNd->pSwpHints->SwpHintsArr::Insert(
|
|
|
|
pNd->MakeTxtAttr( *pItem, 0, pNd->GetTxt().Len() ) );
|
|
|
|
pNd->GetpSwAttrSet()->ClearItem( pItem->Which() );
|
|
|
|
|
|
|
|
if( aIter.IsAtEnd() )
|
|
|
|
break;
|
|
|
|
pItem = aIter.NextItem();
|
|
|
|
}
|
|
|
|
|
|
|
|
SwFmtChg aTmp1( pNd->GetFmtColl() );
|
|
|
|
pNd->SwModify::Modify( &aTmp1, &aTmp1 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( pNd->pSwpHints->CanBeDeleted() )
|
|
|
|
DELETEZ( pNd->pSwpHints );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
* SwpHints::CalcFlags()
|
|
|
|
*************************************************************************/
|
|
|
|
|
|
|
|
void SwpHints::CalcFlags()
|
|
|
|
{
|
|
|
|
bDDEFlds = bFtn = FALSE;
|
|
|
|
const USHORT nSize = Count();
|
|
|
|
const SwTxtAttr* pAttr;
|
|
|
|
for( USHORT nPos = 0; nPos < nSize; ++nPos )
|
|
|
|
switch( ( pAttr = (*this)[ nPos ])->Which() )
|
|
|
|
{
|
|
|
|
case RES_TXTATR_FTN:
|
|
|
|
bFtn = TRUE;
|
|
|
|
if( bDDEFlds )
|
|
|
|
return;
|
|
|
|
break;
|
|
|
|
case RES_TXTATR_FIELD:
|
|
|
|
{
|
|
|
|
const SwField* pFld = pAttr->GetFld().GetFld();
|
|
|
|
if( RES_DDEFLD == pFld->GetTyp()->Which() )
|
|
|
|
{
|
|
|
|
bDDEFlds = TRUE;
|
|
|
|
if( bFtn )
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
* SwpHints::CalcVisibleFlag()
|
|
|
|
*************************************************************************/
|
|
|
|
|
|
|
|
BOOL SwpHints::CalcVisibleFlag()
|
|
|
|
{
|
|
|
|
BOOL bOldVis = bVis;
|
|
|
|
bCalcVis = FALSE;
|
|
|
|
BOOL bNewVis = TRUE;
|
|
|
|
const USHORT nSize = Count();
|
|
|
|
const SwTxtAttr *pTxtHt;
|
|
|
|
|
|
|
|
for( USHORT nPos = 0; nPos < nSize; ++nPos )
|
|
|
|
{
|
|
|
|
pTxtHt = (*this)[ nPos ];
|
|
|
|
const USHORT nWhich = pTxtHt->Which();
|
|
|
|
|
|
|
|
if( RES_TXTATR_FIELD == nWhich )
|
|
|
|
{
|
|
|
|
const SwFmtFld& rFld = pTxtHt->GetFld();
|
|
|
|
if( RES_HIDDENPARAFLD == rFld.GetFld()->GetTyp()->Which())
|
|
|
|
{
|
|
|
|
if( !((SwHiddenParaField*)rFld.GetFld())->IsHidden() )
|
|
|
|
{
|
|
|
|
SetVisible(TRUE);
|
|
|
|
return !bOldVis;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
bNewVis = FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
SetVisible( bNewVis );
|
|
|
|
return bOldVis != bNewVis;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
* SwpHints::Resort()
|
|
|
|
*************************************************************************/
|
|
|
|
|
|
|
|
// Ein Hint hat seinen Anfangswert geaendert.
|
|
|
|
// Hat sich dadurch die Sortierreihenfolge
|
|
|
|
// geaendert, so wird solange umsortiert, bis
|
|
|
|
// sie wieder stimmt.
|
|
|
|
|
|
|
|
BOOL SwpHints::Resort( const USHORT nPos )
|
|
|
|
{
|
|
|
|
const SwTxtAttr *pTmp;
|
|
|
|
|
|
|
|
if ( ( nPos+1 < Count() &&
|
|
|
|
*(*this)[nPos]->GetStart() > *(*this)[nPos+1]->GetStart() ) ||
|
|
|
|
( nPos > 0 &&
|
|
|
|
*(*this)[nPos]->GetStart() < *(*this)[nPos-1]->GetStart() ) )
|
|
|
|
{
|
|
|
|
pTmp = (*this)[nPos];
|
|
|
|
DeleteAtPos( nPos );
|
|
|
|
SwpHintsArr::Insert( pTmp );
|
|
|
|
// Wenn tatsaechlich umsortiert wurde, muss die
|
|
|
|
// Position i nochmal bearbeitet werden.
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
* SwpHints::NoteInHistory()
|
|
|
|
*************************************************************************/
|
|
|
|
|
|
|
|
void SwpHints::NoteInHistory( SwTxtAttr *pAttr, const BOOL bNew )
|
|
|
|
{
|
|
|
|
if ( pHistory )
|
|
|
|
pHistory->Add( pAttr, bNew );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
* SwpHints::ClearDummies()
|
|
|
|
*************************************************************************/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* ClearDummies: Hints, die genau den gleichen Bereich umfassen wie
|
|
|
|
* ein nachfolgender mit gleichem Attribut oder eine nachfolgende Zeichen-
|
|
|
|
* vorlage, muessen entfernt werden.
|
|
|
|
* Solche Hints entstehen, wenn sie urspruenglich einen groesseren, den
|
|
|
|
* Nachfolger umfassenden Bereich hatten, die Aussenanteile aber durch
|
|
|
|
* SwTxtNode::RstAttr oder SwTxtNode::Update geloescht wurden.
|
|
|
|
*/
|
|
|
|
|
|
|
|
void SwpHints::ClearDummies( SwTxtNode &rNode )
|
|
|
|
{
|
|
|
|
USHORT i = 0;
|
|
|
|
while ( i < Count() )
|
|
|
|
{
|
|
|
|
SwTxtAttr *pHt = GetHt( i++ );
|
|
|
|
const USHORT nWhich = pHt->Which();
|
|
|
|
const xub_StrLen *pEnd = pHt->GetEnd();
|
2000-11-06 09:43:55 +00:00
|
|
|
if ( pEnd && !pHt->IsOverlapAllowedAttr() && !pHt->IsCharFmtAttr() )
|
2000-09-18 23:08:29 +00:00
|
|
|
for( USHORT j = i; j < Count(); ++j )
|
|
|
|
{
|
|
|
|
SwTxtAttr *pOther = GetHt(j);
|
|
|
|
if ( *pOther->GetStart() > *pHt->GetStart() )
|
|
|
|
break;
|
|
|
|
|
2000-11-06 09:43:55 +00:00
|
|
|
if( pOther->Which() == nWhich || pOther->IsCharFmtAttr() )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
|
|
|
//JP 03.10.95: nicht zusammenfassen, zu kompliziert
|
|
|
|
// fuer WIN95-Compiler!!
|
|
|
|
if( *pEnd == *pOther->GetEnd() &&
|
|
|
|
( pOther->Which() == nWhich ||
|
|
|
|
lcl_Included( nWhich, pOther ) ) )
|
|
|
|
{
|
|
|
|
// Vorsicht: Geloeschte Dummies wuerden bei einer
|
|
|
|
// Undo-Aktion die Macht an sich reissen ...
|
|
|
|
// if( pHistory ) pHistory->Add( pHt );
|
|
|
|
rNode.DestroyAttr( Cut( --i ) );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
* SwpHints::Merge( )
|
|
|
|
*************************************************************************/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Merge: Gleichartigen, gleichwertige Hints, die aneinandergrenzen,
|
|
|
|
* koennen verschmolzen werden, wenn an ihrer gemeinsamen Kante nicht ein
|
|
|
|
* gleichartiges Attribut endet oder beginnt, welches einen von der beiden
|
|
|
|
* Kandidaten umfasst, auch Zeichenvorlage duerfen nicht ueberlappt werden.
|
|
|
|
*/
|
2001-09-05 08:40:27 +00:00
|
|
|
/*-----------------5.9.2001 09:26-------------------
|
|
|
|
* And here a smarter version of good old Merge(..)
|
|
|
|
* If a SwTxtAttr is given, only the merging between this attribute and the
|
|
|
|
* neighbours are checked. This saves time, if no attribute is given (in more
|
|
|
|
* complex situations), the whole attribute array is checked as before.
|
|
|
|
* --------------------------------------------------*/
|
|
|
|
|
|
|
|
BOOL SwpHints::Merge( SwTxtNode &rNode, SwTxtAttr* pAttr )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2001-09-05 08:40:27 +00:00
|
|
|
USHORT i;
|
2000-09-18 23:08:29 +00:00
|
|
|
BOOL bMerged = FALSE;
|
2001-09-05 08:40:27 +00:00
|
|
|
if( pAttr && USHRT_MAX != ( i = GetPos( pAttr ) ) )
|
|
|
|
{
|
|
|
|
const xub_StrLen *pEnd = pAttr->GetEnd();
|
|
|
|
if ( pEnd && !pAttr->IsDontMergeAttr() )
|
|
|
|
{
|
|
|
|
USHORT j = i;
|
|
|
|
const USHORT nWhich = pAttr->Which();
|
|
|
|
const USHORT nStart = *pAttr->GetStart();
|
|
|
|
const USHORT nEnd = *pEnd;
|
|
|
|
SwTxtAttr *pPrev;
|
|
|
|
SwTxtAttr *pNext;
|
2001-09-06 12:20:55 +00:00
|
|
|
USHORT nEndIdx = aHtEnd.C40_GETPOS( SwTxtAttr, pAttr );
|
2001-09-05 08:40:27 +00:00
|
|
|
ASSERT( USHRT_MAX != nEndIdx, "Missing end index" );
|
|
|
|
if( nEndIdx )
|
|
|
|
{
|
|
|
|
// If there's a attribute with same start and which-id,
|
|
|
|
// it's not possible to merge with a previous attribute.
|
|
|
|
pPrev = pAttr;
|
|
|
|
while( j )
|
|
|
|
{
|
|
|
|
SwTxtAttr *pOther = GetHt(--j);
|
|
|
|
if ( *pOther->GetStart() < nStart )
|
|
|
|
break;
|
|
|
|
if( pOther->Which() == nWhich || pOther->IsCharFmtAttr()
|
|
|
|
|| pAttr->IsCharFmtAttr() )
|
|
|
|
{
|
|
|
|
pPrev = NULL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
pPrev = NULL;
|
|
|
|
if( i + 1 < Count() )
|
|
|
|
{
|
|
|
|
// If there's a attribute with same end and which-id,
|
|
|
|
// it's not possible to merge with a following attribute.
|
|
|
|
j = nEndIdx + 1;
|
|
|
|
pNext = pAttr;
|
|
|
|
while( j < Count() )
|
|
|
|
{
|
|
|
|
SwTxtAttr *pOther = GetEnd( j++ );
|
|
|
|
if( !pOther->GetEnd() )
|
|
|
|
continue;
|
|
|
|
if( *pOther->GetEnd() > nEnd )
|
|
|
|
break;
|
|
|
|
if( pOther->Which() == nWhich || pOther->IsCharFmtAttr()
|
|
|
|
|| pAttr->IsCharFmtAttr() )
|
|
|
|
{
|
|
|
|
pNext = NULL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
pNext = NULL;
|
|
|
|
if( pPrev )
|
|
|
|
{
|
|
|
|
pPrev = NULL;
|
|
|
|
j = nEndIdx;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
// Looking for a previous attribute with the same which-id
|
|
|
|
// which ends exact at the start of the given attribute
|
|
|
|
SwTxtAttr *pOther = GetEnd( --j );
|
|
|
|
pEnd = pOther->GetEnd();
|
|
|
|
if( !pEnd || *pEnd > nStart )
|
|
|
|
continue;
|
|
|
|
if( *pEnd < nStart )
|
|
|
|
break;
|
|
|
|
if( pOther->Which() == nWhich )
|
|
|
|
{
|
|
|
|
if( pOther->GetAttr() == pAttr->GetAttr() )
|
|
|
|
{
|
|
|
|
bMerged = TRUE;
|
|
|
|
pPrev = pOther;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
pPrev = NULL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if( pOther->IsCharFmtAttr() || pAttr->IsCharFmtAttr() )
|
|
|
|
{
|
|
|
|
pPrev = NULL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} while ( j );
|
|
|
|
}
|
|
|
|
if( pNext )
|
|
|
|
{
|
|
|
|
j = i + 1;
|
|
|
|
pNext = NULL;
|
|
|
|
while( j < Count() )
|
|
|
|
{
|
|
|
|
// Looking for a following attribute with the same which-id
|
|
|
|
// which starts at the end of the given attribute
|
|
|
|
SwTxtAttr *pOther = GetStart( j++ );
|
|
|
|
pEnd = pOther->GetEnd();
|
|
|
|
if( !pEnd || *pOther->GetStart() < nEnd )
|
|
|
|
continue;
|
|
|
|
if( *pOther->GetStart() > nEnd )
|
|
|
|
break;
|
|
|
|
if( pOther->Which() == nWhich )
|
|
|
|
{
|
|
|
|
if( pOther->GetAttr() == pAttr->GetAttr() )
|
|
|
|
{
|
|
|
|
bMerged = TRUE;
|
|
|
|
pNext = pOther;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
pNext = NULL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if( pOther->IsCharFmtAttr() || pAttr->IsCharFmtAttr() )
|
|
|
|
{
|
|
|
|
pNext = NULL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if( bMerged )
|
|
|
|
{
|
|
|
|
if( pNext )
|
|
|
|
{
|
|
|
|
if( pHistory )
|
|
|
|
{
|
|
|
|
pHistory->Add( pAttr );
|
|
|
|
pHistory->Add( pNext );
|
|
|
|
}
|
|
|
|
*pAttr->GetEnd() = *pNext->GetEnd();
|
|
|
|
pAttr->SetDontExpand( FALSE );
|
|
|
|
if( pHistory ) pHistory->Add( pAttr, TRUE );
|
|
|
|
rNode.DestroyAttr( Cut( j - 1 ) );
|
|
|
|
}
|
|
|
|
if( pPrev )
|
|
|
|
{
|
|
|
|
if( pHistory )
|
|
|
|
{
|
|
|
|
pHistory->Add( pPrev );
|
|
|
|
pHistory->Add( pAttr );
|
|
|
|
}
|
|
|
|
*pPrev->GetEnd() = *pAttr->GetEnd();
|
|
|
|
pPrev->SetDontExpand( FALSE );
|
|
|
|
if( pHistory ) pHistory->Add( pPrev, TRUE );
|
|
|
|
rNode.DestroyAttr( Cut( i ) );
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
i = 0;
|
2000-09-18 23:08:29 +00:00
|
|
|
while ( i < Count() )
|
|
|
|
{
|
|
|
|
SwTxtAttr *pHt = GetHt( i++ );
|
|
|
|
const xub_StrLen *pEnd = pHt->GetEnd();
|
2000-11-06 09:43:55 +00:00
|
|
|
if ( pEnd && !pHt->IsDontMergeAttr() )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2000-11-06 09:43:55 +00:00
|
|
|
const USHORT nWhich = pHt->Which();
|
2000-09-18 23:08:29 +00:00
|
|
|
for ( USHORT j = i; j < Count(); j++ )
|
|
|
|
{
|
|
|
|
SwTxtAttr *pOther = GetHt(j);
|
|
|
|
if ( *pOther->GetStart() > *pEnd )
|
|
|
|
break; // keine beruehrenden Attribute mehr vorhanden
|
2000-11-06 09:43:55 +00:00
|
|
|
|
|
|
|
if( *pOther->GetStart() == *pEnd &&
|
|
|
|
( pOther->Which() == nWhich ||
|
|
|
|
pOther->IsCharFmtAttr() ||
|
|
|
|
( pHt->IsCharFmtAttr() && !pHt->IsDontMergeAttr() )))
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
|
|
|
// Beruehrendes Attribut gefunden mit gleichem Typ bzw.
|
|
|
|
// Zeichenvorlage.
|
|
|
|
// Bei Attribut mit anderem Wert bzw. Zeichenvorlage
|
|
|
|
// ist keine Verschmelzung mehr moeglich
|
2000-11-06 09:43:55 +00:00
|
|
|
if( pOther->Which() == nWhich &&
|
2000-09-18 23:08:29 +00:00
|
|
|
pOther->GetAttr() == pHt->GetAttr() )
|
|
|
|
{
|
|
|
|
// Unser Partner pOther erfuellt alle Voraussetzungen,
|
|
|
|
// jetzt muessen wir uns selbst noch ueberpruefen, ob wir
|
|
|
|
// nicht von einem gleichartigen Attribut oder einer
|
|
|
|
// Zeichenvorlage umfasst werden, die das gleiche Ende
|
|
|
|
// wie wir selbst haben.
|
|
|
|
BOOL bMerge = TRUE;
|
|
|
|
for ( USHORT k = 0; k+1 < i; k++ )
|
|
|
|
{
|
|
|
|
SwTxtAttr *pAnOther = GetHt(k);
|
2000-11-06 09:43:55 +00:00
|
|
|
if( ( pAnOther->Which() == nWhich ||
|
|
|
|
pAnOther->IsCharFmtAttr() ||
|
|
|
|
pHt->IsCharFmtAttr() )
|
2000-09-18 23:08:29 +00:00
|
|
|
&& pAnOther->GetEnd()
|
|
|
|
&& *pAnOther->GetEnd() == *pEnd )
|
|
|
|
{
|
|
|
|
bMerge = FALSE; // kein Verschmelzen von i+j
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( bMerge )
|
|
|
|
{
|
|
|
|
// Auch Verschmelzen muss der History mitgeteilt
|
|
|
|
// werden, da sonst ein Delete sein Attribut nicht
|
|
|
|
// mehr findet, wenn es verschmolzen wurde!
|
|
|
|
if( pHistory )
|
|
|
|
{
|
|
|
|
pHistory->Add( pHt );
|
|
|
|
pHistory->Add( pOther );
|
|
|
|
}
|
|
|
|
*pHt->GetEnd() = *pOther->GetEnd();
|
|
|
|
pHt->SetDontExpand( FALSE );
|
|
|
|
if( pHistory ) pHistory->Add( pHt, TRUE );
|
|
|
|
rNode.DestroyAttr( Cut( j ) );
|
|
|
|
--i;
|
|
|
|
bMerged = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( bMerged )
|
|
|
|
ClearDummies( rNode );
|
|
|
|
return bMerged;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
* SwpHints::Forget( ... )
|
|
|
|
*************************************************************************/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Forget: Hints, die genau den gleichen Bereich umfassen wie
|
|
|
|
* ein nachfolgender mit gleichem Attribut oder eine nachfolgende Zeichen-
|
|
|
|
* vorlage, duerfen nicht eingefuegt werden.
|
|
|
|
* Solche Hints koennen entstehen, wenn durch SwTxtNode::RstAttr
|
|
|
|
* ein Attribut in zwei Teile zerlegt wird und der zweite Teil einen
|
|
|
|
* identischen Bereich mit einem inneren Attribut bekaeme.
|
|
|
|
*/
|
|
|
|
|
|
|
|
BOOL SwpHints::Forget( const USHORT i, const USHORT nWhich,
|
|
|
|
const xub_StrLen nStrt, const xub_StrLen nEnd )
|
|
|
|
{
|
|
|
|
BOOL bRet = FALSE;
|
|
|
|
for ( USHORT j = i+1; j < Count(); j++ )
|
|
|
|
{
|
|
|
|
SwTxtAttr *pHt = GetHt( j );
|
|
|
|
if ( *pHt->GetStart() > nStrt )
|
|
|
|
break;
|
|
|
|
const USHORT nWhch = pHt->Which();
|
|
|
|
const xub_StrLen *pEnd = pHt->GetEnd();
|
|
|
|
if ( pEnd && *pEnd == nEnd &&
|
|
|
|
( nWhch == nWhich ||
|
2000-11-06 09:43:55 +00:00
|
|
|
( pHt->IsCharFmtAttr() && lcl_Included( nWhich, pHt ) ) ) )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
|
|
|
bRet = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return bRet;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
* SwpHints::Insert()
|
|
|
|
*************************************************************************/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Insert: Der neue Hint wird immer eingefuegt. Wenn dabei ein
|
|
|
|
* ueberlappender oder gleicher Hintbereich mit gleichem Attribut
|
|
|
|
* und Wert gefunden, wird der neue Hint entsprechend veraendert
|
|
|
|
* und der alte herausgenommen (und zerstoert:
|
|
|
|
* SwpHints::Destroy()).
|
|
|
|
*/
|
|
|
|
|
|
|
|
void SwpHints::Insert( SwTxtAttr *pHint, SwTxtNode &rNode, USHORT nMode )
|
|
|
|
{
|
|
|
|
// Irgendwann ist immer Schluss
|
|
|
|
if( USHRT_MAX == Count() )
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Felder bilden eine Ausnahme:
|
|
|
|
// 1) Sie koennen nie ueberlappen
|
|
|
|
// 2) Wenn zwei Felder genau aneinander liegen,
|
|
|
|
// sollen sie nicht zu einem verschmolzen werden.
|
|
|
|
// Wir koennen also auf die while-Schleife verzichten
|
|
|
|
|
|
|
|
xub_StrLen *pHtEnd = pHint->GetEnd();
|
|
|
|
USHORT nWhich = pHint->Which();
|
|
|
|
|
|
|
|
switch( nWhich )
|
|
|
|
{
|
|
|
|
case RES_TXTATR_CHARFMT:
|
|
|
|
((SwTxtCharFmt*)pHint)->ChgTxtNode( &rNode );
|
|
|
|
break;
|
|
|
|
case RES_TXTATR_INETFMT:
|
|
|
|
{
|
|
|
|
((SwTxtINetFmt*)pHint)->ChgTxtNode( &rNode );
|
|
|
|
SwCharFmt* pFmt = rNode.GetDoc()->GetCharFmtFromPool( RES_POOLCHR_INET_NORMAL );
|
|
|
|
pFmt->Add( (SwTxtINetFmt*)pHint );
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case RES_TXTATR_FIELD:
|
|
|
|
{
|
|
|
|
BOOL bDelFirst = 0 != ((SwTxtFld*)pHint)->GetpTxtNode();
|
|
|
|
((SwTxtFld*)pHint)->ChgTxtNode( &rNode );
|
|
|
|
SwDoc* pDoc = rNode.GetDoc();
|
|
|
|
const SwField* pFld = ((SwTxtFld*)pHint)->GetFld().GetFld();
|
|
|
|
|
|
|
|
if( !pDoc->IsNewFldLst() )
|
|
|
|
{
|
|
|
|
// was fuer ein Feld ist es denn ??
|
|
|
|
// bestimmte Felder mussen am Doc das Calculations-Flag updaten
|
|
|
|
switch( pFld->GetTyp()->Which() )
|
|
|
|
{
|
|
|
|
case RES_DBFLD:
|
|
|
|
case RES_SETEXPFLD:
|
|
|
|
case RES_HIDDENPARAFLD:
|
|
|
|
case RES_HIDDENTXTFLD:
|
|
|
|
case RES_DBNUMSETFLD:
|
|
|
|
case RES_DBNEXTSETFLD:
|
|
|
|
{
|
|
|
|
if( bDelFirst )
|
|
|
|
pDoc->InsDelFldInFldLst( FALSE, *(SwTxtFld*)pHint );
|
|
|
|
if( rNode.GetNodes().IsDocNodes() )
|
|
|
|
pDoc->InsDelFldInFldLst( TRUE, *(SwTxtFld*)pHint );
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case RES_DDEFLD:
|
|
|
|
if( rNode.GetNodes().IsDocNodes() )
|
|
|
|
((SwDDEFieldType*)pFld->GetTyp())->IncRefCnt();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// gehts ins normale Nodes-Array?
|
|
|
|
if( rNode.GetNodes().IsDocNodes() )
|
|
|
|
{
|
|
|
|
BOOL bInsFldType = FALSE;
|
|
|
|
switch( pFld->GetTyp()->Which() )
|
|
|
|
{
|
|
|
|
case RES_SETEXPFLD:
|
|
|
|
bInsFldType = ((SwSetExpFieldType*)pFld->GetTyp())->IsDeleted();
|
|
|
|
if( GSE_SEQ & ((SwSetExpFieldType*)pFld->GetTyp())->GetType() )
|
|
|
|
{
|
|
|
|
// bevor die ReferenzNummer gesetzt wird, sollte
|
|
|
|
// das Feld am richtigen FeldTypen haengen!
|
|
|
|
SwSetExpFieldType* pFldType = (SwSetExpFieldType*)
|
|
|
|
pDoc->InsertFldType( *pFld->GetTyp() );
|
|
|
|
if( pFldType != pFld->GetTyp() )
|
|
|
|
{
|
|
|
|
SwFmtFld* pFmtFld = (SwFmtFld*)&((SwTxtFld*)pHint)
|
|
|
|
->GetFld();
|
|
|
|
pFldType->Add( pFmtFld ); // ummelden
|
|
|
|
pFmtFld->GetFld()->ChgTyp( pFldType );
|
|
|
|
}
|
|
|
|
pFldType->SetSeqRefNo( *(SwSetExpField*)pFld );
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case RES_USERFLD:
|
|
|
|
bInsFldType = ((SwUserFieldType*)pFld->GetTyp())->IsDeleted();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RES_DDEFLD:
|
|
|
|
if( pDoc->IsNewFldLst() )
|
|
|
|
((SwDDEFieldType*)pFld->GetTyp())->IncRefCnt();
|
|
|
|
bInsFldType = ((SwDDEFieldType*)pFld->GetTyp())->IsDeleted();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if( bInsFldType )
|
|
|
|
pDoc->InsDeletedFldType( *pFld->GetTyp() );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case RES_TXTATR_FTN :
|
|
|
|
((SwTxtFtn*)pHint)->ChgTxtNode( &rNode );
|
|
|
|
break;
|
|
|
|
case RES_TXTATR_REFMARK:
|
|
|
|
((SwTxtRefMark*)pHint)->ChgTxtNode( &rNode );
|
2001-01-26 17:10:47 +00:00
|
|
|
if( rNode.GetNodes().IsDocNodes() )
|
|
|
|
{
|
|
|
|
//search for a refernce with the same name
|
|
|
|
SwTxtAttr* pHt;
|
|
|
|
xub_StrLen *pHtEnd, *pHintEnd;
|
|
|
|
for( USHORT n = 0, nEnd = Count(); n < nEnd; ++n )
|
|
|
|
if( RES_TXTATR_REFMARK == (pHt = GetHt( n ))->Which() &&
|
|
|
|
pHint->GetAttr() == pHt->GetAttr() &&
|
|
|
|
0 != ( pHtEnd = pHt->GetEnd() ) &&
|
|
|
|
0 != ( pHintEnd = pHint->GetEnd() ) )
|
|
|
|
{
|
|
|
|
SwComparePosition eCmp = ::ComparePosition(
|
|
|
|
*pHt->GetStart(), *pHtEnd,
|
|
|
|
*pHint->GetStart(), *pHintEnd );
|
|
|
|
BOOL bDelOld = TRUE, bChgStart = FALSE, bChgEnd = FALSE;
|
|
|
|
switch( eCmp )
|
|
|
|
{
|
|
|
|
case POS_BEFORE:
|
|
|
|
case POS_BEHIND: bDelOld = FALSE; break;
|
|
|
|
|
|
|
|
case POS_OUTSIDE: bChgStart = bChgEnd = TRUE; break;
|
|
|
|
|
|
|
|
case POS_COLLIDE_END:
|
|
|
|
case POS_OVERLAP_BEFORE: bChgStart = TRUE; break;
|
|
|
|
case POS_COLLIDE_START:
|
|
|
|
case POS_OVERLAP_BEHIND: bChgEnd = TRUE; break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( bChgStart )
|
|
|
|
*pHint->GetStart() = *pHt->GetStart();
|
|
|
|
if( bChgEnd )
|
|
|
|
*pHintEnd = *pHtEnd;
|
|
|
|
|
|
|
|
if( bDelOld )
|
|
|
|
{
|
|
|
|
if( pHistory )
|
|
|
|
pHistory->Add( pHt );
|
|
|
|
rNode.DestroyAttr( Cut( n-- ) );
|
|
|
|
--nEnd;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2000-09-18 23:08:29 +00:00
|
|
|
break;
|
|
|
|
case RES_TXTATR_TOXMARK:
|
|
|
|
((SwTxtTOXMark*)pHint)->ChgTxtNode( &rNode );
|
|
|
|
break;
|
2000-10-23 10:58:55 +00:00
|
|
|
|
|
|
|
case RES_TXTATR_CJK_RUBY:
|
|
|
|
{
|
|
|
|
((SwTxtRuby*)pHint)->ChgTxtNode( &rNode );
|
|
|
|
SwCharFmt* pFmt = rNode.GetDoc()->GetCharFmtFromPool(
|
|
|
|
RES_POOLCHR_RUBYTEXT );
|
|
|
|
pFmt->Add( (SwTxtRuby*)pHint );
|
|
|
|
}
|
|
|
|
break;
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if( SETATTR_DONTEXPAND & nMode )
|
|
|
|
pHint->SetDontExpand( TRUE );
|
|
|
|
|
|
|
|
// SwTxtAttrs ohne Ende werden sonderbehandelt:
|
|
|
|
// Sie werden natuerlich in das Array insertet, aber sie werden nicht
|
|
|
|
// in die pPrev/Next/On/Off-Verkettung aufgenommen.
|
|
|
|
// Der Formatierer erkennt diese TxtHints an dem CH_TXTATR_.. im Text !
|
|
|
|
xub_StrLen nHtStart = *pHint->GetStart();
|
|
|
|
if( !pHtEnd )
|
|
|
|
{
|
|
|
|
SwpHintsArr::Insert( pHint );
|
|
|
|
CalcFlags();
|
2001-09-05 08:40:27 +00:00
|
|
|
#ifndef PRODUCT
|
|
|
|
if( !rNode.GetDoc()->IsInReading() )
|
|
|
|
CHECK;
|
|
|
|
#endif
|
2000-09-18 23:08:29 +00:00
|
|
|
// ... und die Abhaengigen benachrichtigen
|
|
|
|
if ( rNode.GetDepends() )
|
|
|
|
{
|
|
|
|
SwUpdateAttr aHint( nHtStart, nHtStart, nWhich );
|
|
|
|
rNode.Modify( 0, &aHint );
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------
|
|
|
|
// Ab hier gibt es nur noch pHint mit einem EndIdx !!!
|
|
|
|
|
2001-09-05 08:40:27 +00:00
|
|
|
SwTxtAttr *pMerge = pHint; // For a smarter Merge-function
|
|
|
|
|
2001-11-26 10:58:29 +00:00
|
|
|
BOOL bResort = FALSE;
|
|
|
|
|
2000-09-18 23:08:29 +00:00
|
|
|
if( *pHtEnd < nHtStart )
|
|
|
|
{
|
|
|
|
ASSERT( *pHtEnd >= nHtStart,
|
|
|
|
"+SwpHints::Insert: invalid hint, end < start" );
|
|
|
|
|
|
|
|
// Wir drehen den Quatsch einfach um:
|
|
|
|
*pHint->GetStart() = *pHtEnd;
|
|
|
|
*pHtEnd = nHtStart;
|
|
|
|
nHtStart = *pHint->GetStart();
|
|
|
|
}
|
|
|
|
|
|
|
|
// AMA: Damit wir endlich mit ueberlappenden Hints fertig werden ...
|
|
|
|
// das neue Verfahren:
|
|
|
|
|
2000-11-06 09:43:55 +00:00
|
|
|
if( !(SETATTR_NOHINTADJUST & nMode) && !pHint->IsOverlapAllowedAttr() )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
|
|
|
const SfxPoolItem* pParaItem;
|
|
|
|
xub_StrLen nMaxEnd = *pHtEnd;
|
|
|
|
xub_StrLen nHtEnd = *pHtEnd;
|
|
|
|
BOOL bParaAttr = rNode.GetpSwAttrSet() &&
|
2000-11-06 09:43:55 +00:00
|
|
|
( SFX_ITEM_SET == rNode.GetpSwAttrSet()->GetItemState( nWhich,
|
|
|
|
FALSE, &pParaItem ) ) && ( pParaItem == &pHint->GetAttr() );
|
2000-09-18 23:08:29 +00:00
|
|
|
BOOL bReplace = !( SETATTR_DONTREPLACE & nMode );
|
2000-11-06 09:43:55 +00:00
|
|
|
SwpHtStart_SAR *pTmpHints = 0;
|
2000-09-18 23:08:29 +00:00
|
|
|
|
|
|
|
USHORT i;
|
|
|
|
// Wir wollen zwar von nHtStart bis nMaxEnd, muessen aber ggf.
|
|
|
|
// stueckeln (Attribute duerfen keine Zeichenvorlagen ueberlappen).
|
|
|
|
// Das erste Stueck wird also von nHtStart bis zum ersten Start/Ende
|
|
|
|
// einer Zeichenvorlage gehen usw. bis nHtEnd = nMaxEnd erreicht ist.
|
2000-11-06 09:43:55 +00:00
|
|
|
do {
|
2000-09-18 23:08:29 +00:00
|
|
|
BOOL bINet = nWhich == RES_TXTATR_INETFMT;
|
|
|
|
BOOL bForgetAttr = bParaAttr;
|
|
|
|
// Muessen wir uns aufspalten?
|
2000-11-06 17:16:53 +00:00
|
|
|
if ( !bINet && !pHint->IsDontMergeAttr() )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
|
|
|
// Ab der zweiten Runde muessen wir zunaechst einen neuen
|
|
|
|
// Hint erzeugen.
|
|
|
|
if ( nHtEnd != nMaxEnd )
|
|
|
|
{
|
2001-09-05 08:40:27 +00:00
|
|
|
pMerge = NULL; // No way to use the smarter Merge()
|
2000-09-18 23:08:29 +00:00
|
|
|
pHint = rNode.MakeTxtAttr( bParaAttr ? *pParaItem :
|
|
|
|
pHint->GetAttr(),
|
|
|
|
nHtStart, nMaxEnd );
|
|
|
|
nHtEnd = *pHint->GetEnd();
|
|
|
|
}
|
|
|
|
|
|
|
|
for ( i = 0; i < Count(); i++)
|
|
|
|
{
|
|
|
|
SwTxtAttr *pOther = GetHt(i);
|
|
|
|
// Wir suchen nach Zeichenvorlagen, die uns schneiden
|
|
|
|
// oder in uns liegen
|
2000-11-06 09:43:55 +00:00
|
|
|
BOOL bOtherFmt = pOther->IsCharFmtAttr();
|
|
|
|
if( bOtherFmt ||
|
|
|
|
( RES_TXTATR_CHARFMT == nWhich && pOther->GetEnd() ) )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
|
|
|
if( bForgetAttr && bOtherFmt &&
|
|
|
|
*pOther->GetStart() <= nHtStart &&
|
|
|
|
*pOther->GetEnd() >= nHtStart )
|
|
|
|
bForgetAttr = FALSE;
|
|
|
|
/* Die Flags bCheckInclude und bOtherFmt sollen die
|
|
|
|
* Anzahl der Aufrufe von lcl_Include minimieren, da
|
|
|
|
* dieses wg. IsVisitedURL() teuer ist. */
|
|
|
|
BOOL bCheckInclude = FALSE;
|
|
|
|
if( *pOther->GetStart() > nHtStart
|
|
|
|
&& *pOther->GetStart() < nHtEnd
|
|
|
|
&& ( bReplace || *pOther->GetEnd() > nHtEnd ) )
|
|
|
|
{
|
|
|
|
if( !bOtherFmt )
|
|
|
|
{
|
|
|
|
bOtherFmt = !lcl_Included( pOther->Which(),
|
|
|
|
pHint );
|
|
|
|
bCheckInclude = TRUE;
|
|
|
|
}
|
|
|
|
if( bOtherFmt )
|
|
|
|
nHtEnd = *pOther->GetStart();
|
|
|
|
}
|
|
|
|
if( *pOther->GetEnd() > nHtStart
|
|
|
|
&& *pOther->GetEnd() < nHtEnd
|
|
|
|
&& ( bReplace || *pOther->GetStart() < nHtStart ) )
|
|
|
|
{
|
|
|
|
if( bOtherFmt || ( !bCheckInclude &&
|
|
|
|
!lcl_Included( pOther->Which(), pHint ) ) )
|
|
|
|
nHtEnd = *pOther->GetEnd();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*pHint->GetEnd() = nHtEnd;
|
|
|
|
}
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
while(i < Count())
|
|
|
|
{
|
|
|
|
SwTxtAttr *pOther = GetHt(i);
|
|
|
|
const USHORT nOtherWhich = pOther->Which();
|
2000-11-06 09:43:55 +00:00
|
|
|
BOOL bCheckInclude = pHint->IsCharFmtAttr() &&
|
|
|
|
pOther->IsCharFmtAttr() &&
|
|
|
|
nWhich != nOtherWhich;
|
|
|
|
|
|
|
|
BOOL bOtherCharFmt = RES_TXTATR_CHARFMT == nOtherWhich;
|
|
|
|
if( nOtherWhich == nWhich || bCheckInclude )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
|
|
|
if(0 == pOther->GetEnd())
|
|
|
|
{
|
|
|
|
if( *pOther->GetStart() == nHtStart &&
|
|
|
|
nOtherWhich == nWhich &&
|
|
|
|
pOther->GetAttr() == pHint->GetAttr() )
|
|
|
|
{
|
|
|
|
// Gibts schon, alten raus.
|
|
|
|
if( pHistory )
|
|
|
|
pHistory->Add( pOther );
|
|
|
|
rNode.DestroyAttr( Cut(i) );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
++i;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2000-11-06 09:43:55 +00:00
|
|
|
// Attribute mit Anfang und Ende.
|
2000-09-18 23:08:29 +00:00
|
|
|
const Range aHintRg( nHtStart, nHtEnd );
|
|
|
|
const Range aOtherRg( *pOther->GetStart(),
|
|
|
|
*pOther->GetEnd() );
|
|
|
|
|
2000-11-06 09:43:55 +00:00
|
|
|
if( aOtherRg.IsInside( aHintRg.Min() ) ||
|
|
|
|
aHintRg.IsInside( aOtherRg.Min() ) )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
|
|
|
// aBig umspannt beide Ranges
|
2000-11-06 09:43:55 +00:00
|
|
|
const Range aBig(
|
|
|
|
Min( aHintRg.Min(), aOtherRg.Min()),
|
|
|
|
Max( aHintRg.Max(), aOtherRg.Max()));
|
2000-09-18 23:08:29 +00:00
|
|
|
|
|
|
|
// Gleiches Attribut
|
|
|
|
// oder Zeichenvorlage:
|
|
|
|
// Bereiche duerfen nicht ueberlappen.
|
|
|
|
|
|
|
|
// Zuerst wurde geprueft, ob sich der neue mit dem
|
|
|
|
// alten ueberschneidet, danach gibt es nur noch
|
|
|
|
// drei Faelle zu beachten:
|
|
|
|
// 1) der neue umschliesst den alten
|
|
|
|
// 2) der neue ueberlappt den alten hinten
|
|
|
|
// 3) der neue ueberlappt den alten vorne
|
|
|
|
|
|
|
|
BOOL bNoINet = RES_TXTATR_INETFMT != nOtherWhich ||
|
|
|
|
nWhich == nOtherWhich;
|
|
|
|
|
|
|
|
// 1) der neue umschliesst den alten
|
|
|
|
if( aBig == aHintRg )
|
|
|
|
{
|
|
|
|
BOOL bTmpReplace = bReplace ||
|
|
|
|
( aHintRg == aOtherRg &&
|
|
|
|
nWhich == nOtherWhich &&
|
2000-11-06 09:43:55 +00:00
|
|
|
!pHint->IsCharFmtAttr() );
|
2000-09-18 23:08:29 +00:00
|
|
|
if( bNoINet && bTmpReplace &&
|
2000-11-06 09:43:55 +00:00
|
|
|
( !bOtherCharFmt || nWhich == nOtherWhich ) )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
|
|
|
if( !bCheckInclude ||
|
|
|
|
lcl_Included( nOtherWhich, pHint ) )
|
|
|
|
{
|
|
|
|
if( pHistory ) pHistory->Add( pOther );
|
|
|
|
rNode.DestroyAttr( Cut(i) );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
++i;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if( !bReplace && aBig == aOtherRg )
|
|
|
|
bForgetAttr = FALSE;
|
|
|
|
// 2) der neue ueberlappt hinten
|
|
|
|
else if( aBig.Max() == aHintRg.Max() )
|
|
|
|
{
|
|
|
|
if( bNoINet &&
|
2000-11-06 09:43:55 +00:00
|
|
|
( !bOtherCharFmt || RES_TXTATR_CHARFMT != nWhich ) &&
|
2000-09-18 23:08:29 +00:00
|
|
|
( bReplace || aHintRg.Max() != aOtherRg.Max() ) )
|
|
|
|
{
|
|
|
|
if( ( bCheckInclude &&
|
|
|
|
lcl_Included( nOtherWhich, pHint ) ) ||
|
2000-11-06 09:43:55 +00:00
|
|
|
( !bCheckInclude && !bOtherCharFmt ) )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
|
|
|
if( nMaxEnd == nHtStart )
|
|
|
|
bForgetAttr = FALSE;
|
|
|
|
if( pHistory ) pHistory->Add( pOther );
|
|
|
|
*pOther->GetEnd() = nHtStart;
|
2001-11-26 10:58:29 +00:00
|
|
|
bResort = TRUE;
|
2000-09-18 23:08:29 +00:00
|
|
|
if( pHistory ) pHistory->Add( pOther, TRUE );
|
|
|
|
// ChainDelEnd( pOther );
|
|
|
|
// ChainEnds( pOther );
|
|
|
|
}
|
|
|
|
else if( bINet &&
|
|
|
|
aHintRg.Max() != aOtherRg.Max() &&
|
|
|
|
aHintRg.Min() < aOtherRg.Max() )
|
|
|
|
{
|
|
|
|
// Wenn ein INetFmt eingefuegt wird, muss
|
|
|
|
// sich ein anderes Attribut ggf. aufspal-
|
|
|
|
// ten. Es wird beiseite gestellt und in
|
|
|
|
// einem spaeteren Durchgang eingefuegt.
|
|
|
|
// Beim Einfuegen spaltet es sich selbst.
|
|
|
|
if( pHistory ) pHistory->Add( pOther );
|
|
|
|
if( !pTmpHints )
|
|
|
|
pTmpHints = new SwpHtStart_SAR();
|
|
|
|
pTmpHints->C40_INSERT( SwTxtAttr, pOther,
|
|
|
|
pTmpHints->Count() );
|
|
|
|
Cut( i );
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// 3) der neue ueberlappt vorne
|
2000-11-06 09:43:55 +00:00
|
|
|
else if( aBig.Min() == aHintRg.Min() )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
|
|
|
if( bNoINet &&
|
|
|
|
( RES_TXTATR_CHARFMT != nOtherWhich ||
|
|
|
|
RES_TXTATR_CHARFMT != nWhich ) &&
|
|
|
|
( bReplace || aHintRg.Min() != aOtherRg.Min() ) )
|
|
|
|
{
|
|
|
|
if( ( bCheckInclude &&
|
|
|
|
lcl_Included( nOtherWhich, pHint ) ) ||
|
2000-11-06 09:43:55 +00:00
|
|
|
( !bCheckInclude && !bOtherCharFmt ) )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
|
|
|
if( pHistory ) pHistory->Add( pOther );
|
|
|
|
|
|
|
|
*pOther->GetStart() = nHtEnd;
|
|
|
|
|
|
|
|
if( pHistory ) pHistory->Add( pOther, TRUE );
|
|
|
|
// ChainDelStart( pOther );
|
|
|
|
// ChainStarts( pOther );
|
|
|
|
|
|
|
|
// nehme die History weg, damit beim Resort
|
|
|
|
// nicht doppelt eingetragen wird!
|
|
|
|
|
|
|
|
SwRegHistory * pSave = pHistory;
|
|
|
|
pHistory = 0;
|
|
|
|
const BOOL bOk = Resort(i);
|
|
|
|
pHistory = pSave;
|
|
|
|
if( bOk )
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else if( bINet &&
|
|
|
|
aHintRg.Min() != aOtherRg.Min() &&
|
|
|
|
aHintRg.Max() > aOtherRg.Min() )
|
|
|
|
{
|
|
|
|
// Wenn ein INetFmt eingefuegt wird, muss
|
|
|
|
// sich ein anderes Attribut ggf. aufspal-
|
|
|
|
// ten. Es wird beiseite gestellt und in
|
|
|
|
// einem spaeteren Durchgang eingefuegt.
|
|
|
|
// Beim Einfuegen spaltet es sich selbst.
|
|
|
|
if( pHistory ) pHistory->Add( pOther );
|
|
|
|
if( !pTmpHints )
|
|
|
|
pTmpHints = new SwpHtStart_SAR();
|
|
|
|
pTmpHints->C40_INSERT( SwTxtAttr, pOther,
|
|
|
|
pTmpHints->Count() );
|
|
|
|
Cut( i );
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
bForgetAttr = FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
|
|
|
|
ClearDummies( rNode );
|
|
|
|
// Nur wenn wir nicht sowieso schon durch die Absatzattribute
|
|
|
|
// gueltig sind, werden wir eingefuegt ...
|
|
|
|
if( bForgetAttr )
|
2001-09-05 08:40:27 +00:00
|
|
|
{
|
2000-09-18 23:08:29 +00:00
|
|
|
rNode.DestroyAttr( pHint );
|
2001-09-05 08:40:27 +00:00
|
|
|
pMerge = NULL; // No smart Merge()
|
|
|
|
}
|
2000-09-18 23:08:29 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
SwpHintsArr::Insert( pHint );
|
|
|
|
if ( pHistory )
|
|
|
|
pHistory->Add( pHint, TRUE );
|
2001-11-26 10:58:29 +00:00
|
|
|
bResort = FALSE;
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
// InsertChain( pHint );
|
|
|
|
|
|
|
|
// ... und die Abhaengigen benachrichtigen
|
|
|
|
if ( rNode.GetDepends() )
|
|
|
|
{
|
|
|
|
SwUpdateAttr aHint( nHtStart, nHtEnd, nWhich );
|
|
|
|
rNode.Modify( 0, &aHint );
|
|
|
|
}
|
|
|
|
// Falls es noch 'ne Runde gibt:
|
|
|
|
nHtStart = nHtEnd;
|
|
|
|
if( nMaxEnd > nHtEnd )
|
|
|
|
continue;
|
|
|
|
if( !pTmpHints )
|
|
|
|
break;
|
2001-09-05 08:40:27 +00:00
|
|
|
pMerge = NULL; // No smart Merge()
|
2000-09-18 23:08:29 +00:00
|
|
|
pHint = pTmpHints->GetObject(0);
|
|
|
|
nWhich = pHint->Which();
|
|
|
|
nHtStart = *pHint->GetStart();
|
|
|
|
nHtEnd = *pHint->GetEnd();
|
|
|
|
nMaxEnd = nHtEnd;
|
|
|
|
bParaAttr = FALSE;
|
|
|
|
pTmpHints->Remove(0);
|
|
|
|
if( !pTmpHints->Count() )
|
|
|
|
{
|
|
|
|
delete pTmpHints;
|
|
|
|
pTmpHints = NULL;
|
|
|
|
}
|
|
|
|
} while ( TRUE );
|
|
|
|
|
2001-11-26 10:58:29 +00:00
|
|
|
if( bResort )
|
|
|
|
SwpHintsArr::Resort();
|
|
|
|
|
2000-09-18 23:08:29 +00:00
|
|
|
// Jetzt wollen wir mal gucken, ob wir das SwpHintsArray nicht
|
|
|
|
// etwas vereinfachen koennen ...
|
2001-09-05 08:40:27 +00:00
|
|
|
Merge( rNode, pMerge );
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SwpHintsArr::Insert( pHint );
|
|
|
|
if ( pHistory )
|
|
|
|
pHistory->Add( pHint, TRUE );
|
|
|
|
// InsertChain( pHint );
|
|
|
|
|
|
|
|
// ... und die Abhaengigen benachrichtigen
|
|
|
|
if ( rNode.GetDepends() )
|
|
|
|
{
|
|
|
|
SwUpdateAttr aHint( nHtStart,
|
|
|
|
nHtStart == *pHtEnd ? *pHtEnd + 1 : *pHtEnd, nWhich );
|
|
|
|
rNode.Modify( 0, &aHint );
|
|
|
|
}
|
|
|
|
}
|
2001-09-05 08:40:27 +00:00
|
|
|
#ifndef PRODUCT
|
|
|
|
if( !rNode.GetDoc()->IsInReading() )
|
|
|
|
CHECK;
|
|
|
|
#endif
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
* SwpHints::DeleteAtPos()
|
|
|
|
*************************************************************************/
|
|
|
|
|
|
|
|
void SwpHints::DeleteAtPos( const USHORT nPos )
|
|
|
|
{
|
|
|
|
SwTxtAttr *pHint = GetHt(nPos);
|
|
|
|
// ChainDelete( pHint );
|
|
|
|
if( pHistory ) pHistory->Add( pHint );
|
|
|
|
SwpHintsArr::DeleteAtPos( nPos );
|
|
|
|
|
|
|
|
if( RES_TXTATR_FIELD == pHint->Which() )
|
|
|
|
{
|
|
|
|
SwFieldType* pFldTyp = ((SwTxtFld*)pHint)->GetFld().GetFld()->GetTyp();
|
|
|
|
if( RES_DDEFLD == pFldTyp->Which() )
|
|
|
|
{
|
|
|
|
const SwTxtNode* pNd = ((SwTxtFld*)pHint)->GetpTxtNode();
|
|
|
|
if( pNd && pNd->GetNodes().IsDocNodes() )
|
|
|
|
((SwDDEFieldType*)pFldTyp)->DecRefCnt();
|
|
|
|
((SwTxtFld*)pHint)->ChgTxtNode( 0 );
|
|
|
|
}
|
|
|
|
else if( !bVis && RES_HIDDENPARAFLD == pFldTyp->Which() )
|
|
|
|
bCalcVis = TRUE;
|
|
|
|
}
|
|
|
|
CalcFlags();
|
|
|
|
CHECK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ist der Hint schon bekannt, dann suche die Position und loesche ihn.
|
|
|
|
// Ist er nicht im Array, so gibt es ein ASSERT !!
|
|
|
|
|
|
|
|
void SwpHints::Delete( SwTxtAttr* pTxtHt )
|
|
|
|
{
|
|
|
|
// Attr 2.0: SwpHintsArr::Delete( pTxtHt );
|
|
|
|
const USHORT nPos = GetStartOf( pTxtHt );
|
|
|
|
ASSERT( USHRT_MAX != nPos, "Attribut nicht im Attribut-Array!" );
|
|
|
|
if( USHRT_MAX != nPos )
|
|
|
|
DeleteAtPos( nPos );
|
|
|
|
}
|
|
|
|
|
|
|
|
void SwTxtNode::ClearSwpHintsArr( int bDelAll, int bDelFields )
|
|
|
|
{
|
|
|
|
if( pSwpHints )
|
|
|
|
{
|
|
|
|
USHORT nPos = 0;
|
|
|
|
while( nPos < pSwpHints->Count() )
|
|
|
|
{
|
|
|
|
SwTxtAttr* pDel = pSwpHints->GetHt( nPos );
|
|
|
|
BOOL bDel = bDelAll;
|
|
|
|
if( !bDelAll )
|
|
|
|
switch( pDel->Which() )
|
|
|
|
{
|
|
|
|
case RES_TXTATR_FLYCNT:
|
|
|
|
case RES_TXTATR_FTN:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RES_TXTATR_FIELD:
|
|
|
|
case RES_TXTATR_HARDBLANK:
|
|
|
|
if( bDelFields )
|
|
|
|
bDel = TRUE;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
bDel = TRUE; break;
|
|
|
|
}
|
|
|
|
if( bDel )
|
|
|
|
{
|
|
|
|
pSwpHints->SwpHintsArr::DeleteAtPos( nPos );
|
|
|
|
DestroyAttr( pDel );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
++nPos;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
FASTBOOL SwTxtNode::IsInSymbolFont( xub_StrLen nPos ) const
|
|
|
|
{
|
|
|
|
SfxItemSet aSet( (SfxItemPool&)GetDoc()->GetAttrPool(),
|
|
|
|
RES_CHRATR_FONT, RES_CHRATR_FONT );
|
|
|
|
if( GetAttr( aSet, nPos, nPos ))
|
|
|
|
return RTL_TEXTENCODING_SYMBOL == ((SvxFontItem&)aSet.Get( RES_CHRATR_FONT ))
|
|
|
|
.GetCharSet();
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
//JP 07.10.95: waere so auch nicht schlecht!
|
|
|
|
// SwTxtFrmInfo aFInfo( GetFrm() );
|
|
|
|
// return aFInfo.IsBullet( nPos );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
USHORT SwTxtNode::GetLang( const xub_StrLen nBegin, const xub_StrLen nLen) const
|
|
|
|
{
|
2000-11-06 17:55:06 +00:00
|
|
|
USHORT nWhichId = RES_CHRATR_LANGUAGE;
|
|
|
|
USHORT nRet = LANGUAGE_DONTKNOW;
|
|
|
|
if( pSwpHints )
|
|
|
|
{
|
2001-09-24 14:09:52 +00:00
|
|
|
nWhichId = GetWhichOfScript( nWhichId,
|
|
|
|
pBreakIt->GetRealScriptOfText( aText, nBegin ));
|
2000-11-06 17:55:06 +00:00
|
|
|
|
|
|
|
xub_StrLen nEnd = nBegin + nLen;
|
|
|
|
for( USHORT i = 0, nSize = pSwpHints->Count(); i < nSize; ++i )
|
|
|
|
{
|
|
|
|
// ist der Attribut-Anfang schon groesser als der Idx ?
|
|
|
|
const SwTxtAttr *pHt = pSwpHints->operator[](i);
|
|
|
|
xub_StrLen nAttrStart = *pHt->GetStart();
|
|
|
|
if( nEnd < nAttrStart )
|
|
|
|
break;
|
|
|
|
|
|
|
|
const USHORT nWhich = pHt->Which();
|
|
|
|
|
|
|
|
if( ( pHt->IsCharFmtAttr() && lcl_Included( nWhichId, pHt ) )
|
|
|
|
|| nWhichId == nWhich )
|
|
|
|
{
|
|
|
|
const xub_StrLen *pEndIdx = pHt->GetEnd();
|
|
|
|
// Ueberlappt das Attribut den Bereich?
|
|
|
|
|
|
|
|
if( pEndIdx &&
|
|
|
|
nLen ? ( nAttrStart < nEnd && nBegin < *pEndIdx )
|
|
|
|
: (( nAttrStart < nBegin &&
|
|
|
|
( pHt->DontExpand() ? nBegin < *pEndIdx
|
|
|
|
: nBegin <= *pEndIdx )) ||
|
|
|
|
( nBegin == nAttrStart &&
|
|
|
|
( nAttrStart == *pEndIdx || !nBegin ))) )
|
|
|
|
{
|
|
|
|
const SfxPoolItem* pItem;
|
|
|
|
if( RES_TXTATR_CHARFMT == nWhich )
|
|
|
|
pItem = &pHt->GetCharFmt().GetCharFmt()->GetAttr( nWhichId );
|
|
|
|
else if( RES_TXTATR_INETFMT == nWhich )
|
|
|
|
pItem = &((SwTxtINetFmt*)pHt)->GetCharFmt()->GetAttr( nWhichId );
|
|
|
|
else
|
|
|
|
pItem = &pHt->GetAttr();
|
|
|
|
|
|
|
|
USHORT nLng = ((SvxLanguageItem*)pItem)->GetLanguage();
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2000-11-06 17:55:06 +00:00
|
|
|
// Umfasst das Attribut den Bereich komplett?
|
|
|
|
if( nAttrStart <= nBegin && nEnd <= *pEndIdx )
|
|
|
|
nRet = nLng;
|
|
|
|
else if( LANGUAGE_DONTKNOW == nRet )
|
|
|
|
nRet = nLng; // partielle Ueberlappung, der 1. gewinnt
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2000-09-18 23:08:29 +00:00
|
|
|
if( LANGUAGE_DONTKNOW == nRet )
|
2000-11-06 17:55:06 +00:00
|
|
|
{
|
2001-07-04 16:43:57 +00:00
|
|
|
if( !pSwpHints )
|
2001-09-24 14:09:52 +00:00
|
|
|
nWhichId = GetWhichOfScript( RES_CHRATR_LANGUAGE,
|
2001-11-08 07:35:13 +00:00
|
|
|
pBreakIt->GetRealScriptOfText( aText, nBegin ));
|
2000-11-06 17:55:06 +00:00
|
|
|
|
|
|
|
nRet = ((SvxLanguageItem&)GetSwAttrSet().Get( nWhichId )).GetLanguage();
|
2001-07-04 16:43:57 +00:00
|
|
|
if( LANGUAGE_DONTKNOW == nRet )
|
|
|
|
nRet = GetAppLanguage();
|
2000-11-06 17:55:06 +00:00
|
|
|
}
|
2000-09-18 23:08:29 +00:00
|
|
|
return nRet;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
sal_Unicode GetCharOfTxtAttr( const SwTxtAttr& rAttr )
|
|
|
|
{
|
|
|
|
sal_Unicode cRet = CH_TXTATR_BREAKWORD;
|
|
|
|
switch ( rAttr.Which() )
|
|
|
|
{
|
|
|
|
case RES_TXTATR_REFMARK:
|
|
|
|
case RES_TXTATR_TOXMARK:
|
|
|
|
|
|
|
|
// case RES_TXTATR_FIELD: ??????
|
|
|
|
// case RES_TXTATR_FLYCNT, // 29
|
|
|
|
|
|
|
|
case RES_TXTATR_FTN:
|
|
|
|
cRet = CH_TXTATR_INWORD;
|
|
|
|
break;
|
|
|
|
|
|
|
|
// depends on the character ??
|
|
|
|
// case RES_TXTATR_HARDBLANK:
|
|
|
|
// cRet = CH_TXTATR_INWORD;
|
|
|
|
// break;
|
|
|
|
}
|
|
|
|
return cRet;
|
|
|
|
}
|
|
|
|
|
|
|
|
|