1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: editdoc.cxx,v $
10 * $Revision: 1.48.148.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
34 #include <eeng_pch.hxx>
36 #include <svx/tstpitem.hxx>
37 #include <svx/colritem.hxx>
38 #include <fontitem.hxx>
39 #include <svx/crsditem.hxx>
40 #include <svx/fhgtitem.hxx>
41 #include <svx/postitem.hxx>
42 #include <svx/kernitem.hxx>
43 #include <svx/wrlmitem.hxx>
44 #include <svx/wghtitem.hxx>
45 #include <svx/udlnitem.hxx>
46 #include <svx/cntritem.hxx>
47 #include <svx/escpitem.hxx>
48 #include <svx/shdditem.hxx>
49 #include <svx/akrnitem.hxx>
50 #include <svx/cscoitem.hxx>
51 #include <svx/langitem.hxx>
52 #include <svx/emphitem.hxx>
53 #include <svx/charscaleitem.hxx>
54 #include <svx/charreliefitem.hxx>
55 #include <xmlcnitm.hxx>
57 #include <editdoc.hxx>
58 #include <editdbg.hxx>
60 #include <eerdll2.hxx>
61 #include <tools/stream.hxx>
63 #include <tools/debug.hxx>
64 #include <tools/shl.hxx>
65 #include <vcl/svapp.hxx>
67 #ifndef _COM_SUN_STAR_TEXT_SCRIPTTYPE_HPP_
68 #include <com/sun/star/i18n/ScriptType.hpp>
71 #include <stdlib.h> // qsort
73 using namespace ::com::sun::star
;
76 // ------------------------------------------------------------
78 USHORT
GetScriptItemId( USHORT nItemId
, short nScriptType
)
82 if ( ( nScriptType
== i18n::ScriptType::ASIAN
) ||
83 ( nScriptType
== i18n::ScriptType::COMPLEX
) )
87 case EE_CHAR_LANGUAGE
:
88 nId
= ( nScriptType
== i18n::ScriptType::ASIAN
) ? EE_CHAR_LANGUAGE_CJK
: EE_CHAR_LANGUAGE_CTL
;
90 case EE_CHAR_FONTINFO
:
91 nId
= ( nScriptType
== i18n::ScriptType::ASIAN
) ? EE_CHAR_FONTINFO_CJK
: EE_CHAR_FONTINFO_CTL
;
93 case EE_CHAR_FONTHEIGHT
:
94 nId
= ( nScriptType
== i18n::ScriptType::ASIAN
) ? EE_CHAR_FONTHEIGHT_CJK
: EE_CHAR_FONTHEIGHT_CTL
;
97 nId
= ( nScriptType
== i18n::ScriptType::ASIAN
) ? EE_CHAR_WEIGHT_CJK
: EE_CHAR_WEIGHT_CTL
;
100 nId
= ( nScriptType
== i18n::ScriptType::ASIAN
) ? EE_CHAR_ITALIC_CJK
: EE_CHAR_ITALIC_CTL
;
108 BOOL
IsScriptItemValid( USHORT nItemId
, short nScriptType
)
114 case EE_CHAR_LANGUAGE
:
115 bValid
= nScriptType
== i18n::ScriptType::LATIN
;
117 case EE_CHAR_LANGUAGE_CJK
:
118 bValid
= nScriptType
== i18n::ScriptType::ASIAN
;
120 case EE_CHAR_LANGUAGE_CTL
:
121 bValid
= nScriptType
== i18n::ScriptType::COMPLEX
;
123 case EE_CHAR_FONTINFO
:
124 bValid
= nScriptType
== i18n::ScriptType::LATIN
;
126 case EE_CHAR_FONTINFO_CJK
:
127 bValid
= nScriptType
== i18n::ScriptType::ASIAN
;
129 case EE_CHAR_FONTINFO_CTL
:
130 bValid
= nScriptType
== i18n::ScriptType::COMPLEX
;
132 case EE_CHAR_FONTHEIGHT
:
133 bValid
= nScriptType
== i18n::ScriptType::LATIN
;
135 case EE_CHAR_FONTHEIGHT_CJK
:
136 bValid
= nScriptType
== i18n::ScriptType::ASIAN
;
138 case EE_CHAR_FONTHEIGHT_CTL
:
139 bValid
= nScriptType
== i18n::ScriptType::COMPLEX
;
142 bValid
= nScriptType
== i18n::ScriptType::LATIN
;
144 case EE_CHAR_WEIGHT_CJK
:
145 bValid
= nScriptType
== i18n::ScriptType::ASIAN
;
147 case EE_CHAR_WEIGHT_CTL
:
148 bValid
= nScriptType
== i18n::ScriptType::COMPLEX
;
151 bValid
= nScriptType
== i18n::ScriptType::LATIN
;
153 case EE_CHAR_ITALIC_CJK
:
154 bValid
= nScriptType
== i18n::ScriptType::ASIAN
;
156 case EE_CHAR_ITALIC_CTL
:
157 bValid
= nScriptType
== i18n::ScriptType::COMPLEX
;
165 // ------------------------------------------------------------
167 // Sollte spaeter zentral nach TOOLS/STRING (Aktuell: 303)
168 // fuer Grep: WS_TARGET
170 DBG_NAME( EE_TextPortion
);
171 DBG_NAME( EE_EditLine
);
172 DBG_NAME( EE_ContentNode
);
173 DBG_NAME( EE_CharAttribList
);
175 SfxItemInfo aItemInfos
[EDITITEMCOUNT
] = {
176 { SID_ATTR_FRAMEDIRECTION
, SFX_ITEM_POOLABLE
}, // EE_PARA_WRITINGDIR
177 { 0, SFX_ITEM_POOLABLE
}, // EE_PARA_XMLATTRIBS
178 { SID_ATTR_PARA_HANGPUNCTUATION
, SFX_ITEM_POOLABLE
}, // EE_PARA_HANGINGPUNCTUATION
179 { SID_ATTR_PARA_FORBIDDEN_RULES
, SFX_ITEM_POOLABLE
},
180 { SID_ATTR_PARA_SCRIPTSPACE
, SFX_ITEM_POOLABLE
}, // EE_PARA_ASIANCJKSPACING
181 { SID_ATTR_NUMBERING_RULE
, SFX_ITEM_POOLABLE
}, // EE_PARA_NUMBULL
182 { 0, SFX_ITEM_POOLABLE
}, // EE_PARA_HYPHENATE
183 { 0, SFX_ITEM_POOLABLE
}, // EE_PARA_BULLETSTATE
184 { 0, SFX_ITEM_POOLABLE
}, // EE_PARA_OUTLLRSPACE
185 { SID_ATTR_PARA_OUTLLEVEL
, SFX_ITEM_POOLABLE
},
186 { SID_ATTR_PARA_BULLET
, SFX_ITEM_POOLABLE
},
187 { SID_ATTR_LRSPACE
, SFX_ITEM_POOLABLE
},
188 { SID_ATTR_ULSPACE
, SFX_ITEM_POOLABLE
},
189 { SID_ATTR_PARA_LINESPACE
, SFX_ITEM_POOLABLE
},
190 { SID_ATTR_PARA_ADJUST
, SFX_ITEM_POOLABLE
},
191 { SID_ATTR_TABSTOP
, SFX_ITEM_POOLABLE
},
192 { SID_ATTR_CHAR_COLOR
, SFX_ITEM_POOLABLE
},
193 { SID_ATTR_CHAR_FONT
, SFX_ITEM_POOLABLE
},
194 { SID_ATTR_CHAR_FONTHEIGHT
, SFX_ITEM_POOLABLE
},
195 { SID_ATTR_CHAR_SCALEWIDTH
, SFX_ITEM_POOLABLE
},
196 { SID_ATTR_CHAR_WEIGHT
, SFX_ITEM_POOLABLE
},
197 { SID_ATTR_CHAR_UNDERLINE
, SFX_ITEM_POOLABLE
},
198 { SID_ATTR_CHAR_STRIKEOUT
, SFX_ITEM_POOLABLE
},
199 { SID_ATTR_CHAR_POSTURE
, SFX_ITEM_POOLABLE
},
200 { SID_ATTR_CHAR_CONTOUR
, SFX_ITEM_POOLABLE
},
201 { SID_ATTR_CHAR_SHADOWED
, SFX_ITEM_POOLABLE
},
202 { SID_ATTR_CHAR_ESCAPEMENT
, SFX_ITEM_POOLABLE
},
203 { SID_ATTR_CHAR_AUTOKERN
, SFX_ITEM_POOLABLE
},
204 { SID_ATTR_CHAR_KERNING
, SFX_ITEM_POOLABLE
},
205 { SID_ATTR_CHAR_WORDLINEMODE
, SFX_ITEM_POOLABLE
},
206 { SID_ATTR_CHAR_LANGUAGE
, SFX_ITEM_POOLABLE
},
207 { SID_ATTR_CHAR_CJK_LANGUAGE
, SFX_ITEM_POOLABLE
},
208 { SID_ATTR_CHAR_CTL_LANGUAGE
, SFX_ITEM_POOLABLE
},
209 { SID_ATTR_CHAR_CJK_FONT
, SFX_ITEM_POOLABLE
},
210 { SID_ATTR_CHAR_CTL_FONT
, SFX_ITEM_POOLABLE
},
211 { SID_ATTR_CHAR_CJK_FONTHEIGHT
, SFX_ITEM_POOLABLE
},
212 { SID_ATTR_CHAR_CTL_FONTHEIGHT
, SFX_ITEM_POOLABLE
},
213 { SID_ATTR_CHAR_CJK_WEIGHT
, SFX_ITEM_POOLABLE
},
214 { SID_ATTR_CHAR_CTL_WEIGHT
, SFX_ITEM_POOLABLE
},
215 { SID_ATTR_CHAR_CJK_POSTURE
, SFX_ITEM_POOLABLE
},
216 { SID_ATTR_CHAR_CTL_POSTURE
, SFX_ITEM_POOLABLE
},
217 { SID_ATTR_CHAR_EMPHASISMARK
, SFX_ITEM_POOLABLE
},
218 { SID_ATTR_CHAR_RELIEF
, SFX_ITEM_POOLABLE
},
219 { 0, SFX_ITEM_POOLABLE
}, // EE_CHAR_RUBI_DUMMY
220 { 0, SFX_ITEM_POOLABLE
}, // EE_CHAR_XMLATTRIBS
221 { SID_ATTR_CHAR_OVERLINE
, SFX_ITEM_POOLABLE
},
222 { 0, SFX_ITEM_POOLABLE
}, // EE_FEATURE_TAB
223 { 0, SFX_ITEM_POOLABLE
}, // EE_FEATURE_LINEBR
224 { SID_ATTR_CHAR_CHARSETCOLOR
, SFX_ITEM_POOLABLE
}, // EE_FEATURE_NOTCONV
225 { SID_FIELD
, SFX_ITEM_POOLABLE
}
229 3999, 4001, 4002, 4003, 4004, 4005, 4006,
230 4007, 4008, 4009, 4010, 4011, 4012, 4013, 4017, 4018, 4019 // MI: 4019?
234 3999, 4000, 4001, 4002, 4003, 4004, 4005, 4006, 4007, 4008, 4009,
235 4010, 4011, 4012, 4013, 4014, 4015, 4016, 4018, 4019, 4020
239 3997, 3998, 3999, 4000, 4001, 4002, 4003, 4004, 4005, 4006, 4007,
240 4009, 4010, 4011, 4012, 4013, 4014, 4015, 4016, 4017, 4018, 4019,
245 3994, 3995, 3996, 3997, 3998, 3999, 4000, 4001, 4002, 4003,
246 4004, 4005, 4006, 4007, 4008, 4009, 4010, 4011, 4012, 4013,
247 4014, 4015, 4016, 4017, 4018,
248 /* CJK Items inserted here: EE_CHAR_LANGUAGE - EE_CHAR_XMLATTRIBS */
249 4034, 4035, 4036, 4037
253 3994, 3995, 3996, 3997, 3998, 3999, 4000, 4001, 4002, 4003,
254 4004, 4005, 4006, 4007, 4008, 4009, 4010, 4011, 4012, 4013,
255 4014, 4015, 4016, 4017, 4018, 4019, 4020, 4021, 4022, 4023,
256 4024, 4025, 4026, 4027, 4028, 4029, 4030, 4031, 4032, 4033,
257 /* EE_CHAR_OVERLINE inserted here */
258 4035, 4036, 4037, 4038
261 SV_IMPL_PTRARR( DummyContentList
, ContentNode
* );
262 SV_IMPL_VARARR( ScriptTypePosInfos
, ScriptTypePosInfo
);
263 SV_IMPL_VARARR( WritingDirectionInfos
, WritingDirectionInfo
);
264 // SV_IMPL_VARARR( ExtraCharInfos, ExtraCharInfo );
267 int SAL_CALL
CompareStart( const void* pFirst
, const void* pSecond
)
269 if ( (*((EditCharAttrib
**)pFirst
))->GetStart() < (*((EditCharAttrib
**)pSecond
))->GetStart() )
271 else if ( (*((EditCharAttrib
**)pFirst
))->GetStart() > (*((EditCharAttrib
**)pSecond
))->GetStart() )
276 EditCharAttrib
* MakeCharAttrib( SfxItemPool
& rPool
, const SfxPoolItem
& rAttr
, USHORT nS
, USHORT nE
)
278 // das neue Attribut im Pool anlegen
279 const SfxPoolItem
& rNew
= rPool
.Put( rAttr
);
281 EditCharAttrib
* pNew
= 0;
282 switch( rNew
.Which() )
284 case EE_CHAR_LANGUAGE
:
285 case EE_CHAR_LANGUAGE_CJK
:
286 case EE_CHAR_LANGUAGE_CTL
:
288 pNew
= new EditCharAttribLanguage( (const SvxLanguageItem
&)rNew
, nS
, nE
);
293 pNew
= new EditCharAttribColor( (const SvxColorItem
&)rNew
, nS
, nE
);
296 case EE_CHAR_FONTINFO
:
297 case EE_CHAR_FONTINFO_CJK
:
298 case EE_CHAR_FONTINFO_CTL
:
300 pNew
= new EditCharAttribFont( (const SvxFontItem
&)rNew
, nS
, nE
);
303 case EE_CHAR_FONTHEIGHT
:
304 case EE_CHAR_FONTHEIGHT_CJK
:
305 case EE_CHAR_FONTHEIGHT_CTL
:
307 pNew
= new EditCharAttribFontHeight( (const SvxFontHeightItem
&)rNew
, nS
, nE
);
310 case EE_CHAR_FONTWIDTH
:
312 pNew
= new EditCharAttribFontWidth( (const SvxCharScaleWidthItem
&)rNew
, nS
, nE
);
316 case EE_CHAR_WEIGHT_CJK
:
317 case EE_CHAR_WEIGHT_CTL
:
319 pNew
= new EditCharAttribWeight( (const SvxWeightItem
&)rNew
, nS
, nE
);
322 case EE_CHAR_UNDERLINE
:
324 pNew
= new EditCharAttribUnderline( (const SvxUnderlineItem
&)rNew
, nS
, nE
);
327 case EE_CHAR_OVERLINE
:
329 pNew
= new EditCharAttribOverline( (const SvxOverlineItem
&)rNew
, nS
, nE
);
332 case EE_CHAR_EMPHASISMARK
:
334 pNew
= new EditCharAttribEmphasisMark( (const SvxEmphasisMarkItem
&)rNew
, nS
, nE
);
339 pNew
= new EditCharAttribRelief( (const SvxCharReliefItem
&)rNew
, nS
, nE
);
342 case EE_CHAR_STRIKEOUT
:
344 pNew
= new EditCharAttribStrikeout( (const SvxCrossedOutItem
&)rNew
, nS
, nE
);
348 case EE_CHAR_ITALIC_CJK
:
349 case EE_CHAR_ITALIC_CTL
:
351 pNew
= new EditCharAttribItalic( (const SvxPostureItem
&)rNew
, nS
, nE
);
354 case EE_CHAR_OUTLINE
:
356 pNew
= new EditCharAttribOutline( (const SvxContourItem
&)rNew
, nS
, nE
);
361 pNew
= new EditCharAttribShadow( (const SvxShadowedItem
&)rNew
, nS
, nE
);
364 case EE_CHAR_ESCAPEMENT
:
366 pNew
= new EditCharAttribEscapement( (const SvxEscapementItem
&)rNew
, nS
, nE
);
369 case EE_CHAR_PAIRKERNING
:
371 pNew
= new EditCharAttribPairKerning( (const SvxAutoKernItem
&)rNew
, nS
, nE
);
374 case EE_CHAR_KERNING
:
376 pNew
= new EditCharAttribKerning( (const SvxKerningItem
&)rNew
, nS
, nE
);
381 pNew
= new EditCharAttribWordLineMode( (const SvxWordLineModeItem
&)rNew
, nS
, nE
);
384 case EE_CHAR_XMLATTRIBS
:
386 pNew
= new EditCharAttrib( rNew
, nS
, nE
); // Attrib is only for holding XML information...
391 pNew
= new EditCharAttribTab( (const SfxVoidItem
&)rNew
, nS
);
394 case EE_FEATURE_LINEBR
:
396 pNew
= new EditCharAttribLineBreak( (const SfxVoidItem
&)rNew
, nS
);
399 case EE_FEATURE_FIELD
:
401 pNew
= new EditCharAttribField( (const SvxFieldItem
&)rNew
, nS
);
406 DBG_ERROR( "Ungueltiges Attribut!" );
412 // -------------------------------------------------------------------------
414 // -------------------------------------------------------------------------
418 DBG_CTOR( EE_EditLine
, 0 );
421 nStartPortion
= 0; // damit in ungueltiger Zeile ohne Portions von einer gueltigen Zeile mit der Portion Nr0 unterscieden werden kann.
429 bHangingPunctuation
= FALSE
;
433 EditLine::EditLine( const EditLine
& r
)
435 DBG_CTOR( EE_EditLine
, 0 );
439 nStartPortion
= r
.nStartPortion
;
440 nEndPortion
= r
.nEndPortion
;
441 bHangingPunctuation
= r
.bHangingPunctuation
;
452 EditLine::~EditLine()
454 DBG_DTOR( EE_EditLine
, 0 );
457 EditLine
* EditLine::Clone() const
459 EditLine
* pL
= new EditLine
;
460 if ( aPositions
.Count() )
462 pL
->aPositions
.Insert (aPositions
.GetData(), aPositions
.Count(), 0);
464 pL
->nStartPosX
= nStartPosX
;
467 pL
->nStartPortion
= nStartPortion
;
468 pL
->nEndPortion
= nEndPortion
;
469 pL
->nHeight
= nHeight
;
470 pL
->nTxtWidth
= nTxtWidth
;
471 pL
->nTxtHeight
= nTxtHeight
;
472 pL
->nCrsrHeight
= nCrsrHeight
;
473 pL
->nMaxAscent
= nMaxAscent
;
478 BOOL
operator == ( const EditLine
& r1
, const EditLine
& r2
)
480 if ( r1
.nStart
!= r2
.nStart
)
483 if ( r1
.nEnd
!= r2
.nEnd
)
486 if ( r1
.nStartPortion
!= r2
.nStartPortion
)
489 if ( r1
.nEndPortion
!= r2
.nEndPortion
)
495 EditLine
& EditLine::operator = ( const EditLine
& r
)
499 nEndPortion
= r
.nEndPortion
;
500 nStartPortion
= r
.nStartPortion
;
505 BOOL
operator != ( const EditLine
& r1
, const EditLine
& r2
)
507 return !( r1
== r2
);
510 Size
EditLine::CalcTextSize( ParaPortion
& rParaPortion
)
514 TextPortion
* pPortion
;
516 USHORT nIndex
= GetStart();
518 DBG_ASSERT( rParaPortion
.GetTextPortions().Count(), "GetTextSize vor CreatePortions !" );
520 for ( USHORT n
= nStartPortion
; n
<= nEndPortion
; n
++ )
522 pPortion
= rParaPortion
.GetTextPortions().GetObject(n
);
523 switch ( pPortion
->GetKind() )
525 case PORTIONKIND_TEXT
:
526 case PORTIONKIND_FIELD
:
527 case PORTIONKIND_HYPHENATOR
:
529 aTmpSz
= pPortion
->GetSize();
530 aSz
.Width() += aTmpSz
.Width();
531 if ( aSz
.Height() < aTmpSz
.Height() )
532 aSz
.Height() = aTmpSz
.Height();
535 case PORTIONKIND_TAB
:
536 // case PORTIONKIND_EXTRASPACE:
538 aSz
.Width() += pPortion
->GetSize().Width();
542 nIndex
= nIndex
+ pPortion
->GetLen();
545 SetHeight( (USHORT
)aSz
.Height() );
549 \f// -------------------------------------------------------------------------
550 // class EditLineList
551 // -------------------------------------------------------------------------
552 EditLineList::EditLineList()
556 EditLineList::~EditLineList()
561 void EditLineList::Reset()
563 for ( USHORT nLine
= 0; nLine
< Count(); nLine
++ )
564 delete GetObject(nLine
);
565 Remove( 0, Count() );
568 void EditLineList::DeleteFromLine( USHORT nDelFrom
)
570 DBG_ASSERT( nDelFrom
<= (Count() - 1), "DeleteFromLine: Out of range" );
571 for ( USHORT nL
= nDelFrom
; nL
< Count(); nL
++ )
572 delete GetObject(nL
);
573 Remove( nDelFrom
, Count()-nDelFrom
);
576 USHORT
EditLineList::FindLine( USHORT nChar
, BOOL bInclEnd
)
578 for ( USHORT nLine
= 0; nLine
< Count(); nLine
++ )
580 EditLine
* pLine
= GetObject( nLine
);
581 if ( ( bInclEnd
&& ( pLine
->GetEnd() >= nChar
) ) ||
582 ( pLine
->GetEnd() > nChar
) )
588 DBG_ASSERT( !bInclEnd
, "Zeile nicht gefunden: FindLine" );
589 return ( Count() - 1 );
592 \f// -------------------------------------------------------------------------
593 // class EditSelection
594 // -------------------------------------------------------------------------
595 BOOL
EditPaM::DbgIsBuggy( EditDoc
& rDoc
)
599 if ( rDoc
.GetPos( pNode
) >= rDoc
.Count() )
601 if ( nIndex
> pNode
->Len() )
607 BOOL
EditSelection::DbgIsBuggy( EditDoc
& rDoc
)
609 if ( aStartPaM
.DbgIsBuggy( rDoc
) )
611 if ( aEndPaM
.DbgIsBuggy( rDoc
) )
617 EditSelection::EditSelection()
621 EditSelection::EditSelection( const EditPaM
& rStartAndAnd
)
623 // koennte noch optimiert werden!
624 // nicht erst Def-CTOR vom PaM rufen!
625 aStartPaM
= rStartAndAnd
;
626 aEndPaM
= rStartAndAnd
;
629 EditSelection::EditSelection( const EditPaM
& rStart
, const EditPaM
& rEnd
)
631 // koennte noch optimiert werden!
636 EditSelection
& EditSelection::operator = ( const EditPaM
& rPaM
)
643 BOOL
EditSelection::IsInvalid() const
647 if ( aStartPaM
== aEmptyPaM
)
650 if ( aEndPaM
== aEmptyPaM
)
656 BOOL
EditSelection::Adjust( const ContentList
& rNodes
)
658 DBG_ASSERT( aStartPaM
.GetIndex() <= aStartPaM
.GetNode()->Len(), "Index im Wald in Adjust(1)" );
659 DBG_ASSERT( aEndPaM
.GetIndex() <= aEndPaM
.GetNode()->Len(), "Index im Wald in Adjust(2)" );
661 ContentNode
* pStartNode
= aStartPaM
.GetNode();
662 ContentNode
* pEndNode
= aEndPaM
.GetNode();
664 USHORT nStartNode
= rNodes
.GetPos( pStartNode
);
665 USHORT nEndNode
= rNodes
.GetPos( pEndNode
);
667 DBG_ASSERT( nStartNode
!= USHRT_MAX
, "Node im Wald in Adjust(1)" );
668 DBG_ASSERT( nEndNode
!= USHRT_MAX
, "Node im Wald in Adjust(2)" );
671 if ( nStartNode
> nEndNode
)
673 else if ( ( nStartNode
== nEndNode
) && ( aStartPaM
.GetIndex() > aEndPaM
.GetIndex() ) )
678 EditPaM
aTmpPaM( aStartPaM
);
687 \f// -------------------------------------------------------------------------
689 // -------------------------------------------------------------------------
690 BOOL
operator == ( const EditPaM
& r1
, const EditPaM
& r2
)
692 if ( r1
.GetNode() != r2
.GetNode() )
695 if ( r1
.GetIndex() != r2
.GetIndex() )
701 EditPaM
& EditPaM::operator = ( const EditPaM
& rPaM
)
703 nIndex
= rPaM
.nIndex
;
708 BOOL
operator != ( const EditPaM
& r1
, const EditPaM
& r2
)
710 return !( r1
== r2
);
714 \f// -------------------------------------------------------------------------
716 // -------------------------------------------------------------------------
717 ContentNode::ContentNode( SfxItemPool
& rPool
) : aContentAttribs( rPool
)
719 DBG_CTOR( EE_ContentNode
, 0 );
723 ContentNode::ContentNode( const XubString
& rStr
, const ContentAttribs
& rContentAttribs
) :
724 XubString( rStr
), aContentAttribs( rContentAttribs
)
726 DBG_CTOR( EE_ContentNode
, 0 );
730 ContentNode::~ContentNode()
732 DBG_DTOR( EE_ContentNode
, 0 );
738 void ContentNode::ExpandAttribs( USHORT nIndex
, USHORT nNew
, SfxItemPool
& rItemPool
)
743 // Da Features anders behandelt werden als normale Zeichenattribute,
744 // kann sich hier auch die Sortierung der Start-Liste aendern!
745 // In jedem if..., in dem weiter (n) Moeglichkeiten aufgrund von
746 // bFeature oder Spezialfall existieren,
747 // muessen (n-1) Moeglichkeiten mit bResort versehen werden.
748 // Die wahrscheinlichste Moeglichkeit erhaelt kein bResort,
749 // so dass nicht neu sortiert wird, wenn sich alle Attribute
751 BOOL bResort
= FALSE
;
752 BOOL bExpandedEmptyAtIndexNull
= FALSE
;
755 EditCharAttrib
* pAttrib
= GetAttrib( aCharAttribList
.GetAttribs(), nAttr
);
758 if ( pAttrib
->GetEnd() >= nIndex
)
760 // Alle Attribute hinter der Einfuegeposition verschieben...
761 if ( pAttrib
->GetStart() > nIndex
)
763 pAttrib
->MoveForward( nNew
);
765 // 0: Leeres Attribut expandieren, wenn an Einfuegestelle
766 else if ( pAttrib
->IsEmpty() )
768 // Index nicht pruefen, leeres durfte nur dort liegen.
769 // Wenn spaeter doch Ueberpruefung:
770 // Spezialfall: Start == 0; AbsLen == 1, nNew = 1 => Expand, weil durch Absatzumbruch!
771 // Start <= nIndex, End >= nIndex => Start=End=nIndex!
772 // if ( pAttrib->GetStart() == nIndex )
773 pAttrib
->Expand( nNew
);
774 if ( pAttrib
->GetStart() == 0 )
775 bExpandedEmptyAtIndexNull
= TRUE
;
777 // 1: Attribut startet davor, geht bis Index...
778 else if ( pAttrib
->GetEnd() == nIndex
) // Start muss davor liegen
780 // Nur expandieren, wenn kein Feature,
781 // und wenn nicht in ExcludeListe!
782 // Sonst geht z.B. ein UL bis zum neuen ULDB, beide expandieren
783 // if ( !pAttrib->IsFeature() && !rExclList.FindAttrib( pAttrib->Which() ) )
784 if ( !pAttrib
->IsFeature() && !aCharAttribList
.FindEmptyAttrib( pAttrib
->Which(), nIndex
) )
786 if ( !pAttrib
->IsEdge() )
787 pAttrib
->Expand( nNew
);
792 // 2: Attribut startet davor, geht hinter Index...
793 else if ( ( pAttrib
->GetStart() < nIndex
) && ( pAttrib
->GetEnd() > nIndex
) )
795 DBG_ASSERT( !pAttrib
->IsFeature(), "Grosses Feature?!" );
796 pAttrib
->Expand( nNew
);
798 // 3: Attribut startet auf Index...
799 else if ( pAttrib
->GetStart() == nIndex
)
801 if ( pAttrib
->IsFeature() )
803 pAttrib
->MoveForward( nNew
);
808 BOOL bExpand
= FALSE
;
812 if( bExpandedEmptyAtIndexNull
)
814 // Check if this kind of attribut was empty and expanded here...
815 USHORT nW
= pAttrib
->GetItem()->Which();
816 for ( USHORT nA
= 0; nA
< nAttr
; nA
++ )
818 EditCharAttrib
* pA
= aCharAttribList
.GetAttribs()[nA
];
819 if ( ( pA
->GetStart() == 0 ) && ( pA
->GetItem()->Which() == nW
) )
830 pAttrib
->Expand( nNew
);
835 pAttrib
->MoveForward( nNew
);
841 if ( pAttrib
->IsEdge() )
842 pAttrib
->SetEdge( FALSE
);
844 DBG_ASSERT( !pAttrib
->IsFeature() || ( pAttrib
->GetLen() == 1 ), "Expand: FeaturesLen != 1" );
846 DBG_ASSERT( pAttrib
->GetStart() <= pAttrib
->GetEnd(), "Expand: Attribut verdreht!" );
847 DBG_ASSERT( ( pAttrib
->GetEnd() <= Len() ), "Expand: Attrib groesser als Absatz!" );
848 if ( pAttrib
->IsEmpty() )
850 DBG_ERROR( "Leeres Attribut nach ExpandAttribs?" );
852 aCharAttribList
.GetAttribs().Remove( nAttr
);
853 rItemPool
.Remove( *pAttrib
->GetItem() );
858 pAttrib
= GetAttrib( aCharAttribList
.GetAttribs(), nAttr
);
862 aCharAttribList
.ResortAttribs();
867 BOOL bSep
= ( GetChar( nIndex
) == ' ' ) || IsFeature( nIndex
);
868 pWrongList
->TextInserted( nIndex
, nNew
, bSep
);
873 DBG_ASSERT( CheckOrderedList( aCharAttribList
.GetAttribs(), TRUE
), "Expand: Start-Liste verdreht" );
877 void ContentNode::CollapsAttribs( USHORT nIndex
, USHORT nDeleted
, SfxItemPool
& rItemPool
)
882 // Da Features anders behandelt werden als normale Zeichenattribute,
883 // kann sich hier auch die Sortierung der Start-Liste aendern!
884 BOOL bResort
= FALSE
;
885 BOOL bDelAttr
= FALSE
;
886 USHORT nEndChanges
= nIndex
+nDeleted
;
889 EditCharAttrib
* pAttrib
= GetAttrib( aCharAttribList
.GetAttribs(), nAttr
);
893 if ( pAttrib
->GetEnd() >= nIndex
)
895 // Alles Attribute hinter der Einfuegeposition verschieben...
896 if ( pAttrib
->GetStart() >= nEndChanges
)
898 pAttrib
->MoveBackward( nDeleted
);
900 // 1. Innenliegende Attribute loeschen...
901 else if ( ( pAttrib
->GetStart() >= nIndex
) && ( pAttrib
->GetEnd() <= nEndChanges
) )
903 // Spezialfall: Attrubt deckt genau den Bereich ab
904 // => als leeres Attribut behalten.
905 if ( !pAttrib
->IsFeature() && ( pAttrib
->GetStart() == nIndex
) && ( pAttrib
->GetEnd() == nEndChanges
) )
906 pAttrib
->GetEnd() = nIndex
; // leer
910 // 2. Attribut beginnt davor, endet drinnen oder dahinter...
911 else if ( ( pAttrib
->GetStart() <= nIndex
) && ( pAttrib
->GetEnd() > nIndex
) )
913 DBG_ASSERT( !pAttrib
->IsFeature(), "Collapsing Feature!" );
914 if ( pAttrib
->GetEnd() <= nEndChanges
) // endet drinnen
915 pAttrib
->GetEnd() = nIndex
;
917 pAttrib
->Collaps( nDeleted
); // endet dahinter
919 // 3. Attribut beginnt drinnen, endet dahinter...
920 else if ( ( pAttrib
->GetStart() >= nIndex
) && ( pAttrib
->GetEnd() > nEndChanges
) )
922 // Features duerfen nicht expandieren!
923 if ( pAttrib
->IsFeature() )
925 pAttrib
->MoveBackward( nDeleted
);
930 pAttrib
->GetStart() = nEndChanges
;
931 pAttrib
->MoveBackward( nDeleted
);
935 DBG_ASSERT( !pAttrib
->IsFeature() || ( pAttrib
->GetLen() == 1 ), "Expand: FeaturesLen != 1" );
937 DBG_ASSERT( pAttrib
->GetStart() <= pAttrib
->GetEnd(), "Collaps: Attribut verdreht!" );
938 DBG_ASSERT( ( pAttrib
->GetEnd() <= Len()) || bDelAttr
, "Collaps: Attrib groesser als Absatz!" );
939 if ( bDelAttr
/* || pAttrib->IsEmpty() */ )
942 aCharAttribList
.GetAttribs().Remove( nAttr
);
943 rItemPool
.Remove( *pAttrib
->GetItem() );
947 else if ( pAttrib
->IsEmpty() )
948 aCharAttribList
.HasEmptyAttribs() = TRUE
;
951 pAttrib
= GetAttrib( aCharAttribList
.GetAttribs(), nAttr
);
955 aCharAttribList
.ResortAttribs();
959 pWrongList
->TextDeleted( nIndex
, nDeleted
);
963 DBG_ASSERT( CheckOrderedList( aCharAttribList
.GetAttribs(), TRUE
), "Collaps: Start-Liste verdreht" );
967 void ContentNode::CopyAndCutAttribs( ContentNode
* pPrevNode
, SfxItemPool
& rPool
, BOOL bKeepEndingAttribs
)
969 DBG_ASSERT( pPrevNode
, "kopieren von Attributen auf einen NULL-Pointer ?" );
971 xub_StrLen nCut
= pPrevNode
->Len();
974 EditCharAttrib
* pAttrib
= GetAttrib( pPrevNode
->GetCharAttribs().GetAttribs(), nAttr
);
977 if ( pAttrib
->GetEnd() < nCut
)
979 // bleiben unveraendert....
982 else if ( pAttrib
->GetEnd() == nCut
)
984 // muessen als leeres Attribut kopiert werden.
985 if ( bKeepEndingAttribs
&& !pAttrib
->IsFeature() && !aCharAttribList
.FindAttrib( pAttrib
->GetItem()->Which(), 0 ) )
987 EditCharAttrib
* pNewAttrib
= MakeCharAttrib( rPool
, *(pAttrib
->GetItem()), 0, 0 );
988 DBG_ASSERT( pNewAttrib
, "MakeCharAttrib fehlgeschlagen!" );
989 aCharAttribList
.InsertAttrib( pNewAttrib
);
992 else if ( pAttrib
->IsInside( nCut
) || ( !nCut
&& !pAttrib
->GetStart() && !pAttrib
->IsFeature() ) )
994 // Wenn ganz vorne gecuttet wird, muss das Attribut erhalten bleiben!
995 // muessen kopiert und geaendert werden
996 EditCharAttrib
* pNewAttrib
= MakeCharAttrib( rPool
, *(pAttrib
->GetItem()), 0, pAttrib
->GetEnd()-nCut
);
997 DBG_ASSERT( pNewAttrib
, "MakeCharAttrib fehlgeschlagen!" );
998 aCharAttribList
.InsertAttrib( pNewAttrib
);
1000 pAttrib
->GetEnd() = nCut
;
1004 // alle dahinter verschieben in den neuen Node (this)
1005 // pPrevNode->GetCharAttribs().RemoveAttrib( pAttrib );
1006 pPrevNode
->GetCharAttribs().GetAttribs().Remove( nAttr
);
1007 aCharAttribList
.InsertAttrib( pAttrib
);
1008 DBG_ASSERT( pAttrib
->GetStart() >= nCut
, "Start < nCut!" );
1009 DBG_ASSERT( pAttrib
->GetEnd() >= nCut
, "End < nCut!" );
1010 pAttrib
->GetStart() = pAttrib
->GetStart() - nCut
;
1011 pAttrib
->GetEnd() = pAttrib
->GetEnd() - nCut
;
1015 pAttrib
= GetAttrib( pPrevNode
->GetCharAttribs().GetAttribs(), nAttr
);
1019 void ContentNode::AppendAttribs( ContentNode
* pNextNode
)
1021 DBG_ASSERT( pNextNode
, "kopieren von Attributen von einen NULL-Pointer ?" );
1023 USHORT nNewStart
= Len();
1026 DBG_ASSERT( aCharAttribList
.DbgCheckAttribs(), "Attribute VOR AppendAttribs kaputt" );
1030 EditCharAttrib
* pAttrib
= GetAttrib( pNextNode
->GetCharAttribs().GetAttribs(), nAttr
);
1033 // alle Attribute verschieben in den aktuellen Node (this)
1034 BOOL bMelted
= FALSE
;
1035 if ( ( pAttrib
->GetStart() == 0 ) && ( !pAttrib
->IsFeature() ) )
1037 // Evtl koennen Attribute zusammengefasst werden:
1038 USHORT nTmpAttr
= 0;
1039 EditCharAttrib
* pTmpAttrib
= GetAttrib( aCharAttribList
.GetAttribs(), nTmpAttr
);
1040 while ( !bMelted
&& pTmpAttrib
)
1042 if ( pTmpAttrib
->GetEnd() == nNewStart
)
1044 if ( ( pTmpAttrib
->Which() == pAttrib
->Which() ) &&
1045 ( *(pTmpAttrib
->GetItem()) == *(pAttrib
->GetItem() ) ) )
1047 pTmpAttrib
->GetEnd() =
1048 pTmpAttrib
->GetEnd() + pAttrib
->GetLen();
1049 pNextNode
->GetCharAttribs().GetAttribs().Remove( nAttr
);
1050 // Vom Pool abmelden ?!
1056 pTmpAttrib
= GetAttrib( aCharAttribList
.GetAttribs(), nTmpAttr
);
1062 pAttrib
->GetStart() = pAttrib
->GetStart() + nNewStart
;
1063 pAttrib
->GetEnd() = pAttrib
->GetEnd() + nNewStart
;
1064 aCharAttribList
.InsertAttrib( pAttrib
);
1067 pAttrib
= GetAttrib( pNextNode
->GetCharAttribs().GetAttribs(), nAttr
);
1069 // Fuer die Attribute, die nur ruebergewandert sind:
1070 pNextNode
->GetCharAttribs().Clear();
1073 DBG_ASSERT( aCharAttribList
.DbgCheckAttribs(), "Attribute NACH AppendAttribs kaputt" );
1077 void ContentNode::CreateDefFont()
1079 // Erst alle Informationen aus dem Style verwenden...
1080 SfxStyleSheet
* pS
= aContentAttribs
.GetStyleSheet();
1082 CreateFont( GetCharAttribs().GetDefFont(), pS
->GetItemSet() );
1084 // ... dann die harte Absatzformatierung rueberbuegeln...
1085 CreateFont( GetCharAttribs().GetDefFont(),
1086 GetContentAttribs().GetItems(), pS
== NULL
);
1089 void ContentNode::SetStyleSheet( SfxStyleSheet
* pS
, const SvxFont
& rFontFromStyle
)
1091 aContentAttribs
.SetStyleSheet( pS
);
1093 // Erst alle Informationen aus dem Style verwenden...
1094 GetCharAttribs().GetDefFont() = rFontFromStyle
;
1095 // ... dann die harte Absatzformatierung rueberbuegeln...
1096 CreateFont( GetCharAttribs().GetDefFont(),
1097 GetContentAttribs().GetItems(), pS
== NULL
);
1100 void ContentNode::SetStyleSheet( SfxStyleSheet
* pS
, BOOL bRecalcFont
)
1102 aContentAttribs
.SetStyleSheet( pS
);
1107 void ContentNode::DestroyWrongList()
1115 void ContentNode::CreateWrongList()
1117 DBG_ASSERT( !pWrongList
, "WrongList existiert schon!" );
1119 pWrongList
= new WrongList
;
1123 void ContentNode::SetWrongList( WrongList
* p
)
1125 DBG_ASSERT( !pWrongList
, "WrongList existiert schon!" );
1129 \f// -------------------------------------------------------------------------
1130 // class ContentAttribs
1131 // -------------------------------------------------------------------------
1132 ContentAttribs::ContentAttribs( SfxItemPool
& rPool
) :
1133 aAttribSet( rPool
, EE_PARA_START
, EE_CHAR_END
)
1138 ContentAttribs::ContentAttribs( const ContentAttribs
& rRef
) :
1139 aAttribSet( rRef
.aAttribSet
)
1141 pStyle
= rRef
.pStyle
;
1144 ContentAttribs::~ContentAttribs()
1148 SvxTabStop
ContentAttribs::FindTabStop( long nCurPos
, USHORT nDefTab
)
1150 const SvxTabStopItem
& rTabs
= (const SvxTabStopItem
&) GetItem( EE_PARA_TABS
);
1151 for ( USHORT i
= 0; i
< rTabs
.Count(); i
++ )
1153 const SvxTabStop
& rTab
= rTabs
[i
];
1154 if ( rTab
.GetTabPos() > nCurPos
)
1158 // DefTab ermitteln...
1159 SvxTabStop aTabStop
;
1160 long x
= nCurPos
/ nDefTab
+ 1;
1161 aTabStop
.GetTabPos() = nDefTab
* x
;
1165 void ContentAttribs::SetStyleSheet( SfxStyleSheet
* pS
)
1167 BOOL bStyleChanged
= ( pStyle
!= pS
);
1169 // #104799# Only when other style sheet, not when current style sheet modified
1170 if ( pStyle
&& bStyleChanged
)
1172 // Gezielt die Attribute aus der Absatzformatierung entfernen, die im Style
1173 // spezifiziert sind, damit die Attribute des Styles wirken koennen.
1174 const SfxItemSet
& rStyleAttribs
= pStyle
->GetItemSet();
1175 for ( USHORT nWhich
= EE_PARA_START
; nWhich
<= EE_CHAR_END
; nWhich
++ )
1177 // #99635# Don't change bullet on/off
1178 if ( ( nWhich
!= EE_PARA_BULLETSTATE
) && ( rStyleAttribs
.GetItemState( nWhich
) == SFX_ITEM_ON
) )
1179 aAttribSet
.ClearItem( nWhich
);
1184 const SfxPoolItem
& ContentAttribs::GetItem( USHORT nWhich
)
1186 // Harte Absatzattribute haben Vorrang!
1187 SfxItemSet
* pTakeFrom
= &aAttribSet
;
1188 if ( pStyle
&& ( aAttribSet
.GetItemState( nWhich
, FALSE
) != SFX_ITEM_ON
) )
1189 pTakeFrom
= &pStyle
->GetItemSet();
1191 return pTakeFrom
->Get( nWhich
);
1194 BOOL
ContentAttribs::HasItem( USHORT nWhich
)
1196 BOOL bHasItem
= FALSE
;
1197 if ( aAttribSet
.GetItemState( nWhich
, FALSE
) == SFX_ITEM_ON
)
1199 else if ( pStyle
&& pStyle
->GetItemSet().GetItemState( nWhich
) == SFX_ITEM_ON
)
1207 \f// ----------------------------------------------------------------------
1209 // ----------------------------------------------------------------------
1210 const SfxPoolItem
* ItemList::FindAttrib( USHORT nWhich
)
1212 const SfxPoolItem
* pItem
= First();
1213 while ( pItem
&& ( pItem
->Which() != nWhich
) )
1219 \f// -------------------------------------------------------------------------
1221 // -------------------------------------------------------------------------
1222 EditDoc::EditDoc( SfxItemPool
* pPool
)
1227 bOwnerOfPool
= FALSE
;
1231 pItemPool
= new EditEngineItemPool( FALSE
);
1232 bOwnerOfPool
= TRUE
;
1236 bIsVertical
= FALSE
;
1237 bIsFixedCellHeight
= FALSE
;
1239 // Don't create a empty node, Clear() will be called in EditEngine-CTOR
1241 SetModified( FALSE
);
1246 ImplDestroyContents();
1248 SfxItemPool::Free(pItemPool
);
1251 void EditDoc::ImplDestroyContents()
1253 for ( USHORT nNode
= Count(); nNode
; )
1254 RemoveItemsFromPool( GetObject( --nNode
) );
1255 DeleteAndDestroy( 0, Count() );
1258 void EditDoc::RemoveItemsFromPool( ContentNode
* pNode
)
1260 for ( USHORT nAttr
= 0; nAttr
< pNode
->GetCharAttribs().Count(); nAttr
++ )
1262 EditCharAttrib
* pAttr
= pNode
->GetCharAttribs().GetAttribs()[nAttr
];
1263 GetItemPool().Remove( *pAttr
->GetItem() );
1267 void CreateFont( SvxFont
& rFont
, const SfxItemSet
& rSet
, bool bSearchInParent
, short nScriptType
)
1269 Font
aPrevFont( rFont
);
1270 rFont
.SetAlign( ALIGN_BASELINE
);
1271 rFont
.SetTransparent( TRUE
);
1273 USHORT nWhich_FontInfo
= GetScriptItemId( EE_CHAR_FONTINFO
, nScriptType
);
1274 USHORT nWhich_Language
= GetScriptItemId( EE_CHAR_LANGUAGE
, nScriptType
);
1275 USHORT nWhich_FontHeight
= GetScriptItemId( EE_CHAR_FONTHEIGHT
, nScriptType
);
1276 USHORT nWhich_Weight
= GetScriptItemId( EE_CHAR_WEIGHT
, nScriptType
);
1277 USHORT nWhich_Italic
= GetScriptItemId( EE_CHAR_ITALIC
, nScriptType
);
1279 if ( bSearchInParent
|| ( rSet
.GetItemState( nWhich_FontInfo
) == SFX_ITEM_ON
) )
1281 const SvxFontItem
& rFontItem
= (const SvxFontItem
&)rSet
.Get( nWhich_FontInfo
);
1282 rFont
.SetName( rFontItem
.GetFamilyName() );
1283 rFont
.SetFamily( rFontItem
.GetFamily() );
1284 rFont
.SetPitch( rFontItem
.GetPitch() );
1285 rFont
.SetCharSet( rFontItem
.GetCharSet() );
1287 if ( bSearchInParent
|| ( rSet
.GetItemState( nWhich_Language
) == SFX_ITEM_ON
) )
1288 rFont
.SetLanguage( ((const SvxLanguageItem
&)rSet
.Get( nWhich_Language
)).GetLanguage() );
1289 if ( bSearchInParent
|| ( rSet
.GetItemState( EE_CHAR_COLOR
) == SFX_ITEM_ON
) )
1290 rFont
.SetColor( ((const SvxColorItem
&)rSet
.Get( EE_CHAR_COLOR
)).GetValue() );
1291 if ( bSearchInParent
|| ( rSet
.GetItemState( nWhich_FontHeight
) == SFX_ITEM_ON
) )
1292 rFont
.SetSize( Size( rFont
.GetSize().Width(), ((const SvxFontHeightItem
&)rSet
.Get( nWhich_FontHeight
) ).GetHeight() ) );
1293 if ( bSearchInParent
|| ( rSet
.GetItemState( nWhich_Weight
) == SFX_ITEM_ON
) )
1294 rFont
.SetWeight( ((const SvxWeightItem
&)rSet
.Get( nWhich_Weight
)).GetWeight() );
1295 if ( bSearchInParent
|| ( rSet
.GetItemState( EE_CHAR_UNDERLINE
) == SFX_ITEM_ON
) )
1296 rFont
.SetUnderline( ((const SvxUnderlineItem
&)rSet
.Get( EE_CHAR_UNDERLINE
)).GetLineStyle() );
1297 if ( bSearchInParent
|| ( rSet
.GetItemState( EE_CHAR_OVERLINE
) == SFX_ITEM_ON
) )
1298 rFont
.SetOverline( ((const SvxOverlineItem
&)rSet
.Get( EE_CHAR_OVERLINE
)).GetLineStyle() );
1299 if ( bSearchInParent
|| ( rSet
.GetItemState( EE_CHAR_STRIKEOUT
) == SFX_ITEM_ON
) )
1300 rFont
.SetStrikeout( ((const SvxCrossedOutItem
&)rSet
.Get( EE_CHAR_STRIKEOUT
)).GetStrikeout() );
1301 if ( bSearchInParent
|| ( rSet
.GetItemState( nWhich_Italic
) == SFX_ITEM_ON
) )
1302 rFont
.SetItalic( ((const SvxPostureItem
&)rSet
.Get( nWhich_Italic
)).GetPosture() );
1303 if ( bSearchInParent
|| ( rSet
.GetItemState( EE_CHAR_OUTLINE
) == SFX_ITEM_ON
) )
1304 rFont
.SetOutline( ((const SvxContourItem
&)rSet
.Get( EE_CHAR_OUTLINE
)).GetValue() );
1305 if ( bSearchInParent
|| ( rSet
.GetItemState( EE_CHAR_SHADOW
) == SFX_ITEM_ON
) )
1306 rFont
.SetShadow( ((const SvxShadowedItem
&)rSet
.Get( EE_CHAR_SHADOW
)).GetValue() );
1307 if ( bSearchInParent
|| ( rSet
.GetItemState( EE_CHAR_ESCAPEMENT
) == SFX_ITEM_ON
) )
1309 const SvxEscapementItem
& rEsc
= (const SvxEscapementItem
&) rSet
.Get( EE_CHAR_ESCAPEMENT
);
1311 USHORT nProp
= rEsc
.GetProp();
1312 rFont
.SetPropr( (BYTE
)nProp
);
1314 short nEsc
= rEsc
.GetEsc();
1315 if ( nEsc
== DFLT_ESC_AUTO_SUPER
)
1317 else if ( nEsc
== DFLT_ESC_AUTO_SUB
)
1318 nEsc
= sal::static_int_cast
< short >( -( 100 - nProp
) );
1319 rFont
.SetEscapement( nEsc
);
1321 if ( bSearchInParent
|| ( rSet
.GetItemState( EE_CHAR_PAIRKERNING
) == SFX_ITEM_ON
) )
1322 rFont
.SetKerning( ((const SvxAutoKernItem
&)rSet
.Get( EE_CHAR_PAIRKERNING
)).GetValue() );
1323 if ( bSearchInParent
|| ( rSet
.GetItemState( EE_CHAR_KERNING
) == SFX_ITEM_ON
) )
1324 rFont
.SetFixKerning( ((const SvxKerningItem
&)rSet
.Get( EE_CHAR_KERNING
)).GetValue() );
1325 if ( bSearchInParent
|| ( rSet
.GetItemState( EE_CHAR_WLM
) == SFX_ITEM_ON
) )
1326 rFont
.SetWordLineMode( ((const SvxWordLineModeItem
&)rSet
.Get( EE_CHAR_WLM
)).GetValue() );
1327 if ( bSearchInParent
|| ( rSet
.GetItemState( EE_CHAR_EMPHASISMARK
) == SFX_ITEM_ON
) )
1328 rFont
.SetEmphasisMark( ((const SvxEmphasisMarkItem
&)rSet
.Get( EE_CHAR_EMPHASISMARK
)).GetValue() );
1329 if ( bSearchInParent
|| ( rSet
.GetItemState( EE_CHAR_RELIEF
) == SFX_ITEM_ON
) )
1330 rFont
.SetRelief( (FontRelief
)((const SvxCharReliefItem
&)rSet
.Get( EE_CHAR_RELIEF
)).GetValue() );
1332 // Ob ich jetzt den ganzen Font vergleiche, oder vor jeder Aenderung
1333 // pruefe, ob der Wert sich aendert, bleibt sich relativ gleich.
1334 // So ggf ein MakeUniqFont im Font mehr, dafuer bei Aenderung schnellerer
1335 // Abbruch der Abfrage, oder ich musste noch jedesmal ein bChanged pflegen.
1336 if ( rFont
== aPrevFont
)
1337 rFont
= aPrevFont
; // => Gleicher ImpPointer fuer IsSameInstance
1340 void EditDoc::CreateDefFont( BOOL bUseStyles
)
1342 SfxItemSet
aTmpSet( GetItemPool(), EE_PARA_START
, EE_CHAR_END
);
1343 CreateFont( aDefFont
, aTmpSet
);
1344 aDefFont
.SetVertical( IsVertical() );
1345 aDefFont
.SetOrientation( IsVertical() ? 2700 : 0 );
1347 for ( USHORT nNode
= 0; nNode
< Count(); nNode
++ )
1349 ContentNode
* pNode
= GetObject( nNode
);
1350 pNode
->GetCharAttribs().GetDefFont() = aDefFont
;
1352 pNode
->CreateDefFont();
1356 static const sal_Unicode aCR
[] = { 0x0d, 0x00 };
1357 static const sal_Unicode aLF
[] = { 0x0a, 0x00 };
1358 static const sal_Unicode aCRLF
[] = { 0x0d, 0x0a, 0x00 };
1360 XubString
EditDoc::GetSepStr( LineEnd eEnd
)
1363 if ( eEnd
== LINEEND_CR
)
1365 else if ( eEnd
== LINEEND_LF
)
1372 XubString
EditDoc::GetText( LineEnd eEnd
) const
1374 ULONG nLen
= GetTextLen();
1375 USHORT nNodes
= Count();
1377 String aSep
= EditDoc::GetSepStr( eEnd
);
1378 USHORT nSepSize
= aSep
.Len();
1381 nLen
+= nNodes
* nSepSize
;
1382 if ( nLen
> 0xFFFb / sizeof(xub_Unicode
) )
1384 DBG_ERROR( "Text zu gross fuer String" );
1387 xub_Unicode
* pStr
= new xub_Unicode
[nLen
+1];
1388 xub_Unicode
* pCur
= pStr
;
1389 USHORT nLastNode
= nNodes
-1;
1390 for ( USHORT nNode
= 0; nNode
< nNodes
; nNode
++ )
1392 XubString
aTmp( GetParaAsString( GetObject(nNode
) ) );
1393 memcpy( pCur
, aTmp
.GetBuffer(), aTmp
.Len()*sizeof(sal_Unicode
) );
1395 if ( nSepSize
&& ( nNode
!= nLastNode
) )
1397 memcpy( pCur
, aSep
.GetBuffer(), nSepSize
*sizeof(sal_Unicode
) );
1402 XubString
aASCIIText( pStr
);
1407 XubString
EditDoc::GetParaAsString( USHORT nNode
) const
1409 return GetParaAsString( SaveGetObject( nNode
) );
1412 XubString
EditDoc::GetParaAsString( ContentNode
* pNode
, USHORT nStartPos
, USHORT nEndPos
, BOOL bResolveFields
) const
1414 if ( nEndPos
> pNode
->Len() )
1415 nEndPos
= pNode
->Len();
1417 DBG_ASSERT( nStartPos
<= nEndPos
, "Start und Ende vertauscht?" );
1419 USHORT nIndex
= nStartPos
;
1421 EditCharAttrib
* pNextFeature
= pNode
->GetCharAttribs().FindFeature( nIndex
);
1422 while ( nIndex
< nEndPos
)
1424 USHORT nEnd
= nEndPos
;
1425 if ( pNextFeature
&& ( pNextFeature
->GetStart() < nEnd
) )
1426 nEnd
= pNextFeature
->GetStart();
1428 pNextFeature
= 0; // Feature interessiert unten nicht
1431 DBG_ASSERT( nEnd
>= nIndex
, "Ende vorm Index?" );
1432 aStr
+= XubString( *pNode
, nIndex
, nEnd
-nIndex
);
1436 switch ( pNextFeature
->GetItem()->Which() )
1438 case EE_FEATURE_TAB
: aStr
+= '\t';
1440 case EE_FEATURE_LINEBR
: aStr
+= '\x0A';
1442 case EE_FEATURE_FIELD
: if ( bResolveFields
)
1443 aStr
+= ((EditCharAttribField
*)pNextFeature
)->GetFieldValue();
1445 default: DBG_ERROR( "Was fuer ein Feature ?" );
1447 pNextFeature
= pNode
->GetCharAttribs().FindFeature( ++nEnd
);
1454 ULONG
EditDoc::GetTextLen() const
1457 for ( USHORT nNode
= 0; nNode
< Count(); nNode
++ )
1459 ContentNode
* pNode
= GetObject( nNode
);
1460 nLen
+= pNode
->Len();
1461 // Felder k”nnen laenger sein als der Platzhalter im Node.
1462 const CharAttribArray
& rAttrs
= pNode
->GetCharAttribs().GetAttribs();
1463 for ( USHORT nAttr
= rAttrs
.Count(); nAttr
; )
1465 EditCharAttrib
* pAttr
= rAttrs
[--nAttr
];
1466 if ( pAttr
->Which() == EE_FEATURE_FIELD
)
1468 USHORT nFieldLen
= ((EditCharAttribField
*)pAttr
)->GetFieldValue().Len();
1472 nLen
+= nFieldLen
-1;
1479 EditPaM
EditDoc::Clear()
1481 ImplDestroyContents();
1483 ContentNode
* pNode
= new ContentNode( GetItemPool() );
1486 CreateDefFont( FALSE
);
1488 SetModified( FALSE
);
1490 EditPaM
aPaM( pNode
, 0 );
1494 void EditDoc::SetModified( BOOL b
)
1499 aModifyHdl
.Call( NULL
);
1503 EditPaM
EditDoc::RemoveText()
1505 // Das alte ItemSetmerken, damit z.B. im Chart Font behalten bleibt
1506 ContentNode
* pPrevFirstNode
= GetObject(0);
1507 SfxStyleSheet
* pPrevStyle
= pPrevFirstNode
->GetStyleSheet();
1508 SfxItemSet
aPrevSet( pPrevFirstNode
->GetContentAttribs().GetItems() );
1509 Font
aPrevFont( pPrevFirstNode
->GetCharAttribs().GetDefFont() );
1511 ImplDestroyContents();
1513 ContentNode
* pNode
= new ContentNode( GetItemPool() );
1516 pNode
->SetStyleSheet( pPrevStyle
, FALSE
);
1517 pNode
->GetContentAttribs().GetItems().Set( aPrevSet
);
1518 pNode
->GetCharAttribs().GetDefFont() = aPrevFont
;
1520 SetModified( TRUE
);
1522 EditPaM
aPaM( pNode
, 0 );
1526 void EditDoc::InsertText( const EditPaM
& rPaM
, xub_Unicode c
)
1528 DBG_ASSERT( c
!= 0x0A, "EditDoc::InsertText: Zeilentrenner in Absatz nicht erlaubt!" );
1529 DBG_ASSERT( c
!= 0x0D, "EditDoc::InsertText: Zeilentrenner in Absatz nicht erlaubt!" );
1530 DBG_ASSERT( c
!= '\t', "EditDoc::InsertText: Zeilentrenner in Absatz nicht erlaubt!" );
1532 rPaM
.GetNode()->Insert( c
, rPaM
.GetIndex() );
1533 rPaM
.GetNode()->ExpandAttribs( rPaM
.GetIndex(), 1, GetItemPool() );
1535 SetModified( TRUE
);
1538 EditPaM
EditDoc::InsertText( EditPaM aPaM
, const XubString
& rStr
)
1540 DBG_ASSERT( rStr
.Search( 0x0A ) == STRING_NOTFOUND
, "EditDoc::InsertText: Zeilentrenner in Absatz nicht erlaubt!" );
1541 DBG_ASSERT( rStr
.Search( 0x0D ) == STRING_NOTFOUND
, "EditDoc::InsertText: Zeilentrenner in Absatz nicht erlaubt!" );
1542 DBG_ASSERT( rStr
.Search( '\t' ) == STRING_NOTFOUND
, "EditDoc::InsertText: Zeilentrenner in Absatz nicht erlaubt!" );
1543 DBG_ASSERT( aPaM
.GetNode(), "Blinder PaM in EditDoc::InsertText1" );
1545 aPaM
.GetNode()->Insert( rStr
, aPaM
.GetIndex() );
1546 aPaM
.GetNode()->ExpandAttribs( aPaM
.GetIndex(), rStr
.Len(), GetItemPool() );
1547 aPaM
.GetIndex() = aPaM
.GetIndex() + rStr
.Len();
1549 SetModified( TRUE
);
1554 EditPaM
EditDoc::InsertParaBreak( EditPaM aPaM
, BOOL bKeepEndingAttribs
)
1556 DBG_ASSERT( aPaM
.GetNode(), "Blinder PaM in EditDoc::InsertParaBreak" );
1557 ContentNode
* pCurNode
= aPaM
.GetNode();
1558 USHORT nPos
= GetPos( pCurNode
);
1559 XubString aStr
= aPaM
.GetNode()->Copy( aPaM
.GetIndex() );
1560 aPaM
.GetNode()->Erase( aPaM
.GetIndex() );
1562 // the paragraph attributes...
1563 ContentAttribs
aContentAttribs( aPaM
.GetNode()->GetContentAttribs() );
1565 // for a new paragraph we like to have the bullet/numbering visible by default
1566 aContentAttribs
.GetItems().Put( SfxBoolItem( EE_PARA_BULLETSTATE
, TRUE
), EE_PARA_BULLETSTATE
);
1568 // ContenNode-CTOR kopiert auch die Absatzattribute
1569 ContentNode
* pNode
= new ContentNode( aStr
, aContentAttribs
);
1571 // Den Default-Font kopieren
1572 pNode
->GetCharAttribs().GetDefFont() = aPaM
.GetNode()->GetCharAttribs().GetDefFont();
1573 SfxStyleSheet
* pStyle
= aPaM
.GetNode()->GetStyleSheet();
1576 XubString
aFollow( pStyle
->GetFollow() );
1577 if ( aFollow
.Len() && ( aFollow
!= pStyle
->GetName() ) )
1579 SfxStyleSheetBase
* pNext
= pStyle
->GetPool().Find( aFollow
, pStyle
->GetFamily() );
1580 pNode
->SetStyleSheet( (SfxStyleSheet
*)pNext
);
1584 // Zeichenattribute muessen ggf. kopiert bzw gestutzt werden:
1585 pNode
->CopyAndCutAttribs( aPaM
.GetNode(), GetItemPool(), bKeepEndingAttribs
);
1587 Insert( pNode
, nPos
+1 );
1589 SetModified( TRUE
);
1591 aPaM
.SetNode( pNode
);
1596 EditPaM
EditDoc::InsertFeature( EditPaM aPaM
, const SfxPoolItem
& rItem
)
1598 DBG_ASSERT( aPaM
.GetNode(), "Blinder PaM in EditDoc::InsertFeature" );
1600 aPaM
.GetNode()->Insert( CH_FEATURE
, aPaM
.GetIndex() );
1601 aPaM
.GetNode()->ExpandAttribs( aPaM
.GetIndex(), 1, GetItemPool() );
1603 // Fuer das Feature ein Feature-Attribut anlegen...
1604 EditCharAttrib
* pAttrib
= MakeCharAttrib( GetItemPool(), rItem
, aPaM
.GetIndex(), aPaM
.GetIndex()+1 );
1605 DBG_ASSERT( pAttrib
, "Warum kann ich kein Feature anlegen ?" );
1606 aPaM
.GetNode()->GetCharAttribs().InsertAttrib( pAttrib
);
1608 SetModified( TRUE
);
1614 EditPaM
EditDoc::ConnectParagraphs( ContentNode
* pLeft
, ContentNode
* pRight
)
1616 const EditPaM
aPaM( pLeft
, pLeft
->Len() );
1618 // Erst die Attribute, da sonst nLen nicht stimmt!
1619 pLeft
->AppendAttribs( pRight
);
1623 // der rechte verschwindet.
1624 RemoveItemsFromPool( pRight
);
1625 USHORT nRight
= GetPos( pRight
);
1629 SetModified( TRUE
);
1634 EditPaM
EditDoc::RemoveChars( EditPaM aPaM
, USHORT nChars
)
1636 // Evtl. Features entfernen!
1637 aPaM
.GetNode()->Erase( aPaM
.GetIndex(), nChars
);
1638 aPaM
.GetNode()->CollapsAttribs( aPaM
.GetIndex(), nChars
, GetItemPool() );
1640 SetModified( TRUE
);
1645 void EditDoc::InsertAttribInSelection( ContentNode
* pNode
, USHORT nStart
, USHORT nEnd
, const SfxPoolItem
& rPoolItem
)
1647 DBG_ASSERT( pNode
, "Wohin mit dem Attribut?" );
1648 DBG_ASSERT( nEnd
<= pNode
->Len(), "InsertAttrib: Attribut zu gross!" );
1650 // fuer Optimierung:
1651 // dieses endet am Anfang der Selektion => kann erweitert werden
1652 EditCharAttrib
* pEndingAttrib
= 0;
1653 // dieses startet am Ende der Selektion => kann erweitert werden
1654 EditCharAttrib
* pStartingAttrib
= 0;
1656 DBG_ASSERT( nStart
<= nEnd
, "Kleiner Rechenfehler in InsertAttribInSelection" );
1658 RemoveAttribs( pNode
, nStart
, nEnd
, pStartingAttrib
, pEndingAttrib
, rPoolItem
.Which() );
1660 if ( pStartingAttrib
&& pEndingAttrib
&&
1661 ( *(pStartingAttrib
->GetItem()) == rPoolItem
) &&
1662 ( *(pEndingAttrib
->GetItem()) == rPoolItem
) )
1664 // wird ein groesses Attribut.
1665 pEndingAttrib
->GetEnd() = pStartingAttrib
->GetEnd();
1666 GetItemPool().Remove( *(pStartingAttrib
->GetItem()) );
1667 pNode
->GetCharAttribs().GetAttribs().Remove( pNode
->GetCharAttribs().GetAttribs().GetPos( pStartingAttrib
) );
1668 delete pStartingAttrib
;
1670 else if ( pStartingAttrib
&& ( *(pStartingAttrib
->GetItem()) == rPoolItem
) )
1671 pStartingAttrib
->GetStart() = nStart
;
1672 else if ( pEndingAttrib
&& ( *(pEndingAttrib
->GetItem()) == rPoolItem
) )
1673 pEndingAttrib
->GetEnd() = nEnd
;
1675 InsertAttrib( rPoolItem
, pNode
, nStart
, nEnd
);
1677 if ( pStartingAttrib
)
1678 pNode
->GetCharAttribs().ResortAttribs();
1680 SetModified( TRUE
);
1683 BOOL
EditDoc::RemoveAttribs( ContentNode
* pNode
, USHORT nStart
, USHORT nEnd
, USHORT nWhich
)
1685 EditCharAttrib
* pStarting
;
1686 EditCharAttrib
* pEnding
;
1687 return RemoveAttribs( pNode
, nStart
, nEnd
, pStarting
, pEnding
, nWhich
);
1690 BOOL
EditDoc::RemoveAttribs( ContentNode
* pNode
, USHORT nStart
, USHORT nEnd
, EditCharAttrib
*& rpStarting
, EditCharAttrib
*& rpEnding
, USHORT nWhich
)
1692 DBG_ASSERT( pNode
, "Wohin mit dem Attribut?" );
1693 DBG_ASSERT( nEnd
<= pNode
->Len(), "InsertAttrib: Attribut zu gross!" );
1695 // dieses endet am Anfang der Selektion => kann erweitert werden
1697 // dieses startet am Ende der Selektion => kann erweitert werden
1700 BOOL bChanged
= FALSE
;
1702 DBG_ASSERT( nStart
<= nEnd
, "Kleiner Rechenfehler in InsertAttribInSelection" );
1704 // ueber die Attribute iterieren...
1706 EditCharAttrib
* pAttr
= GetAttrib( pNode
->GetCharAttribs().GetAttribs(), nAttr
);
1709 BOOL bRemoveAttrib
= FALSE
;
1711 // Ich denke dass in dieser Methode generell keine Features geloescht
1713 // => Dann koennen die Feature-Abfragen weiter unten entfallen
1714 USHORT nAttrWhich
= pAttr
->Which();
1715 if ( ( nAttrWhich
< EE_FEATURE_START
) && ( !nWhich
|| ( nAttrWhich
== nWhich
) ) )
1717 // Attribut beginnt in Selection
1718 if ( ( pAttr
->GetStart() >= nStart
) && ( pAttr
->GetStart() <= nEnd
) )
1721 if ( pAttr
->GetEnd() > nEnd
)
1723 pAttr
->GetStart() = nEnd
; // dann faengt es dahinter an
1726 break; // es kann kein weiteres Attrib hier liegen
1728 else if ( !pAttr
->IsFeature() || ( pAttr
->GetStart() == nStart
) )
1730 // Feature nur loeschen, wenn genau an der Stelle
1731 bRemoveAttrib
= TRUE
;
1735 // Attribut endet in Selection
1736 else if ( ( pAttr
->GetEnd() >= nStart
) && ( pAttr
->GetEnd() <= nEnd
) )
1739 if ( ( pAttr
->GetStart() < nStart
) && !pAttr
->IsFeature() )
1741 pAttr
->GetEnd() = nStart
; // dann hoert es hier auf
1744 else if ( !pAttr
->IsFeature() || ( pAttr
->GetStart() == nStart
) )
1746 // Feature nur loeschen, wenn genau an der Stelle
1747 bRemoveAttrib
= TRUE
;
1750 // Attribut ueberlappt die Selektion
1751 else if ( ( pAttr
->GetStart() <= nStart
) && ( pAttr
->GetEnd() >= nEnd
) )
1754 if ( pAttr
->GetStart() == nStart
)
1756 pAttr
->GetStart() = nEnd
;
1759 break; // es kann weitere Attribute geben!
1761 else if ( pAttr
->GetEnd() == nEnd
)
1763 pAttr
->GetEnd() = nStart
;
1766 break; // es kann weitere Attribute geben!
1768 else // Attribut muss gesplittet werden...
1770 USHORT nOldEnd
= pAttr
->GetEnd();
1771 pAttr
->GetEnd() = nStart
;
1773 InsertAttrib( *pAttr
->GetItem(), pNode
, nEnd
, nOldEnd
);
1775 break; // es kann weitere Attribute geben!
1779 if ( bRemoveAttrib
)
1781 DBG_ASSERT( ( pAttr
!= rpStarting
) && ( pAttr
!= rpEnding
), "Loeschen und behalten des gleichen Attributs ?" );
1782 DBG_ASSERT( !pAttr
->IsFeature(), "RemoveAttribs: Remove a feature?!" );
1783 pNode
->GetCharAttribs().GetAttribs().Remove(nAttr
);
1784 GetItemPool().Remove( *pAttr
->GetItem() );
1789 pAttr
= GetAttrib( pNode
->GetCharAttribs().GetAttribs(), nAttr
);
1793 SetModified( TRUE
);
1798 void EditDoc::InsertAttrib( const SfxPoolItem
& rPoolItem
, ContentNode
* pNode
, USHORT nStart
, USHORT nEnd
)
1800 // Diese Methode prueft nicht mehr, ob ein entspr. Attribut
1801 // schon an der Stelle existiert!
1803 EditCharAttrib
* pAttrib
= MakeCharAttrib( GetItemPool(), rPoolItem
, nStart
, nEnd
);
1804 DBG_ASSERT( pAttrib
, "MakeCharAttrib fehlgeschlagen!" );
1805 pNode
->GetCharAttribs().InsertAttrib( pAttrib
);
1807 SetModified( TRUE
);
1810 void EditDoc::InsertAttrib( ContentNode
* pNode
, USHORT nStart
, USHORT nEnd
, const SfxPoolItem
& rPoolItem
)
1812 if ( nStart
!= nEnd
)
1814 InsertAttribInSelection( pNode
, nStart
, nEnd
, rPoolItem
);
1818 // Pruefen, ob schon ein neues Attribut mit der WhichId an der Stelle:
1819 EditCharAttrib
* pAttr
= pNode
->GetCharAttribs().FindEmptyAttrib( rPoolItem
.Which(), nStart
);
1822 // Attribut entfernen....
1823 pNode
->GetCharAttribs().GetAttribs().Remove(
1824 pNode
->GetCharAttribs().GetAttribs().GetPos( pAttr
) );
1827 // pruefen, ob ein 'gleiches' Attribut an der Stelle liegt.
1828 pAttr
= pNode
->GetCharAttribs().FindAttrib( rPoolItem
.Which(), nStart
);
1831 if ( pAttr
->IsInside( nStart
) ) // splitten
1833 // ???????????????????????????????
1834 // eigentlich noch pruefen, ob wirklich splittet, oder return !
1835 // ???????????????????????????????
1836 USHORT nOldEnd
= pAttr
->GetEnd();
1837 pAttr
->GetEnd() = nStart
;
1838 pAttr
= MakeCharAttrib( GetItemPool(), *(pAttr
->GetItem()), nStart
, nOldEnd
);
1839 pNode
->GetCharAttribs().InsertAttrib( pAttr
);
1841 else if ( pAttr
->GetEnd() == nStart
)
1843 DBG_ASSERT( !pAttr
->IsEmpty(), "Doch noch ein leeres Attribut?" );
1844 // pruefen, ob genau das gleiche Attribut
1845 if ( *(pAttr
->GetItem()) == rPoolItem
)
1849 InsertAttrib( rPoolItem
, pNode
, nStart
, nStart
);
1852 SetModified( TRUE
);
1855 void EditDoc::FindAttribs( ContentNode
* pNode
, USHORT nStartPos
, USHORT nEndPos
, SfxItemSet
& rCurSet
)
1857 DBG_ASSERT( pNode
, "Wo soll ich suchen ?" );
1858 DBG_ASSERT( nStartPos
<= nEndPos
, "Ungueltiger Bereich!" );
1861 EditCharAttrib
* pAttr
= GetAttrib( pNode
->GetCharAttribs().GetAttribs(), nAttr
);
1862 // keine Selection...
1863 if ( nStartPos
== nEndPos
)
1865 while ( pAttr
&& ( pAttr
->GetStart() <= nEndPos
) )
1867 const SfxPoolItem
* pItem
= 0;
1868 // Attribut liegt dadrueber...
1869 if ( ( pAttr
->GetStart() < nStartPos
) && ( pAttr
->GetEnd() > nStartPos
) )
1870 pItem
= pAttr
->GetItem();
1871 // Attribut endet hier, ist nicht leer
1872 else if ( ( pAttr
->GetStart() < nStartPos
) && ( pAttr
->GetEnd() == nStartPos
) )
1874 if ( !pNode
->GetCharAttribs().FindEmptyAttrib( pAttr
->GetItem()->Which(), nStartPos
) )
1875 pItem
= pAttr
->GetItem();
1877 // Attribut endet hier, ist leer
1878 else if ( ( pAttr
->GetStart() == nStartPos
) && ( pAttr
->GetEnd() == nStartPos
) )
1880 pItem
= pAttr
->GetItem();
1882 // Attribut beginnt hier
1883 else if ( ( pAttr
->GetStart() == nStartPos
) && ( pAttr
->GetEnd() > nStartPos
) )
1885 if ( nStartPos
== 0 ) // Sonderfall
1886 pItem
= pAttr
->GetItem();
1891 USHORT nWhich
= pItem
->Which();
1892 if ( rCurSet
.GetItemState( nWhich
) == SFX_ITEM_OFF
)
1894 rCurSet
.Put( *pItem
);
1896 else if ( rCurSet
.GetItemState( nWhich
) == SFX_ITEM_ON
)
1898 const SfxPoolItem
& rItem
= rCurSet
.Get( nWhich
);
1899 if ( rItem
!= *pItem
)
1901 rCurSet
.InvalidateItem( nWhich
);
1906 pAttr
= GetAttrib( pNode
->GetCharAttribs().GetAttribs(), nAttr
);
1911 while ( pAttr
&& ( pAttr
->GetStart() < nEndPos
) )
1913 const SfxPoolItem
* pItem
= 0;
1914 // Attribut liegt dadrueber...
1915 if ( ( pAttr
->GetStart() <= nStartPos
) && ( pAttr
->GetEnd() >= nEndPos
) )
1916 pItem
= pAttr
->GetItem();
1917 // Attribut startet mitten drin...
1918 else if ( pAttr
->GetStart() >= nStartPos
)
1920 // !!! pItem = pAttr->GetItem();
1921 // einfach nur pItem reicht nicht, da ich z.B. bei Shadow
1922 // niemals ein ungleiches Item finden wuerde, da ein solche
1923 // seine Anwesenheit durch Abwesenheit repraesentiert!
1925 // Es muesste geprueft werden, on genau das gleiche Attribut
1926 // an der Bruchstelle aufsetzt, was recht aufwendig ist.
1927 // Da ich beim Einfuegen von Attributen aber etwas optimiere
1928 // tritt der Fall nicht so schnell auf...
1929 // Also aus Geschwindigkeitsgruenden:
1930 rCurSet
.InvalidateItem( pAttr
->GetItem()->Which() );
1933 // Attribut endet mitten drin...
1934 else if ( pAttr
->GetEnd() > nStartPos
)
1936 // pItem = pAttr->GetItem();
1938 /*-----------------31.05.95 16:01-------------------
1939 Ist falsch, wenn das gleiche Attribut sofort wieder
1941 => Sollte am besten nicht vorkommen, also gleich beim
1942 Setzen von Attributen richtig machen!
1943 --------------------------------------------------*/
1944 rCurSet
.InvalidateItem( pAttr
->GetItem()->Which() );
1949 USHORT nWhich
= pItem
->Which();
1950 if ( rCurSet
.GetItemState( nWhich
) == SFX_ITEM_OFF
)
1952 rCurSet
.Put( *pItem
);
1954 else if ( rCurSet
.GetItemState( nWhich
) == SFX_ITEM_ON
)
1956 const SfxPoolItem
& rItem
= rCurSet
.Get( nWhich
);
1957 if ( rItem
!= *pItem
)
1959 rCurSet
.InvalidateItem( nWhich
);
1964 pAttr
= GetAttrib( pNode
->GetCharAttribs().GetAttribs(), nAttr
);
1970 \f// -------------------------------------------------------------------------
1971 // class EditCharAttribList
1972 // -------------------------------------------------------------------------
1974 CharAttribList::CharAttribList()
1976 DBG_CTOR( EE_CharAttribList
, 0 );
1977 bHasEmptyAttribs
= FALSE
;
1980 CharAttribList::~CharAttribList()
1982 DBG_DTOR( EE_CharAttribList
, 0 );
1985 EditCharAttrib
* pAttr
= GetAttrib( aAttribs
, nAttr
);
1990 pAttr
= GetAttrib( aAttribs
, nAttr
);
1995 void CharAttribList::InsertAttrib( EditCharAttrib
* pAttrib
)
1997 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1998 // optimieren: binaere Suche ? !
1999 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2002 // Vielleicht aber auch einfach nur rueckwaerts iterieren:
2003 // Der haeufigste und kritischste Fall: Attribute kommen bereits
2004 // sortiert an (InsertBinTextObject!)
2005 // Hier waere auch binaere Suche nicht optimal.
2006 // => Wuerde einiges bringen!
2008 const USHORT nCount
= Count();
2009 const USHORT nStart
= pAttrib
->GetStart(); // vielleicht besser fuer Comp.Opt.
2011 if ( pAttrib
->IsEmpty() )
2012 bHasEmptyAttribs
= TRUE
;
2014 BOOL bInserted
= FALSE
;
2015 for ( USHORT x
= 0; x
< nCount
; x
++ )
2017 EditCharAttribPtr pCurAttrib
= aAttribs
[x
];
2018 if ( pCurAttrib
->GetStart() > nStart
)
2020 aAttribs
.Insert( pAttrib
, x
);
2026 aAttribs
.Insert( pAttrib
, nCount
);
2029 void CharAttribList::ResortAttribs()
2033 #if defined __SUNPRO_CC
2034 #pragma disable_warn
2036 qsort( (void*)aAttribs
.GetData(), aAttribs
.Count(), sizeof( EditCharAttrib
* ), CompareStart
);
2037 #if defined __SUNPRO_CC
2043 void CharAttribList::OptimizeRanges( SfxItemPool
& rItemPool
)
2045 for ( USHORT n
= 0; n
< aAttribs
.Count(); n
++ )
2047 EditCharAttrib
* pAttr
= aAttribs
.GetObject( n
);
2048 for ( USHORT nNext
= n
+1; nNext
< aAttribs
.Count(); nNext
++ )
2050 EditCharAttrib
* p
= aAttribs
.GetObject( nNext
);
2051 if ( !pAttr
->IsFeature() && ( p
->GetStart() == pAttr
->GetEnd() ) && ( p
->Which() == pAttr
->Which() ) )
2053 if ( *p
->GetItem() == *pAttr
->GetItem() )
2055 pAttr
->GetEnd() = p
->GetEnd();
2056 aAttribs
.Remove( nNext
);
2057 rItemPool
.Remove( *p
->GetItem() );
2060 break; // only 1 attr with same which can start here.
2062 else if ( p
->GetStart() > pAttr
->GetEnd() )
2070 EditCharAttrib
* CharAttribList::FindAttrib( USHORT nWhich
, USHORT nPos
)
2072 // Rueckwaerts, falls eins dort endet, das naechste startet.
2073 // => Das startende gilt...
2074 USHORT nAttr
= aAttribs
.Count()-1;
2075 EditCharAttrib
* pAttr
= GetAttrib( aAttribs
, nAttr
);
2078 if ( ( pAttr
->Which() == nWhich
) && pAttr
->IsIn(nPos
) )
2080 pAttr
= GetAttrib( aAttribs
, --nAttr
);
2085 EditCharAttrib
* CharAttribList::FindNextAttrib( USHORT nWhich
, USHORT nFromPos
) const
2087 DBG_ASSERT( nWhich
, "FindNextAttrib: Which?" );
2088 const USHORT nAttribs
= aAttribs
.Count();
2089 for ( USHORT nAttr
= 0; nAttr
< nAttribs
; nAttr
++ )
2091 EditCharAttrib
* pAttr
= aAttribs
[ nAttr
];
2092 if ( ( pAttr
->GetStart() >= nFromPos
) && ( pAttr
->Which() == nWhich
) )
2098 BOOL
CharAttribList::HasAttrib( USHORT nWhich
) const
2100 for ( USHORT nAttr
= aAttribs
.Count(); nAttr
; )
2102 const EditCharAttrib
* pAttr
= aAttribs
[--nAttr
];
2103 if ( pAttr
->Which() == nWhich
)
2109 BOOL
CharAttribList::HasAttrib( USHORT nStartPos
, USHORT nEndPos
) const
2112 for ( USHORT nAttr
= aAttribs
.Count(); nAttr
&& !bAttr
; )
2114 const EditCharAttrib
* pAttr
= aAttribs
[--nAttr
];
2115 if ( ( pAttr
->GetStart() < nEndPos
) && ( pAttr
->GetEnd() > nStartPos
) )
2116 return bAttr
= TRUE
;
2122 BOOL
CharAttribList::HasBoundingAttrib( USHORT nBound
)
2124 // Rueckwaerts, falls eins dort endet, das naechste startet.
2125 // => Das startende gilt...
2126 USHORT nAttr
= aAttribs
.Count()-1;
2127 EditCharAttrib
* pAttr
= GetAttrib( aAttribs
, nAttr
);
2128 while ( pAttr
&& ( pAttr
->GetEnd() >= nBound
) )
2130 if ( ( pAttr
->GetStart() == nBound
) || ( pAttr
->GetEnd() == nBound
) )
2132 pAttr
= GetAttrib( aAttribs
, --nAttr
);
2137 EditCharAttrib
* CharAttribList::FindEmptyAttrib( USHORT nWhich
, USHORT nPos
)
2139 if ( !bHasEmptyAttribs
)
2142 EditCharAttrib
* pAttr
= GetAttrib( aAttribs
, nAttr
);
2143 while ( pAttr
&& ( pAttr
->GetStart() <= nPos
) )
2145 if ( ( pAttr
->GetStart() == nPos
) && ( pAttr
->GetEnd() == nPos
) && ( pAttr
->Which() == nWhich
) )
2148 pAttr
= GetAttrib( aAttribs
, nAttr
);
2153 EditCharAttrib
* CharAttribList::FindFeature( USHORT nPos
) const
2157 EditCharAttrib
* pNextAttrib
= GetAttrib( aAttribs
, nAttr
);
2159 // erstmal zur gewuenschten Position...
2160 while ( pNextAttrib
&& ( pNextAttrib
->GetStart() < nPos
) )
2163 pNextAttrib
= GetAttrib( aAttribs
, nAttr
);
2166 // jetzt das Feature suchen...
2167 while ( pNextAttrib
&& !pNextAttrib
->IsFeature() )
2170 pNextAttrib
= GetAttrib( aAttribs
, nAttr
);
2177 void CharAttribList::DeleteEmptyAttribs( SfxItemPool
& rItemPool
)
2179 for ( USHORT nAttr
= 0; nAttr
< aAttribs
.Count(); nAttr
++ )
2181 EditCharAttrib
* pAttr
= aAttribs
[nAttr
];
2182 if ( pAttr
->IsEmpty() )
2184 rItemPool
.Remove( *pAttr
->GetItem() );
2185 aAttribs
.Remove( nAttr
);
2190 bHasEmptyAttribs
= FALSE
;
2193 BOOL
CharAttribList::DbgCheckAttribs()
2197 for ( USHORT nAttr
= 0; nAttr
< aAttribs
.Count(); nAttr
++ )
2199 EditCharAttrib
* pAttr
= aAttribs
[nAttr
];
2200 if ( pAttr
->GetStart() > pAttr
->GetEnd() )
2203 DBG_ERROR( "Attr verdreht" );
2205 else if ( pAttr
->IsFeature() && ( pAttr
->GetLen() != 1 ) )
2208 DBG_ERROR( "Feature, Len != 1" );
2219 SvxFontTable::SvxFontTable()
2223 SvxFontTable::~SvxFontTable()
2225 SvxFontItem
* pItem
= First();
2233 ULONG
SvxFontTable::GetId( const SvxFontItem
& rFontItem
)
2235 SvxFontItem
* pItem
= First();
2238 if ( *pItem
== rFontItem
)
2242 DBG_WARNING( "Font nicht gefunden: GetId()" );
2246 SvxColorList::SvxColorList()
2250 SvxColorList::~SvxColorList()
2252 SvxColorItem
* pItem
= First();
2260 ULONG
SvxColorList::GetId( const SvxColorItem
& rColorItem
)
2262 SvxColorItem
* pItem
= First();
2265 if ( *pItem
== rColorItem
)
2269 DBG_WARNING( "Color nicht gefunden: GetId()" );
2273 EditEngineItemPool::EditEngineItemPool( BOOL bPersistenRefCounts
)
2274 : SfxItemPool( String( "EditEngineItemPool", RTL_TEXTENCODING_ASCII_US
), EE_ITEMS_START
, EE_ITEMS_END
,
2275 aItemInfos
, 0, bPersistenRefCounts
)
2277 SetVersionMap( 1, 3999, 4015, aV1Map
);
2278 SetVersionMap( 2, 3999, 4019, aV2Map
);
2279 SetVersionMap( 3, 3997, 4020, aV3Map
);
2280 SetVersionMap( 4, 3994, 4022, aV4Map
);
2281 SetVersionMap( 5, 3994, 4037, aV5Map
);
2283 DBG_ASSERT( EE_DLL(), "EditDLL?!" );
2284 SfxPoolItem
** ppDefItems
= EE_DLL()->GetGlobalData()->GetDefItems();
2285 SetDefaults( ppDefItems
);
2288 EditEngineItemPool::~EditEngineItemPool()
2292 SvStream
& EditEngineItemPool::Store( SvStream
& rStream
) const
2294 // Bei einem 3.1-Export muess ein Hack eingebaut werden, da BUG im
2295 // SfxItemSet::Load, aber nicht nachtraeglich in 3.1 fixbar.
2297 // Der eingestellte Range muss nach Store erhalten bleiben, weil dann
2298 // erst die ItemSets gespeichert werden...
2300 long nVersion
= rStream
.GetVersion();
2301 BOOL b31Format
= ( nVersion
&& ( nVersion
<= SOFFICE_FILEFORMAT_31
) )
2304 EditEngineItemPool
* pThis
= (EditEngineItemPool
*)this;
2306 pThis
->SetStoringRange( 3997, 4022 );
2308 pThis
->SetStoringRange( EE_ITEMS_START
, EE_ITEMS_END
);
2310 return SfxItemPool::Store( rStream
);