Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <comphelper/string.hxx>
30 : : #include <vcl/wrkwin.hxx>
31 : : #include <vcl/dialog.hxx>
32 : : #include <vcl/msgbox.hxx>
33 : : #include <vcl/svapp.hxx>
34 : :
35 : : #include <editeng/tstpitem.hxx>
36 : : #include <editeng/colritem.hxx>
37 : : #include <editeng/fontitem.hxx>
38 : : #include <editeng/crsditem.hxx>
39 : : #include <editeng/fhgtitem.hxx>
40 : : #include <editeng/postitem.hxx>
41 : : #include <editeng/kernitem.hxx>
42 : : #include <editeng/wrlmitem.hxx>
43 : : #include <editeng/wghtitem.hxx>
44 : : #include <editeng/udlnitem.hxx>
45 : : #include <editeng/cntritem.hxx>
46 : : #include <editeng/escpitem.hxx>
47 : : #include <editeng/shdditem.hxx>
48 : : #include <editeng/akrnitem.hxx>
49 : : #include <editeng/cscoitem.hxx>
50 : : #include <editeng/langitem.hxx>
51 : : #include <editeng/emphitem.hxx>
52 : : #include <editeng/charscaleitem.hxx>
53 : : #include <editeng/charreliefitem.hxx>
54 : : #include <editeng/xmlcnitm.hxx>
55 : : #include <editeng/editids.hrc>
56 : : #include "editeng/editdata.hxx"
57 : : #include "editeng/lrspitem.hxx"
58 : : #include "editeng/ulspitem.hxx"
59 : : #include "editeng/lspcitem.hxx"
60 : :
61 : : #include <editdoc.hxx>
62 : : #include <editdbg.hxx>
63 : : #include <editeng/eerdll.hxx>
64 : : #include <eerdll2.hxx>
65 : :
66 : : #include <tools/stream.hxx>
67 : : #include <tools/debug.hxx>
68 : : #include <tools/shl.hxx>
69 : : #include <com/sun/star/i18n/ScriptType.hpp>
70 : :
71 : : #include <cassert>
72 : : #include <limits>
73 : :
74 : : #include <boost/bind.hpp>
75 : :
76 : : using namespace ::com::sun::star;
77 : :
78 : :
79 : : // ------------------------------------------------------------
80 : :
81 : 3141634 : sal_uInt16 GetScriptItemId( sal_uInt16 nItemId, short nScriptType )
82 : : {
83 : 3141634 : sal_uInt16 nId = nItemId;
84 : :
85 [ + + ][ - + ]: 3141634 : if ( ( nScriptType == i18n::ScriptType::ASIAN ) ||
86 : : ( nScriptType == i18n::ScriptType::COMPLEX ) )
87 : : {
88 [ + + + + : 285 : switch ( nItemId )
+ - ]
89 : : {
90 : : case EE_CHAR_LANGUAGE:
91 [ + - ]: 57 : nId = ( nScriptType == i18n::ScriptType::ASIAN ) ? EE_CHAR_LANGUAGE_CJK : EE_CHAR_LANGUAGE_CTL;
92 : 57 : break;
93 : : case EE_CHAR_FONTINFO:
94 [ + - ]: 57 : nId = ( nScriptType == i18n::ScriptType::ASIAN ) ? EE_CHAR_FONTINFO_CJK : EE_CHAR_FONTINFO_CTL;
95 : 57 : break;
96 : : case EE_CHAR_FONTHEIGHT:
97 [ + - ]: 57 : nId = ( nScriptType == i18n::ScriptType::ASIAN ) ? EE_CHAR_FONTHEIGHT_CJK : EE_CHAR_FONTHEIGHT_CTL;
98 : 57 : break;
99 : : case EE_CHAR_WEIGHT:
100 [ + - ]: 57 : nId = ( nScriptType == i18n::ScriptType::ASIAN ) ? EE_CHAR_WEIGHT_CJK : EE_CHAR_WEIGHT_CTL;
101 : 57 : break;
102 : : case EE_CHAR_ITALIC:
103 [ + - ]: 57 : nId = ( nScriptType == i18n::ScriptType::ASIAN ) ? EE_CHAR_ITALIC_CJK : EE_CHAR_ITALIC_CTL;
104 : 57 : break;
105 : : }
106 : : }
107 : :
108 : 3141634 : return nId;
109 : : }
110 : :
111 : 281982 : sal_Bool IsScriptItemValid( sal_uInt16 nItemId, short nScriptType )
112 : : {
113 : 281982 : sal_Bool bValid = sal_True;
114 : :
115 [ + + + + : 281982 : switch ( nItemId )
+ + + + +
+ + + + +
+ + ]
116 : : {
117 : : case EE_CHAR_LANGUAGE:
118 : 9989 : bValid = nScriptType == i18n::ScriptType::LATIN;
119 : 9989 : break;
120 : : case EE_CHAR_LANGUAGE_CJK:
121 : 8473 : bValid = nScriptType == i18n::ScriptType::ASIAN;
122 : 8473 : break;
123 : : case EE_CHAR_LANGUAGE_CTL:
124 : 8042 : bValid = nScriptType == i18n::ScriptType::COMPLEX;
125 : 8042 : break;
126 : : case EE_CHAR_FONTINFO:
127 : 11614 : bValid = nScriptType == i18n::ScriptType::LATIN;
128 : 11614 : break;
129 : : case EE_CHAR_FONTINFO_CJK:
130 : 8692 : bValid = nScriptType == i18n::ScriptType::ASIAN;
131 : 8692 : break;
132 : : case EE_CHAR_FONTINFO_CTL:
133 : 8464 : bValid = nScriptType == i18n::ScriptType::COMPLEX;
134 : 8464 : break;
135 : : case EE_CHAR_FONTHEIGHT:
136 : 11300 : bValid = nScriptType == i18n::ScriptType::LATIN;
137 : 11300 : break;
138 : : case EE_CHAR_FONTHEIGHT_CJK:
139 : 9503 : bValid = nScriptType == i18n::ScriptType::ASIAN;
140 : 9503 : break;
141 : : case EE_CHAR_FONTHEIGHT_CTL:
142 : 7493 : bValid = nScriptType == i18n::ScriptType::COMPLEX;
143 : 7493 : break;
144 : : case EE_CHAR_WEIGHT:
145 : 10730 : bValid = nScriptType == i18n::ScriptType::LATIN;
146 : 10730 : break;
147 : : case EE_CHAR_WEIGHT_CJK:
148 : 8802 : bValid = nScriptType == i18n::ScriptType::ASIAN;
149 : 8802 : break;
150 : : case EE_CHAR_WEIGHT_CTL:
151 : 8531 : bValid = nScriptType == i18n::ScriptType::COMPLEX;
152 : 8531 : break;
153 : : case EE_CHAR_ITALIC:
154 : 10636 : bValid = nScriptType == i18n::ScriptType::LATIN;
155 : 10636 : break;
156 : : case EE_CHAR_ITALIC_CJK:
157 : 8171 : bValid = nScriptType == i18n::ScriptType::ASIAN;
158 : 8171 : break;
159 : : case EE_CHAR_ITALIC_CTL:
160 : 8658 : bValid = nScriptType == i18n::ScriptType::COMPLEX;
161 : 8658 : break;
162 : : }
163 : :
164 : 281982 : return bValid;
165 : : }
166 : :
167 : :
168 : : // ------------------------------------------------------------
169 : :
170 : : // Should later be moved to TOOLS/STRING (Current: 303)
171 : : // for Grep: WS_TARGET
172 : :
173 : : DBG_NAME( EE_TextPortion );
174 : : DBG_NAME( EE_EditLine );
175 : : DBG_NAME( EE_ContentNode );
176 : : DBG_NAME( EE_CharAttribList );
177 : : DBG_NAME( EE_ParaPortion )
178 : :
179 : : const SfxItemInfo aItemInfos[EDITITEMCOUNT] = {
180 : : { SID_ATTR_FRAMEDIRECTION, SFX_ITEM_POOLABLE }, // EE_PARA_WRITINGDIR
181 : : { 0, SFX_ITEM_POOLABLE }, // EE_PARA_XMLATTRIBS
182 : : { SID_ATTR_PARA_HANGPUNCTUATION, SFX_ITEM_POOLABLE }, // EE_PARA_HANGINGPUNCTUATION
183 : : { SID_ATTR_PARA_FORBIDDEN_RULES, SFX_ITEM_POOLABLE },
184 : : { SID_ATTR_PARA_SCRIPTSPACE, SFX_ITEM_POOLABLE }, // EE_PARA_ASIANCJKSPACING
185 : : { SID_ATTR_NUMBERING_RULE, SFX_ITEM_POOLABLE }, // EE_PARA_NUMBULL
186 : : { 0, SFX_ITEM_POOLABLE }, // EE_PARA_HYPHENATE
187 : : { 0, SFX_ITEM_POOLABLE }, // EE_PARA_BULLETSTATE
188 : : { 0, SFX_ITEM_POOLABLE }, // EE_PARA_OUTLLRSPACE
189 : : { SID_ATTR_PARA_OUTLLEVEL, SFX_ITEM_POOLABLE }, // EE_PARA_OUTLLEVEL
190 : : { SID_ATTR_PARA_BULLET, SFX_ITEM_POOLABLE }, // EE_PARA_BULLET
191 : : { SID_ATTR_LRSPACE, SFX_ITEM_POOLABLE }, // EE_PARA_LRSPACE
192 : : { SID_ATTR_ULSPACE, SFX_ITEM_POOLABLE }, // EE_PARA_ULSPACE
193 : : { SID_ATTR_PARA_LINESPACE, SFX_ITEM_POOLABLE }, // EE_PARA_SBL
194 : : { SID_ATTR_PARA_ADJUST, SFX_ITEM_POOLABLE }, // EE_PARA_JUST
195 : : { SID_ATTR_TABSTOP, SFX_ITEM_POOLABLE }, // EE_PARA_TABS
196 : : { SID_ATTR_ALIGN_HOR_JUSTIFY_METHOD, SFX_ITEM_POOLABLE }, // EE_PARA_JUST_METHOD
197 : : { SID_ATTR_ALIGN_VER_JUSTIFY, SFX_ITEM_POOLABLE }, // EE_PARA_VER_JUST
198 : : { SID_ATTR_CHAR_COLOR, SFX_ITEM_POOLABLE },
199 : : { SID_ATTR_CHAR_FONT, SFX_ITEM_POOLABLE },
200 : : { SID_ATTR_CHAR_FONTHEIGHT, SFX_ITEM_POOLABLE },
201 : : { SID_ATTR_CHAR_SCALEWIDTH, SFX_ITEM_POOLABLE },
202 : : { SID_ATTR_CHAR_WEIGHT, SFX_ITEM_POOLABLE },
203 : : { SID_ATTR_CHAR_UNDERLINE, SFX_ITEM_POOLABLE },
204 : : { SID_ATTR_CHAR_STRIKEOUT, SFX_ITEM_POOLABLE },
205 : : { SID_ATTR_CHAR_POSTURE, SFX_ITEM_POOLABLE },
206 : : { SID_ATTR_CHAR_CONTOUR, SFX_ITEM_POOLABLE },
207 : : { SID_ATTR_CHAR_SHADOWED, SFX_ITEM_POOLABLE },
208 : : { SID_ATTR_CHAR_ESCAPEMENT, SFX_ITEM_POOLABLE },
209 : : { SID_ATTR_CHAR_AUTOKERN, SFX_ITEM_POOLABLE },
210 : : { SID_ATTR_CHAR_KERNING, SFX_ITEM_POOLABLE },
211 : : { SID_ATTR_CHAR_WORDLINEMODE, SFX_ITEM_POOLABLE },
212 : : { SID_ATTR_CHAR_LANGUAGE, SFX_ITEM_POOLABLE },
213 : : { SID_ATTR_CHAR_CJK_LANGUAGE, SFX_ITEM_POOLABLE },
214 : : { SID_ATTR_CHAR_CTL_LANGUAGE, SFX_ITEM_POOLABLE },
215 : : { SID_ATTR_CHAR_CJK_FONT, SFX_ITEM_POOLABLE },
216 : : { SID_ATTR_CHAR_CTL_FONT, SFX_ITEM_POOLABLE },
217 : : { SID_ATTR_CHAR_CJK_FONTHEIGHT, SFX_ITEM_POOLABLE },
218 : : { SID_ATTR_CHAR_CTL_FONTHEIGHT, SFX_ITEM_POOLABLE },
219 : : { SID_ATTR_CHAR_CJK_WEIGHT, SFX_ITEM_POOLABLE },
220 : : { SID_ATTR_CHAR_CTL_WEIGHT, SFX_ITEM_POOLABLE },
221 : : { SID_ATTR_CHAR_CJK_POSTURE, SFX_ITEM_POOLABLE },
222 : : { SID_ATTR_CHAR_CTL_POSTURE, SFX_ITEM_POOLABLE },
223 : : { SID_ATTR_CHAR_EMPHASISMARK, SFX_ITEM_POOLABLE },
224 : : { SID_ATTR_CHAR_RELIEF, SFX_ITEM_POOLABLE },
225 : : { 0, SFX_ITEM_POOLABLE }, // EE_CHAR_RUBI_DUMMY
226 : : { 0, SFX_ITEM_POOLABLE }, // EE_CHAR_XMLATTRIBS
227 : : { SID_ATTR_CHAR_OVERLINE, SFX_ITEM_POOLABLE },
228 : : { 0, SFX_ITEM_POOLABLE }, // EE_FEATURE_TAB
229 : : { 0, SFX_ITEM_POOLABLE }, // EE_FEATURE_LINEBR
230 : : { SID_ATTR_CHAR_CHARSETCOLOR, SFX_ITEM_POOLABLE }, // EE_FEATURE_NOTCONV
231 : : { SID_FIELD, SFX_ITEM_POOLABLE }
232 : : };
233 : :
234 : : const sal_uInt16 aV1Map[] = {
235 : : 3999, 4001, 4002, 4003, 4004, 4005, 4006,
236 : : 4007, 4008, 4009, 4010, 4011, 4012, 4013, 4017, 4018, 4019 // MI: 4019?
237 : : };
238 : :
239 : : const sal_uInt16 aV2Map[] = {
240 : : 3999, 4000, 4001, 4002, 4003, 4004, 4005, 4006, 4007, 4008, 4009,
241 : : 4010, 4011, 4012, 4013, 4014, 4015, 4016, 4018, 4019, 4020
242 : : };
243 : :
244 : : const sal_uInt16 aV3Map[] = {
245 : : 3997, 3998, 3999, 4000, 4001, 4002, 4003, 4004, 4005, 4006, 4007,
246 : : 4009, 4010, 4011, 4012, 4013, 4014, 4015, 4016, 4017, 4018, 4019,
247 : : 4020, 4021
248 : : };
249 : :
250 : : const sal_uInt16 aV4Map[] = {
251 : : 3994, 3995, 3996, 3997, 3998, 3999, 4000, 4001, 4002, 4003,
252 : : 4004, 4005, 4006, 4007, 4008, 4009, 4010, 4011, 4012, 4013,
253 : : 4014, 4015, 4016, 4017, 4018,
254 : : /* CJK Items inserted here: EE_CHAR_LANGUAGE - EE_CHAR_XMLATTRIBS */
255 : : 4034, 4035, 4036, 4037
256 : : };
257 : :
258 : : const sal_uInt16 aV5Map[] = {
259 : : 3994, 3995, 3996, 3997, 3998, 3999, 4000, 4001, 4002, 4003,
260 : : 4004, 4005, 4006, 4007, 4008, 4009, 4010, 4011, 4012, 4013,
261 : : 4014, 4015, 4016, 4017, 4018, 4019, 4020, 4021, 4022, 4023,
262 : : 4024, 4025, 4026, 4027, 4028, 4029, 4030, 4031, 4032, 4033,
263 : : /* EE_CHAR_OVERLINE inserted here */
264 : : 4035, 4036, 4037, 4038
265 : : };
266 : :
267 : 109041 : EditCharAttrib* MakeCharAttrib( SfxItemPool& rPool, const SfxPoolItem& rAttr, sal_uInt16 nS, sal_uInt16 nE )
268 : : {
269 : : // Create a new attribute in the pool
270 : 109041 : const SfxPoolItem& rNew = rPool.Put( rAttr );
271 : :
272 : 109041 : EditCharAttrib* pNew = 0;
273 [ + + + + : 109041 : switch( rNew.Which() )
+ + + + +
+ + + + +
+ + + + +
- + + - ]
274 : : {
275 : : case EE_CHAR_LANGUAGE:
276 : : case EE_CHAR_LANGUAGE_CJK:
277 : : case EE_CHAR_LANGUAGE_CTL:
278 : : {
279 [ + - ]: 9709 : pNew = new EditCharAttribLanguage( (const SvxLanguageItem&)rNew, nS, nE );
280 : : }
281 : 9709 : break;
282 : : case EE_CHAR_COLOR:
283 : : {
284 [ + - ]: 4862 : pNew = new EditCharAttribColor( (const SvxColorItem&)rNew, nS, nE );
285 : : }
286 : 4862 : break;
287 : : case EE_CHAR_FONTINFO:
288 : : case EE_CHAR_FONTINFO_CJK:
289 : : case EE_CHAR_FONTINFO_CTL:
290 : : {
291 [ + - ]: 11503 : pNew = new EditCharAttribFont( (const SvxFontItem&)rNew, nS, nE );
292 : : }
293 : 11503 : break;
294 : : case EE_CHAR_FONTHEIGHT:
295 : : case EE_CHAR_FONTHEIGHT_CJK:
296 : : case EE_CHAR_FONTHEIGHT_CTL:
297 : : {
298 [ + - ]: 12254 : pNew = new EditCharAttribFontHeight( (const SvxFontHeightItem&)rNew, nS, nE );
299 : : }
300 : 12254 : break;
301 : : case EE_CHAR_FONTWIDTH:
302 : : {
303 [ + - ]: 2803 : pNew = new EditCharAttribFontWidth( (const SvxCharScaleWidthItem&)rNew, nS, nE );
304 : : }
305 : 2803 : break;
306 : : case EE_CHAR_WEIGHT:
307 : : case EE_CHAR_WEIGHT_CJK:
308 : : case EE_CHAR_WEIGHT_CTL:
309 : : {
310 [ + - ]: 10209 : pNew = new EditCharAttribWeight( (const SvxWeightItem&)rNew, nS, nE );
311 : : }
312 : 10209 : break;
313 : : case EE_CHAR_UNDERLINE:
314 : : {
315 [ + - ]: 4084 : pNew = new EditCharAttribUnderline( (const SvxUnderlineItem&)rNew, nS, nE );
316 : : }
317 : 4084 : break;
318 : : case EE_CHAR_OVERLINE:
319 : : {
320 [ + - ]: 2044 : pNew = new EditCharAttribOverline( (const SvxOverlineItem&)rNew, nS, nE );
321 : : }
322 : 2044 : break;
323 : : case EE_CHAR_EMPHASISMARK:
324 : : {
325 [ + - ]: 2907 : pNew = new EditCharAttribEmphasisMark( (const SvxEmphasisMarkItem&)rNew, nS, nE );
326 : : }
327 : 2907 : break;
328 : : case EE_CHAR_RELIEF:
329 : : {
330 [ + - ]: 2847 : pNew = new EditCharAttribRelief( (const SvxCharReliefItem&)rNew, nS, nE );
331 : : }
332 : 2847 : break;
333 : : case EE_CHAR_STRIKEOUT:
334 : : {
335 [ + - ]: 3895 : pNew = new EditCharAttribStrikeout( (const SvxCrossedOutItem&)rNew, nS, nE );
336 : : }
337 : 3895 : break;
338 : : case EE_CHAR_ITALIC:
339 : : case EE_CHAR_ITALIC_CJK:
340 : : case EE_CHAR_ITALIC_CTL:
341 : : {
342 [ + - ]: 9789 : pNew = new EditCharAttribItalic( (const SvxPostureItem&)rNew, nS, nE );
343 : : }
344 : 9789 : break;
345 : : case EE_CHAR_OUTLINE:
346 : : {
347 [ + - ]: 3579 : pNew = new EditCharAttribOutline( (const SvxContourItem&)rNew, nS, nE );
348 : : }
349 : 3579 : break;
350 : : case EE_CHAR_SHADOW:
351 : : {
352 [ + - ]: 3615 : pNew = new EditCharAttribShadow( (const SvxShadowedItem&)rNew, nS, nE );
353 : : }
354 : 3615 : break;
355 : : case EE_CHAR_ESCAPEMENT:
356 : : {
357 [ + - ]: 3985 : pNew = new EditCharAttribEscapement( (const SvxEscapementItem&)rNew, nS, nE );
358 : : }
359 : 3985 : break;
360 : : case EE_CHAR_PAIRKERNING:
361 : : {
362 [ + - ]: 3141 : pNew = new EditCharAttribPairKerning( (const SvxAutoKernItem&)rNew, nS, nE );
363 : : }
364 : 3141 : break;
365 : : case EE_CHAR_KERNING:
366 : : {
367 [ + - ]: 3081 : pNew = new EditCharAttribKerning( (const SvxKerningItem&)rNew, nS, nE );
368 : : }
369 : 3081 : break;
370 : : case EE_CHAR_WLM:
371 : : {
372 [ + - ]: 3074 : pNew = new EditCharAttribWordLineMode( (const SvxWordLineModeItem&)rNew, nS, nE );
373 : : }
374 : 3074 : break;
375 : : case EE_CHAR_XMLATTRIBS:
376 : : {
377 [ + - ]: 2660 : pNew = new EditCharAttrib( rNew, nS, nE ); // Attribute is only for holding XML information...
378 : : }
379 : 2660 : break;
380 : : case EE_FEATURE_TAB:
381 : : {
382 [ # # ]: 0 : pNew = new EditCharAttribTab( (const SfxVoidItem&)rNew, nS );
383 : : }
384 : 0 : break;
385 : : case EE_FEATURE_LINEBR:
386 : : {
387 [ + - ]: 40 : pNew = new EditCharAttribLineBreak( (const SfxVoidItem&)rNew, nS );
388 : : }
389 : 40 : break;
390 : : case EE_FEATURE_FIELD:
391 : : {
392 [ + - ]: 8960 : pNew = new EditCharAttribField( (const SvxFieldItem&)rNew, nS );
393 : : }
394 : 8960 : break;
395 : : default:
396 : : {
397 : : OSL_FAIL( "Invalid Attribute!" );
398 : : }
399 : : }
400 : 109041 : return pNew;
401 : : }
402 : :
403 : 321088 : TextPortionList::TextPortionList()
404 : : {
405 : 321088 : }
406 : :
407 : 320840 : TextPortionList::~TextPortionList()
408 : : {
409 [ + - ]: 320840 : Reset();
410 : 320840 : }
411 : :
412 : 392876 : void TextPortionList::Reset()
413 : : {
414 : 392876 : maPortions.clear();
415 : 392876 : }
416 : :
417 : 114287 : void TextPortionList::DeleteFromPortion(size_t nDelFrom)
418 : : {
419 : : DBG_ASSERT( ( nDelFrom < maPortions.size() ) || ( (nDelFrom == 0) && maPortions.empty() ), "DeleteFromPortion: Out of range" );
420 [ + - ]: 114287 : PortionsType::iterator it = maPortions.begin();
421 [ + - ]: 114287 : std::advance(it, nDelFrom);
422 [ + - ][ + - ]: 114287 : maPortions.erase(it, maPortions.end());
423 : 114287 : }
424 : :
425 : 1250045 : size_t TextPortionList::Count() const
426 : : {
427 : 1250045 : return maPortions.size();
428 : : }
429 : :
430 : 45207 : const TextPortion* TextPortionList::operator[](size_t nPos) const
431 : : {
432 : 45207 : return &maPortions[nPos];
433 : : }
434 : :
435 : 1584265 : TextPortion* TextPortionList::operator[](size_t nPos)
436 : : {
437 : 1584265 : return &maPortions[nPos];
438 : : }
439 : :
440 : 326274 : void TextPortionList::Append(TextPortion* p)
441 : : {
442 : 326274 : maPortions.push_back(p);
443 : 326274 : }
444 : :
445 : 94441 : void TextPortionList::Insert(size_t nPos, TextPortion* p)
446 : : {
447 : 94441 : maPortions.insert(maPortions.begin()+nPos, p);
448 : 94441 : }
449 : :
450 : 0 : void TextPortionList::Remove(size_t nPos)
451 : : {
452 : 0 : maPortions.erase(maPortions.begin()+nPos);
453 : 0 : }
454 : :
455 : : namespace {
456 : :
457 : : class FindTextPortionByAddress : std::unary_function<TextPortion, bool>
458 : : {
459 : : const TextPortion* mp;
460 : : public:
461 : 0 : FindTextPortionByAddress(const TextPortion* p) : mp(p) {}
462 : 0 : bool operator() (const TextPortion& v) const
463 : : {
464 : 0 : return &v == mp;
465 : : }
466 : : };
467 : :
468 : : }
469 : :
470 : 0 : size_t TextPortionList::GetPos(const TextPortion* p) const
471 : : {
472 : : PortionsType::const_iterator it =
473 [ # # ][ # # ]: 0 : std::find_if(maPortions.begin(), maPortions.end(), FindTextPortionByAddress(p));
[ # # ]
474 : :
475 [ # # ][ # # ]: 0 : if (it == maPortions.end())
[ # # ]
476 : 0 : return std::numeric_limits<size_t>::max(); // not found.
477 : :
478 [ # # ][ # # ]: 0 : return std::distance(maPortions.begin(), it);
479 : : }
480 : :
481 : 1116 : size_t TextPortionList::FindPortion(
482 : : sal_uInt16 nCharPos, sal_uInt16& nPortionStart, bool bPreferStartingPortion) const
483 : : {
484 : : // When nCharPos at portion limit, the left portion is found
485 : 1116 : sal_uInt16 nTmpPos = 0;
486 : 1116 : size_t n = maPortions.size();
487 [ + - ]: 1116 : for (size_t i = 0; i < n; ++i)
488 : : {
489 : 1116 : const TextPortion& rPortion = maPortions[i];
490 : 1116 : nTmpPos = nTmpPos + rPortion.GetLen();
491 [ + - ]: 1116 : if ( nTmpPos >= nCharPos )
492 : : {
493 : : // take this one if we don't prefer the starting portion, or if it's the last one
494 [ + + ][ + + ]: 1116 : if ( ( nTmpPos != nCharPos ) || !bPreferStartingPortion || ( i == n-1 ) )
[ + - ]
495 : : {
496 : 1116 : nPortionStart = nTmpPos - rPortion.GetLen();
497 : 1116 : return i;
498 : : }
499 : : }
500 : : }
501 : : OSL_FAIL( "FindPortion: Not found!" );
502 : 1116 : return n - 1;
503 : : }
504 : :
505 : 0 : sal_uInt16 TextPortionList::GetStartPos(size_t nPortion)
506 : : {
507 : 0 : sal_uInt16 nPos = 0;
508 [ # # ]: 0 : for (size_t i = 0; i < nPortion; ++i)
509 : : {
510 : 0 : const TextPortion& rPortion = maPortions[i];
511 : 0 : nPos = nPos + rPortion.GetLen();
512 : : }
513 : 0 : return nPos;
514 : : }
515 : :
516 : :
517 : 0 : ExtraPortionInfo::ExtraPortionInfo()
518 : : {
519 : 0 : nOrgWidth = 0;
520 : 0 : nWidthFullCompression = 0;
521 : 0 : nMaxCompression100thPercent = 0;
522 : 0 : nAsianCompressionTypes = 0;
523 : 0 : nPortionOffsetX = 0;
524 : 0 : bFirstCharIsRightPunktuation = sal_False;
525 : 0 : bCompressed = sal_False;
526 : 0 : pOrgDXArray = NULL;
527 : 0 : }
528 : :
529 : 0 : ExtraPortionInfo::~ExtraPortionInfo()
530 : : {
531 [ # # ]: 0 : delete[] pOrgDXArray;
532 : 0 : }
533 : :
534 : 0 : void ExtraPortionInfo::SaveOrgDXArray( const sal_Int32* pDXArray, sal_uInt16 nLen )
535 : : {
536 [ # # ]: 0 : delete[] pOrgDXArray;
537 : 0 : pOrgDXArray = new sal_Int32[nLen];
538 : 0 : memcpy( pOrgDXArray, pDXArray, nLen*sizeof(sal_Int32) );
539 : 0 : }
540 : :
541 : :
542 [ + - ][ + - ]: 321088 : ParaPortion::ParaPortion( ContentNode* pN )
[ + - ]
543 : : {
544 : : DBG_CTOR( EE_ParaPortion, 0 );
545 : :
546 : 321088 : pNode = pN;
547 : 321088 : bInvalid = sal_True;
548 : 321088 : bVisible = sal_True;
549 : 321088 : bSimple = sal_False;
550 : 321088 : bForceRepaint = sal_False;
551 : 321088 : nInvalidPosStart = 0;
552 : 321088 : nInvalidDiff = 0;
553 : 321088 : nHeight = 0;
554 : 321088 : nFirstLineOffset = 0;
555 : 321088 : nBulletX = 0;
556 : 321088 : }
557 : :
558 [ + - ]: 320840 : ParaPortion::~ParaPortion()
559 : : {
560 : : DBG_DTOR( EE_ParaPortion, 0 );
561 : 320840 : }
562 : :
563 : 179468 : void ParaPortion::MarkInvalid( sal_uInt16 nStart, short nDiff )
564 : : {
565 [ + + ]: 179468 : if ( bInvalid == sal_False )
566 : : {
567 : : // nInvalidPosEnd = nStart; // ??? => CreateLines
568 [ + + ]: 23106 : nInvalidPosStart = ( nDiff >= 0 ) ? nStart : ( nStart + nDiff );
569 : 23106 : nInvalidDiff = nDiff;
570 : : }
571 : : else
572 : : {
573 : : // Simple tap in succession
574 [ + + ][ + + ]: 156362 : if ( ( nDiff > 0 ) && ( nInvalidDiff > 0 ) &&
[ + + ]
575 : : ( ( nInvalidPosStart+nInvalidDiff ) == nStart ) )
576 : : {
577 : 909 : nInvalidDiff = nInvalidDiff + nDiff;
578 : : }
579 : : // Simple delete in succession
580 [ + + ][ - + ]: 155453 : else if ( ( nDiff < 0 ) && ( nInvalidDiff < 0 ) && ( nInvalidPosStart == nStart ) )
[ # # ]
581 : : {
582 : 0 : nInvalidPosStart = nInvalidPosStart + nDiff;
583 : 0 : nInvalidDiff = nInvalidDiff + nDiff;
584 : : }
585 : : else
586 : : {
587 : : // nInvalidPosEnd = pNode->Len();
588 : : DBG_ASSERT( ( nDiff >= 0 ) || ( (nStart+nDiff) >= 0 ), "MarkInvalid: Diff out of Range" );
589 [ + + ]: 155453 : nInvalidPosStart = Min( nInvalidPosStart, (sal_uInt16) ( nDiff < 0 ? nStart+nDiff : nDiff ) );
590 : 155453 : nInvalidDiff = 0;
591 : 155453 : bSimple = sal_False;
592 : : }
593 : : }
594 : 179468 : bInvalid = sal_True;
595 : 179468 : aScriptInfos.clear();
596 : 179468 : aWritingDirectionInfos.clear();
597 : 179468 : }
598 : :
599 : 586508 : void ParaPortion::MarkSelectionInvalid( sal_uInt16 nStart, sal_uInt16 /* nEnd */ )
600 : : {
601 [ + + ]: 586508 : if ( bInvalid == sal_False )
602 : : {
603 : 85089 : nInvalidPosStart = nStart;
604 : : // nInvalidPosEnd = nEnd;
605 : : }
606 : : else
607 : : {
608 : 501419 : nInvalidPosStart = Min( nInvalidPosStart, nStart );
609 : : // nInvalidPosEnd = pNode->Len();
610 : : }
611 : 586508 : nInvalidDiff = 0;
612 : 586508 : bInvalid = sal_True;
613 : 586508 : bSimple = sal_False;
614 : 586508 : aScriptInfos.clear();
615 : 586508 : aWritingDirectionInfos.clear();
616 : 586508 : }
617 : :
618 : 0 : sal_uInt16 ParaPortion::GetLineNumber( sal_uInt16 nIndex ) const
619 : : {
620 : : DBG_ASSERTWARNING( aLineList.Count(), "Empty ParaPortion in GetLine!" );
621 : : DBG_ASSERT( bVisible, "Why GetLine() on an invisible paragraph?" );
622 : :
623 [ # # ]: 0 : for ( sal_uInt16 nLine = 0; nLine < aLineList.Count(); nLine++ )
624 : : {
625 [ # # ]: 0 : if ( aLineList[nLine]->IsIn( nIndex ) )
626 : 0 : return nLine;
627 : : }
628 : :
629 : : // Then it should be at the end of the last line!
630 : : DBG_ASSERT( nIndex == aLineList[ aLineList.Count() - 1 ]->GetEnd(), "Index dead wrong!" );
631 : 0 : return (aLineList.Count()-1);
632 : : }
633 : :
634 : 0 : void ParaPortion::SetVisible( sal_Bool bMakeVisible )
635 : : {
636 : 0 : bVisible = bMakeVisible;
637 : 0 : }
638 : :
639 : 0 : void ParaPortion::CorrectValuesBehindLastFormattedLine( sal_uInt16 nLastFormattedLine )
640 : : {
641 : 0 : sal_uInt16 nLines = aLineList.Count();
642 : : DBG_ASSERT( nLines, "CorrectPortionNumbersFromLine: Empty Portion?" );
643 [ # # ]: 0 : if ( nLastFormattedLine < ( nLines - 1 ) )
644 : : {
645 : 0 : const EditLine* pLastFormatted = aLineList[ nLastFormattedLine ];
646 : 0 : const EditLine* pUnformatted = aLineList[ nLastFormattedLine+1 ];
647 : 0 : short nPortionDiff = pUnformatted->GetStartPortion() - pLastFormatted->GetEndPortion();
648 : 0 : short nTextDiff = pUnformatted->GetStart() - pLastFormatted->GetEnd();
649 : 0 : nTextDiff++; // LastFormatted->GetEnd() was included => 1 deducted too much!
650 : :
651 : : // The first unformatted must begin exactly one Portion behind the last
652 : : // of the formatted:
653 : : // If the modified line was split into one portion, can
654 : : // nLastEnd > nNextStart!
655 : 0 : int nPDiff = -( nPortionDiff-1 );
656 : 0 : int nTDiff = -( nTextDiff-1 );
657 [ # # ][ # # ]: 0 : if ( nPDiff || nTDiff )
658 : : {
659 [ # # ]: 0 : for ( sal_uInt16 nL = nLastFormattedLine+1; nL < nLines; nL++ )
660 : : {
661 : 0 : EditLine* pLine = aLineList[ nL ];
662 : :
663 : 0 : pLine->GetStartPortion() = sal::static_int_cast< sal_uInt16 >(
664 : 0 : pLine->GetStartPortion() + nPDiff);
665 : 0 : pLine->GetEndPortion() = sal::static_int_cast< sal_uInt16 >(
666 : 0 : pLine->GetEndPortion() + nPDiff);
667 : :
668 : 0 : pLine->GetStart() = sal::static_int_cast< sal_uInt16 >(
669 : 0 : pLine->GetStart() + nTDiff);
670 : 0 : pLine->GetEnd() = sal::static_int_cast< sal_uInt16 >(
671 : 0 : pLine->GetEnd() + nTDiff);
672 : :
673 : 0 : pLine->SetValid();
674 : : }
675 : : }
676 : : }
677 : : DBG_ASSERT( aLineList[ aLineList.Count()-1 ]->GetEnd() == pNode->Len(), "CorrectLines: The end is not right!" );
678 : 0 : }
679 : :
680 : : // Shared reverse lookup acceleration pieces ...
681 : :
682 : : namespace {
683 : :
684 : : template<typename _Array, typename _Val>
685 : 4150289 : size_t FastGetPos(const _Array& rArray, const _Val* p, size_t& rLastPos)
686 : : {
687 : 4150289 : size_t nArrayLen = rArray.size();
688 : :
689 : : // Through certain filter code-paths we do a lot of appends, which in
690 : : // turn call GetPos - creating some N^2 nightmares. If we have a
691 : : // non-trivially large list, do a few checks from the end first.
692 [ # # - + ]: 4150289 : if (rLastPos > 16 && nArrayLen > 16)
[ # # ][ - + ]
693 : : {
694 : : size_t nEnd;
695 [ # # ][ # # ]: 0 : if (rLastPos > nArrayLen - 2)
696 : 0 : nEnd = nArrayLen;
697 : : else
698 : 0 : nEnd = rLastPos + 2;
699 : :
700 [ # # ][ # # ]: 0 : for (size_t nIdx = rLastPos - 2; nIdx < nEnd; ++nIdx)
701 : : {
702 [ # # ][ # # ]: 0 : if (&rArray.at(nIdx) == p)
703 : : {
704 : 0 : rLastPos = nIdx;
705 : 0 : return nIdx;
706 : : }
707 : : }
708 : : }
709 : : // The world's lamest linear search from svarray ...
710 [ + - ][ + - ]: 4551612 : for (size_t nIdx = 0; nIdx < nArrayLen; ++nIdx)
711 [ + + ][ + + ]: 4551612 : if (&rArray.at(nIdx) == p)
712 : 4150289 : return rLastPos = nIdx;
713 : :
714 : : // 0xFFFF is used to signify "not found" condition. We need to change this.
715 : 4150289 : return std::numeric_limits<sal_uInt16>::max();
716 : : }
717 : :
718 : : }
719 : :
720 : 30636 : ParaPortionList::ParaPortionList() : nLastCache( 0 )
721 : : {
722 : 30636 : }
723 : :
724 : 30388 : ParaPortionList::~ParaPortionList()
725 : : {
726 : 30388 : }
727 : :
728 : 861815 : sal_uInt16 ParaPortionList::GetPos(const ParaPortion* p) const
729 : : {
730 : 861815 : return FastGetPos(maPortions, p, nLastCache);
731 : : }
732 : :
733 : 2137625 : ParaPortion* ParaPortionList::operator [](size_t nPos)
734 : : {
735 [ + - ]: 2137625 : return nPos < maPortions.size() ? &maPortions[nPos] : NULL;
736 : : }
737 : :
738 : 117 : const ParaPortion* ParaPortionList::operator [](size_t nPos) const
739 : : {
740 [ + - ]: 117 : return nPos < maPortions.size() ? &maPortions[nPos] : NULL;
741 : : }
742 : :
743 : 0 : ParaPortion* ParaPortionList::Release(size_t nPos)
744 : : {
745 [ # # ]: 0 : return maPortions.release(maPortions.begin()+nPos).release();
746 : : }
747 : :
748 : 822 : void ParaPortionList::Remove(size_t nPos)
749 : : {
750 : 822 : maPortions.erase(maPortions.begin()+nPos);
751 : 822 : }
752 : :
753 : 321088 : void ParaPortionList::Insert(size_t nPos, ParaPortion* p)
754 : : {
755 : 321088 : maPortions.insert(maPortions.begin()+nPos, p);
756 : 321088 : }
757 : :
758 : 0 : void ParaPortionList::Append(ParaPortion* p)
759 : : {
760 : 0 : maPortions.push_back(p);
761 : 0 : }
762 : :
763 : 2204962 : size_t ParaPortionList::Count() const
764 : : {
765 : 2204962 : return maPortions.size();
766 : : }
767 : :
768 : 309596 : void ParaPortionList::Reset()
769 : : {
770 : 309596 : maPortions.clear();
771 : 309596 : }
772 : :
773 : 203 : long ParaPortionList::GetYOffset(const ParaPortion* pPPortion) const
774 : : {
775 : 203 : long nHeight = 0;
776 [ + - ]: 203 : for (size_t i = 0, n = maPortions.size(); i < n; ++i)
777 : : {
778 : 203 : const ParaPortion* pTmpPortion = &maPortions[i];
779 [ + - ]: 203 : if ( pTmpPortion == pPPortion )
780 : 203 : return nHeight;
781 : 0 : nHeight += pTmpPortion->GetHeight();
782 : : }
783 : : OSL_FAIL( "GetYOffset: Portion not found" );
784 : 203 : return nHeight;
785 : : }
786 : :
787 : 0 : sal_uInt16 ParaPortionList::FindParagraph(long nYOffset) const
788 : : {
789 : 0 : long nY = 0;
790 [ # # ]: 0 : for (size_t i = 0, n = maPortions.size(); i < n; ++i)
791 : : {
792 : 0 : nY += maPortions[i].GetHeight(); // should also be correct even in bVisible!
793 [ # # ]: 0 : if ( nY > nYOffset )
794 : 0 : return i;
795 : : }
796 : 0 : return EE_PARA_NOT_FOUND;
797 : : }
798 : :
799 : 1079969 : const ParaPortion* ParaPortionList::SafeGetObject(size_t nPos) const
800 : : {
801 [ + - ]: 1079969 : return nPos < maPortions.size() ? &maPortions[nPos] : NULL;
802 : : }
803 : :
804 : 1003351 : ParaPortion* ParaPortionList::SafeGetObject(size_t nPos)
805 : : {
806 [ + + ]: 1003351 : return nPos < maPortions.size() ? &maPortions[nPos] : NULL;
807 : : }
808 : :
809 : : #if OSL_DEBUG_LEVEL > 2
810 : : void ParaPortionList::DbgCheck( EditDoc& rDoc)
811 : : {
812 : : DBG_ASSERT( Count() == rDoc.Count(), "ParaPortionList::DbgCheck() - Count() unequal!" );
813 : : for ( sal_uInt16 i = 0; i < Count(); i++ )
814 : : {
815 : : DBG_ASSERT( SafeGetObject(i), "ParaPortionList::DbgCheck() - Null-Pointer in List!" );
816 : : DBG_ASSERT( GetObject(i)->GetNode(), "ParaPortionList::DbgCheck() - Null-Pointer in List(2)!" );
817 : : DBG_ASSERT( GetObject(i)->GetNode() == rDoc.GetObject(i), "ParaPortionList::DbgCheck() - Entries intersect!" );
818 : : }
819 : : }
820 : : #endif
821 : :
822 : 2420 : ContentAttribsInfo::ContentAttribsInfo( const SfxItemSet& rParaAttribs ) :
823 [ + - ]: 2420 : aPrevParaAttribs( rParaAttribs)
824 : : {
825 : 2420 : }
826 : :
827 : 2420 : void ContentAttribsInfo::RemoveAllCharAttribsFromPool(SfxItemPool& rPool) const
828 : : {
829 [ + - ][ + - ]: 2420 : CharAttribsType::const_iterator it = aPrevCharAttribs.begin(), itEnd = aPrevCharAttribs.end();
830 [ + - ][ + - ]: 20972 : for (; it != itEnd; ++it)
[ + + ]
831 [ + - ][ + - ]: 18552 : rPool.Remove(*it->GetItem());
832 : 2420 : }
833 : :
834 : 18552 : void ContentAttribsInfo::AppendCharAttrib(EditCharAttrib* pNew)
835 : : {
836 : 18552 : aPrevCharAttribs.push_back(pNew);
837 : 18552 : }
838 : :
839 : 0 : void ConvertItem( SfxPoolItem& rPoolItem, MapUnit eSourceUnit, MapUnit eDestUnit )
840 : : {
841 : : DBG_ASSERT( eSourceUnit != eDestUnit, "ConvertItem - Why?!" );
842 : :
843 [ # # # # : 0 : switch ( rPoolItem.Which() )
# # ]
844 : : {
845 : : case EE_PARA_LRSPACE:
846 : : {
847 : : DBG_ASSERT( rPoolItem.IsA( TYPE( SvxLRSpaceItem ) ), "ConvertItem: invalid Item!" );
848 : 0 : SvxLRSpaceItem& rItem = (SvxLRSpaceItem&)rPoolItem;
849 : 0 : rItem.SetTxtFirstLineOfst( sal::static_int_cast< short >( OutputDevice::LogicToLogic( rItem.GetTxtFirstLineOfst(), eSourceUnit, eDestUnit ) ) );
850 : 0 : rItem.SetTxtLeft( OutputDevice::LogicToLogic( rItem.GetTxtLeft(), eSourceUnit, eDestUnit ) );
851 : 0 : rItem.SetRight( OutputDevice::LogicToLogic( rItem.GetRight(), eSourceUnit, eDestUnit ) );
852 : : }
853 : 0 : break;
854 : : case EE_PARA_ULSPACE:
855 : : {
856 : : DBG_ASSERT( rPoolItem.IsA( TYPE( SvxULSpaceItem ) ), "ConvertItem: Invalid Item!" );
857 : 0 : SvxULSpaceItem& rItem = (SvxULSpaceItem&)rPoolItem;
858 : 0 : rItem.SetUpper( sal::static_int_cast< sal_uInt16 >( OutputDevice::LogicToLogic( rItem.GetUpper(), eSourceUnit, eDestUnit ) ) );
859 : 0 : rItem.SetLower( sal::static_int_cast< sal_uInt16 >( OutputDevice::LogicToLogic( rItem.GetLower(), eSourceUnit, eDestUnit ) ) );
860 : : }
861 : 0 : break;
862 : : case EE_PARA_SBL:
863 : : {
864 : : DBG_ASSERT( rPoolItem.IsA( TYPE( SvxLineSpacingItem ) ), "ConvertItem: Invalid Item!" );
865 : 0 : SvxLineSpacingItem& rItem = (SvxLineSpacingItem&)rPoolItem;
866 : : // SetLineHeight changes also eLineSpace!
867 [ # # ]: 0 : if ( rItem.GetLineSpaceRule() == SVX_LINE_SPACE_MIN )
868 : 0 : rItem.SetLineHeight( sal::static_int_cast< sal_uInt16 >( OutputDevice::LogicToLogic( rItem.GetLineHeight(), eSourceUnit, eDestUnit ) ) );
869 : : }
870 : 0 : break;
871 : : case EE_PARA_TABS:
872 : : {
873 : : DBG_ASSERT( rPoolItem.IsA( TYPE( SvxTabStopItem ) ), "ConvertItem: Invalid Item!" );
874 : 0 : SvxTabStopItem& rItem = (SvxTabStopItem&)rPoolItem;
875 [ # # ]: 0 : SvxTabStopItem aNewItem( EE_PARA_TABS );
876 [ # # ]: 0 : for ( sal_uInt16 i = 0; i < rItem.Count(); i++ )
877 : : {
878 [ # # ]: 0 : const SvxTabStop& rTab = rItem[i];
879 [ # # ][ # # ]: 0 : SvxTabStop aNewStop( OutputDevice::LogicToLogic( rTab.GetTabPos(), eSourceUnit, eDestUnit ), rTab.GetAdjustment(), rTab.GetDecimal(), rTab.GetFill() );
[ # # ]
880 [ # # ]: 0 : aNewItem.Insert( aNewStop );
881 : : }
882 [ # # ][ # # ]: 0 : rItem = aNewItem;
883 : : }
884 : 0 : break;
885 : : case EE_CHAR_FONTHEIGHT:
886 : : case EE_CHAR_FONTHEIGHT_CJK:
887 : : case EE_CHAR_FONTHEIGHT_CTL:
888 : : {
889 : : DBG_ASSERT( rPoolItem.IsA( TYPE( SvxFontHeightItem ) ), "ConvertItem: Invalid Item!" );
890 : 0 : SvxFontHeightItem& rItem = (SvxFontHeightItem&)rPoolItem;
891 : 0 : rItem.SetHeight( OutputDevice::LogicToLogic( rItem.GetHeight(), eSourceUnit, eDestUnit ) );
892 : : }
893 : 0 : break;
894 : : }
895 : 0 : }
896 : :
897 : 0 : void ConvertAndPutItems( SfxItemSet& rDest, const SfxItemSet& rSource, const MapUnit* pSourceUnit, const MapUnit* pDestUnit )
898 : : {
899 : 0 : const SfxItemPool* pSourcePool = rSource.GetPool();
900 : 0 : const SfxItemPool* pDestPool = rDest.GetPool();
901 : :
902 [ # # ]: 0 : for ( sal_uInt16 nWhich = EE_PARA_START; nWhich <= EE_CHAR_END; nWhich++ )
903 : : {
904 : : // If possible go through SlotID ...
905 : :
906 : 0 : sal_uInt16 nSourceWhich = nWhich;
907 : 0 : sal_uInt16 nSlot = pDestPool->GetTrueSlotId( nWhich );
908 [ # # ]: 0 : if ( nSlot )
909 : : {
910 : 0 : sal_uInt16 nW = pSourcePool->GetTrueWhich( nSlot );
911 [ # # ]: 0 : if ( nW )
912 : 0 : nSourceWhich = nW;
913 : : }
914 : :
915 [ # # ]: 0 : if ( rSource.GetItemState( nSourceWhich, sal_False ) == SFX_ITEM_ON )
916 : : {
917 [ # # ]: 0 : MapUnit eSourceUnit = pSourceUnit ? *pSourceUnit : (MapUnit)pSourcePool->GetMetric( nSourceWhich );
918 [ # # ]: 0 : MapUnit eDestUnit = pDestUnit ? *pDestUnit : (MapUnit)pDestPool->GetMetric( nWhich );
919 [ # # ]: 0 : if ( eSourceUnit != eDestUnit )
920 : : {
921 : 0 : SfxPoolItem* pItem = rSource.Get( nSourceWhich ).Clone();
922 : : // pItem->SetWhich( nWhich );
923 : 0 : ConvertItem( *pItem, eSourceUnit, eDestUnit );
924 : 0 : rDest.Put( *pItem, nWhich );
925 [ # # ]: 0 : delete pItem;
926 : : }
927 : : else
928 : : {
929 : 0 : rDest.Put( rSource.Get( nSourceWhich ), nWhich );
930 : : }
931 : : }
932 : : }
933 : 0 : }
934 : :
935 : 414995 : EditLine::EditLine() :
936 : : bHangingPunctuation(false),
937 : 414995 : bInvalid(true)
938 : : {
939 : : DBG_CTOR( EE_EditLine, 0 );
940 : :
941 : 414995 : nStart = nEnd = 0;
942 : 414995 : nStartPortion = 0; // to be able to tell the difference between a line
943 : : // without Ptorions form one with the Portion number 0
944 : 414995 : nEndPortion = 0;
945 : 414995 : nHeight = 0;
946 : 414995 : nStartPosX = 0;
947 : 414995 : nTxtHeight = 0;
948 : 414995 : nTxtWidth = 0;
949 : 414995 : nCrsrHeight = 0;
950 : 414995 : nMaxAscent = 0;
951 : 414995 : }
952 : :
953 : 114343 : EditLine::EditLine( const EditLine& r ) :
954 : : bHangingPunctuation(r.bHangingPunctuation),
955 : 114343 : bInvalid(true)
956 : : {
957 : : DBG_CTOR( EE_EditLine, 0 );
958 : :
959 : 114343 : nEnd = r.nEnd;
960 : 114343 : nStart = r.nStart;
961 : 114343 : nStartPortion = r.nStartPortion;
962 : 114343 : nEndPortion = r.nEndPortion;
963 : :
964 : 114343 : nHeight = 0;
965 : 114343 : nStartPosX = 0;
966 : 114343 : nTxtHeight = 0;
967 : 114343 : nTxtWidth = 0;
968 : 114343 : nCrsrHeight = 0;
969 : 114343 : nMaxAscent = 0;
970 : 114343 : }
971 : :
972 : 529123 : EditLine::~EditLine()
973 : : {
974 : : DBG_DTOR( EE_EditLine, 0 );
975 : 529123 : }
976 : :
977 : 901370 : EditLine::CharPosArrayType& EditLine::GetCharPosArray()
978 : : {
979 : 901370 : return aPositions;
980 : : }
981 : :
982 : 39186 : const EditLine::CharPosArrayType& EditLine::GetCharPosArray() const
983 : : {
984 : 39186 : return aPositions;
985 : : }
986 : :
987 : 0 : EditLine* EditLine::Clone() const
988 : : {
989 [ # # ]: 0 : EditLine* pL = new EditLine;
990 : 0 : pL->aPositions = aPositions;
991 : 0 : pL->nStartPosX = nStartPosX;
992 : 0 : pL->nStart = nStart;
993 : 0 : pL->nEnd = nEnd;
994 : 0 : pL->nStartPortion = nStartPortion;
995 : 0 : pL->nEndPortion = nEndPortion;
996 : 0 : pL->nHeight = nHeight;
997 : 0 : pL->nTxtWidth = nTxtWidth;
998 : 0 : pL->nTxtHeight = nTxtHeight;
999 : 0 : pL->nCrsrHeight = nCrsrHeight;
1000 : 0 : pL->nMaxAscent = nMaxAscent;
1001 : :
1002 : 0 : return pL;
1003 : : }
1004 : :
1005 : 0 : sal_Bool operator == ( const EditLine& r1, const EditLine& r2 )
1006 : : {
1007 [ # # ]: 0 : if ( r1.nStart != r2.nStart )
1008 : 0 : return sal_False;
1009 : :
1010 [ # # ]: 0 : if ( r1.nEnd != r2.nEnd )
1011 : 0 : return sal_False;
1012 : :
1013 [ # # ]: 0 : if ( r1.nStartPortion != r2.nStartPortion )
1014 : 0 : return sal_False;
1015 : :
1016 [ # # ]: 0 : if ( r1.nEndPortion != r2.nEndPortion )
1017 : 0 : return sal_False;
1018 : :
1019 : 0 : return sal_True;
1020 : : }
1021 : :
1022 : 94211 : EditLine& EditLine::operator = ( const EditLine& r )
1023 : : {
1024 : 94211 : nEnd = r.nEnd;
1025 : 94211 : nStart = r.nStart;
1026 : 94211 : nEndPortion = r.nEndPortion;
1027 : 94211 : nStartPortion = r.nStartPortion;
1028 : 94211 : return *this;
1029 : : }
1030 : :
1031 : :
1032 : 0 : sal_Bool operator != ( const EditLine& r1, const EditLine& r2 )
1033 : : {
1034 : 0 : return !( r1 == r2 );
1035 : : }
1036 : :
1037 : 208554 : Size EditLine::CalcTextSize( ParaPortion& rParaPortion )
1038 : : {
1039 : 208554 : Size aSz;
1040 : 208554 : Size aTmpSz;
1041 : : TextPortion* pPortion;
1042 : :
1043 : 208554 : sal_uInt16 nIndex = GetStart();
1044 : :
1045 : : DBG_ASSERT( rParaPortion.GetTextPortions().Count(), "GetTextSize before CreatePortions !" );
1046 : :
1047 [ + + ]: 419068 : for ( sal_uInt16 n = nStartPortion; n <= nEndPortion; n++ )
1048 : : {
1049 [ + - ]: 210514 : pPortion = rParaPortion.GetTextPortions()[n];
1050 [ + - + ]: 210514 : switch ( pPortion->GetKind() )
1051 : : {
1052 : : case PORTIONKIND_TEXT:
1053 : : case PORTIONKIND_FIELD:
1054 : : case PORTIONKIND_HYPHENATOR:
1055 : : {
1056 : 210483 : aTmpSz = pPortion->GetSize();
1057 : 210483 : aSz.Width() += aTmpSz.Width();
1058 [ + + ]: 210483 : if ( aSz.Height() < aTmpSz.Height() )
1059 : 208537 : aSz.Height() = aTmpSz.Height();
1060 : : }
1061 : 210483 : break;
1062 : : case PORTIONKIND_TAB:
1063 : : {
1064 : 0 : aSz.Width() += pPortion->GetSize().Width();
1065 : : }
1066 : 0 : break;
1067 : : }
1068 : 210514 : nIndex = nIndex + pPortion->GetLen();
1069 : : }
1070 : :
1071 : 208554 : SetHeight( (sal_uInt16)aSz.Height() );
1072 : 208554 : return aSz;
1073 : : }
1074 : :
1075 : 321088 : EditLineList::EditLineList()
1076 : : {
1077 : 321088 : }
1078 : :
1079 : 320840 : EditLineList::~EditLineList()
1080 : : {
1081 [ + - ]: 320840 : Reset();
1082 : 320840 : }
1083 : :
1084 : 392876 : void EditLineList::Reset()
1085 : : {
1086 : 392876 : maLines.clear();
1087 : 392876 : }
1088 : :
1089 : 2 : void EditLineList::DeleteFromLine(size_t nDelFrom)
1090 : : {
1091 : : DBG_ASSERT( nDelFrom <= (maLines.size() - 1), "DeleteFromLine: Out of range" );
1092 [ + - ]: 2 : LinesType::iterator it = maLines.begin();
1093 [ + - ]: 2 : std::advance(it, nDelFrom);
1094 [ + - ][ + - ]: 2 : maLines.erase(it, maLines.end());
1095 : 2 : }
1096 : :
1097 : 0 : size_t EditLineList::FindLine(sal_uInt16 nChar, bool bInclEnd)
1098 : : {
1099 : 0 : size_t n = maLines.size();
1100 [ # # ]: 0 : for (size_t i = 0; i < n; ++i)
1101 : : {
1102 : 0 : const EditLine& rLine = maLines[i];
1103 [ # # # # ]: 0 : if ( (bInclEnd && (rLine.GetEnd() >= nChar)) ||
[ # # ][ # # ]
1104 : 0 : (rLine.GetEnd() > nChar) )
1105 : : {
1106 : 0 : return i;
1107 : : }
1108 : : }
1109 : :
1110 : : DBG_ASSERT( !bInclEnd, "Line not found: FindLine" );
1111 : 0 : return n - 1;
1112 : : }
1113 : :
1114 : 3169910 : size_t EditLineList::Count() const
1115 : : {
1116 : 3169910 : return maLines.size();
1117 : : }
1118 : :
1119 : 22523 : const EditLine* EditLineList::operator[](size_t nPos) const
1120 : : {
1121 : 22523 : return &maLines[nPos];
1122 : : }
1123 : :
1124 : 1464576 : EditLine* EditLineList::operator[](size_t nPos)
1125 : : {
1126 : 1464576 : return &maLines[nPos];
1127 : : }
1128 : :
1129 : 320816 : void EditLineList::Append(EditLine* p)
1130 : : {
1131 : 320816 : maLines.push_back(p);
1132 : 320816 : }
1133 : :
1134 : 94179 : void EditLineList::Insert(size_t nPos, EditLine* p)
1135 : : {
1136 : 94179 : maLines.insert(maLines.begin()+nPos, p);
1137 : 94179 : }
1138 : :
1139 : 1816061 : EditPaM::EditPaM() : pNode(NULL), nIndex(0) {}
1140 : 1433845 : EditPaM::EditPaM(const EditPaM& r) : pNode(r.pNode), nIndex(r.nIndex) {}
1141 : 1948038 : EditPaM::EditPaM(ContentNode* p, sal_uInt16 n) : pNode(p), nIndex(n) {}
1142 : :
1143 : 2481139 : const ContentNode* EditPaM::GetNode() const
1144 : : {
1145 : 2481139 : return pNode;
1146 : : }
1147 : :
1148 : 2420198 : ContentNode* EditPaM::GetNode()
1149 : : {
1150 : 2420198 : return pNode;
1151 : : }
1152 : :
1153 : 81812 : void EditPaM::SetNode(ContentNode* p)
1154 : : {
1155 : 81812 : pNode = p;
1156 : 81812 : }
1157 : :
1158 : 0 : sal_Bool EditPaM::DbgIsBuggy( EditDoc& rDoc )
1159 : : {
1160 [ # # ]: 0 : if ( !pNode )
1161 : 0 : return sal_True;
1162 [ # # ]: 0 : if ( rDoc.GetPos( pNode ) >= rDoc.Count() )
1163 : 0 : return sal_True;
1164 [ # # ]: 0 : if ( nIndex > pNode->Len() )
1165 : 0 : return sal_True;
1166 : :
1167 : 0 : return sal_False;
1168 : : }
1169 : :
1170 : 0 : sal_Bool EditSelection::DbgIsBuggy( EditDoc& rDoc )
1171 : : {
1172 [ # # ]: 0 : if ( aStartPaM.DbgIsBuggy( rDoc ) )
1173 : 0 : return sal_True;
1174 [ # # ]: 0 : if ( aEndPaM.DbgIsBuggy( rDoc ) )
1175 : 0 : return sal_True;
1176 : :
1177 : 0 : return sal_False;
1178 : : }
1179 : :
1180 : 158375 : EditSelection::EditSelection()
1181 : : {
1182 : 158375 : }
1183 : :
1184 : 140367 : EditSelection::EditSelection( const EditPaM& rStartAndAnd )
1185 : : {
1186 : : // could still be optimized!
1187 : : // do no first call the Def-constructor from PaM!
1188 : 140367 : aStartPaM = rStartAndAnd;
1189 : 140367 : aEndPaM = rStartAndAnd;
1190 : 140367 : }
1191 : :
1192 : 577679 : EditSelection::EditSelection( const EditPaM& rStart, const EditPaM& rEnd )
1193 : : {
1194 : : // could still be optimized!
1195 : 577679 : aStartPaM = rStart;
1196 : 577679 : aEndPaM = rEnd;
1197 : 577679 : }
1198 : :
1199 : 3665 : EditSelection& EditSelection::operator = ( const EditPaM& rPaM )
1200 : : {
1201 : 3665 : aStartPaM = rPaM;
1202 : 3665 : aEndPaM = rPaM;
1203 : 3665 : return *this;
1204 : : }
1205 : :
1206 : 0 : sal_Bool EditSelection::IsInvalid() const
1207 : : {
1208 : 0 : EditPaM aEmptyPaM;
1209 : :
1210 [ # # ]: 0 : if ( aStartPaM == aEmptyPaM )
1211 : 0 : return sal_True;
1212 : :
1213 [ # # ]: 0 : if ( aEndPaM == aEmptyPaM )
1214 : 0 : return sal_True;
1215 : :
1216 : 0 : return sal_False;
1217 : : }
1218 : :
1219 : 274080 : sal_Bool EditSelection::Adjust( const EditDoc& rNodes )
1220 : : {
1221 : : DBG_ASSERT( aStartPaM.GetIndex() <= aStartPaM.GetNode()->Len(), "Index out of range in Adjust(1)" );
1222 : : DBG_ASSERT( aEndPaM.GetIndex() <= aEndPaM.GetNode()->Len(), "Index out of range in Adjust(2)" );
1223 : :
1224 : 274080 : const ContentNode* pStartNode = aStartPaM.GetNode();
1225 : 274080 : const ContentNode* pEndNode = aEndPaM.GetNode();
1226 : :
1227 : 274080 : sal_uInt16 nStartNode = rNodes.GetPos( pStartNode );
1228 : 274080 : sal_uInt16 nEndNode = rNodes.GetPos( pEndNode );
1229 : :
1230 : : DBG_ASSERT( nStartNode != USHRT_MAX, "Node out of range in Adjust(1)" );
1231 : : DBG_ASSERT( nEndNode != USHRT_MAX, "Node out of range in Adjust(2)" );
1232 : :
1233 : 274080 : sal_Bool bSwap = sal_False;
1234 [ - + ]: 274080 : if ( nStartNode > nEndNode )
1235 : 0 : bSwap = sal_True;
1236 [ + + ][ - + ]: 274080 : else if ( ( nStartNode == nEndNode ) && ( aStartPaM.GetIndex() > aEndPaM.GetIndex() ) )
[ - + ]
1237 : 0 : bSwap = sal_True;
1238 : :
1239 [ - + ]: 274080 : if ( bSwap )
1240 : : {
1241 : 0 : EditPaM aTmpPaM( aStartPaM );
1242 : 0 : aStartPaM = aEndPaM;
1243 : 0 : aEndPaM = aTmpPaM;
1244 : : }
1245 : :
1246 : 274080 : return bSwap;
1247 : : }
1248 : :
1249 : 199705 : sal_Bool operator == ( const EditPaM& r1, const EditPaM& r2 )
1250 : : {
1251 [ + + ]: 199705 : if ( r1.GetNode() != r2.GetNode() )
1252 : 1320 : return sal_False;
1253 : :
1254 [ + + ]: 198385 : if ( r1.GetIndex() != r2.GetIndex() )
1255 : 3952 : return sal_False;
1256 : :
1257 : 199705 : return sal_True;
1258 : : }
1259 : :
1260 : 2116431 : EditPaM& EditPaM::operator = ( const EditPaM& rPaM )
1261 : : {
1262 : 2116431 : nIndex = rPaM.nIndex;
1263 : 2116431 : pNode = rPaM.pNode;
1264 : 2116431 : return *this;
1265 : : }
1266 : :
1267 : 199705 : sal_Bool operator != ( const EditPaM& r1, const EditPaM& r2 )
1268 : : {
1269 : 199705 : return !( r1 == r2 );
1270 : : }
1271 : :
1272 [ + - ][ + - ]: 319256 : ContentNode::ContentNode( SfxItemPool& rPool ) : aContentAttribs( rPool )
[ + - ]
1273 : : {
1274 : : DBG_CTOR( EE_ContentNode, 0 );
1275 : 319256 : pWrongList = NULL;
1276 : 319256 : }
1277 : :
1278 : 1832 : ContentNode::ContentNode( const XubString& rStr, const ContentAttribs& rContentAttribs ) :
1279 [ + - ][ + - ]: 1832 : maString(rStr), aContentAttribs(rContentAttribs)
[ + - ]
1280 : : {
1281 : : DBG_CTOR( EE_ContentNode, 0 );
1282 : 1832 : pWrongList = NULL;
1283 : 1832 : }
1284 : :
1285 [ + - ][ + - ]: 320840 : ContentNode::~ContentNode()
[ + - ]
1286 : : {
1287 : : DBG_DTOR( EE_ContentNode, 0 );
1288 [ + + ][ + - ]: 320840 : delete pWrongList;
1289 : 320840 : }
1290 : :
1291 : 177408 : void ContentNode::ExpandAttribs( sal_uInt16 nIndex, sal_uInt16 nNew, SfxItemPool& rItemPool )
1292 : : {
1293 [ + + ]: 177408 : if ( !nNew )
1294 : 177408 : return;
1295 : :
1296 : : // Since features are treated differently than normal character attributes,
1297 : : // can also the order of the start list be change!
1298 : : // In every if ..., in the next (n) opportunities due to bFeature or
1299 : : // an existing special case, must (n-1) opportunities be provided with
1300 : : // bResort. The most likely possibility receives no bResort, so that is
1301 : : // not sorted anew when all attributes are the same.
1302 : 172670 : bool bResort = false;
1303 : 172670 : bool bExpandedEmptyAtIndexNull = false;
1304 : :
1305 : 172670 : size_t nAttr = 0;
1306 : 172670 : CharAttribList::AttribsType& rAttribs = aCharAttribList.GetAttribs();
1307 : 172670 : EditCharAttrib* pAttrib = GetAttrib(rAttribs, nAttr);
1308 [ + + ]: 175639 : while ( pAttrib )
1309 : : {
1310 [ + + ]: 2969 : if ( pAttrib->GetEnd() >= nIndex )
1311 : : {
1312 : : // Move all attributes behind the insertion point...
1313 [ + + ]: 2588 : if ( pAttrib->GetStart() > nIndex )
1314 : : {
1315 : 1236 : pAttrib->MoveForward( nNew );
1316 : : }
1317 : : // 0: Expand empty attribute, if at insertion point
1318 [ + + ]: 1352 : else if ( pAttrib->IsEmpty() )
1319 : : {
1320 : : // Do not check Index, a emty one could only be there
1321 : : // When later checking it anyhow:
1322 : : // Special caase: Start == 0; AbsLen == 1, nNew = 1
1323 : : // => Expand, because of paragraph break!
1324 : : // Start <= nIndex, End >= nIndex => Start=End=nIndex!
1325 : : // if ( pAttrib->GetStart() == nIndex )
1326 : 720 : pAttrib->Expand( nNew );
1327 [ + + ]: 720 : if ( pAttrib->GetStart() == 0 )
1328 : 696 : bExpandedEmptyAtIndexNull = sal_True;
1329 : : }
1330 : : // 1: Attribute starts before, goes to index ...
1331 [ + + ]: 632 : else if ( pAttrib->GetEnd() == nIndex ) // Start must be before
1332 : : {
1333 : : // Only expand when there is no feature
1334 : : // and if not in exclude list!
1335 : : // Otherwise, a UL will go on until a new ULDB, expaning both
1336 : : // if ( !pAttrib->IsFeature() && !rExclList.FindAttrib( pAttrib->Which() ) )
1337 [ + + ][ + + ]: 629 : if ( !pAttrib->IsFeature() && !aCharAttribList.FindEmptyAttrib( pAttrib->Which(), nIndex ) )
[ + + ]
1338 : : {
1339 [ + - ]: 228 : if ( !pAttrib->IsEdge() )
1340 : 228 : pAttrib->Expand( nNew );
1341 : : }
1342 : : else
1343 : 401 : bResort = sal_True;
1344 : : }
1345 : : // 2: Attribute starts before, goes past the Index...
1346 [ - + ][ # # ]: 3 : else if ( ( pAttrib->GetStart() < nIndex ) && ( pAttrib->GetEnd() > nIndex ) )
[ - + ]
1347 : : {
1348 : : DBG_ASSERT( !pAttrib->IsFeature(), "Large Feature?!" );
1349 : 0 : pAttrib->Expand( nNew );
1350 : : }
1351 : : // 3: Attribute starts on index...
1352 [ + - ]: 3 : else if ( pAttrib->GetStart() == nIndex )
1353 : : {
1354 [ + - ]: 3 : if ( pAttrib->IsFeature() )
1355 : : {
1356 : 3 : pAttrib->MoveForward( nNew );
1357 : 3 : bResort = sal_True;
1358 : : }
1359 : : else
1360 : : {
1361 : 0 : bool bExpand = false;
1362 [ # # ]: 0 : if ( nIndex == 0 )
1363 : : {
1364 : 0 : bExpand = sal_True;
1365 [ # # ]: 0 : if( bExpandedEmptyAtIndexNull )
1366 : : {
1367 : : // Check if this kind of attribut was empty and expanded here...
1368 : 0 : sal_uInt16 nW = pAttrib->GetItem()->Which();
1369 [ # # ]: 0 : for ( sal_uInt16 nA = 0; nA < nAttr; nA++ )
1370 : : {
1371 : 0 : const EditCharAttrib& r = aCharAttribList.GetAttribs()[nA];
1372 [ # # ][ # # ]: 0 : if ( ( r.GetStart() == 0 ) && ( r.GetItem()->Which() == nW ) )
[ # # ]
1373 : : {
1374 : 0 : bExpand = false;
1375 : 0 : break;
1376 : : }
1377 : : }
1378 : :
1379 : : }
1380 : : }
1381 [ # # ]: 0 : if ( bExpand )
1382 : : {
1383 : 0 : pAttrib->Expand( nNew );
1384 : 0 : bResort = true;
1385 : : }
1386 : : else
1387 : : {
1388 : 0 : pAttrib->MoveForward( nNew );
1389 : : }
1390 : : }
1391 : : }
1392 : : }
1393 : :
1394 [ - + ]: 2969 : if ( pAttrib->IsEdge() )
1395 : 0 : pAttrib->SetEdge(false);
1396 : :
1397 : : DBG_ASSERT( !pAttrib->IsFeature() || ( pAttrib->GetLen() == 1 ), "Expand: FeaturesLen != 1" );
1398 : :
1399 : : DBG_ASSERT( pAttrib->GetStart() <= pAttrib->GetEnd(), "Expand: Attribute distorted!" );
1400 : : DBG_ASSERT( ( pAttrib->GetEnd() <= Len() ), "Expand: Attribute larger than paragraph!" );
1401 [ - + ]: 2969 : if ( pAttrib->IsEmpty() )
1402 : : {
1403 : : OSL_FAIL( "Empty Attribute after ExpandAttribs?" );
1404 : 0 : bResort = true;
1405 : 0 : rItemPool.Remove( *pAttrib->GetItem() );
1406 : 0 : rAttribs.erase(rAttribs.begin()+nAttr);
1407 : 0 : --nAttr;
1408 : : }
1409 : 2969 : ++nAttr;
1410 : 2969 : pAttrib = GetAttrib(rAttribs, nAttr);
1411 : : }
1412 : :
1413 [ + + ]: 172670 : if ( bResort )
1414 : 392 : aCharAttribList.ResortAttribs();
1415 : :
1416 [ + + ]: 172670 : if ( pWrongList )
1417 : : {
1418 [ + + ][ + + ]: 20147 : bool bSep = ( maString.GetChar( nIndex ) == ' ' ) || IsFeature( nIndex );
1419 : 20147 : pWrongList->TextInserted( nIndex, nNew, bSep );
1420 : : }
1421 : :
1422 : : #if OSL_DEBUG_LEVEL > 2
1423 : : OSL_ENSURE( CheckOrderedList( aCharAttribList.GetAttribs(), sal_True ), "Expand: Start List distorted" );
1424 : : #endif
1425 : : }
1426 : :
1427 : 1848 : void ContentNode::CollapsAttribs( sal_uInt16 nIndex, sal_uInt16 nDeleted, SfxItemPool& rItemPool )
1428 : : {
1429 [ + + ]: 1848 : if ( !nDeleted )
1430 : 1848 : return;
1431 : :
1432 : : // Since features are treated differently than normal character attributes,
1433 : : // can also the order of the start list be change!
1434 : 234 : bool bResort = false;
1435 : 234 : bool bDelAttr = false;
1436 : 234 : sal_uInt16 nEndChanges = nIndex+nDeleted;
1437 : :
1438 : 234 : size_t nAttr = 0;
1439 : 234 : CharAttribList::AttribsType& rAttribs = aCharAttribList.GetAttribs();
1440 : 234 : EditCharAttrib* pAttrib = GetAttrib(rAttribs, nAttr);
1441 [ + + ]: 333 : while ( pAttrib )
1442 : : {
1443 : 99 : bDelAttr = false;
1444 [ + - ]: 99 : if ( pAttrib->GetEnd() >= nIndex )
1445 : : {
1446 : : // Move all Attribute behind the insert point...
1447 [ - + ]: 99 : if ( pAttrib->GetStart() >= nEndChanges )
1448 : : {
1449 : 0 : pAttrib->MoveBackward( nDeleted );
1450 : : }
1451 : : // 1. Delete Internal attributes...
1452 [ + - ][ + - ]: 99 : else if ( ( pAttrib->GetStart() >= nIndex ) && ( pAttrib->GetEnd() <= nEndChanges ) )
[ + - ]
1453 : : {
1454 : : // Special case: Attribute covers the area exactly
1455 : : // => keep as empty Attribute.
1456 [ - + ][ # # ]: 99 : if ( !pAttrib->IsFeature() && ( pAttrib->GetStart() == nIndex ) && ( pAttrib->GetEnd() == nEndChanges ) )
[ # # ][ - + ]
1457 : 0 : pAttrib->GetEnd() = nIndex; // empty
1458 : : else
1459 : 99 : bDelAttr = sal_True;
1460 : : }
1461 : : // 2. Attribute starts earlier, ends inside or behind it ...
1462 [ # # ][ # # ]: 0 : else if ( ( pAttrib->GetStart() <= nIndex ) && ( pAttrib->GetEnd() > nIndex ) )
[ # # ]
1463 : : {
1464 : : DBG_ASSERT( !pAttrib->IsFeature(), "Collapsing Feature!" );
1465 [ # # ]: 0 : if ( pAttrib->GetEnd() <= nEndChanges ) // ends inside
1466 : 0 : pAttrib->GetEnd() = nIndex;
1467 : : else
1468 : 0 : pAttrib->Collaps( nDeleted ); // ends behind
1469 : : }
1470 : : // 3. Attribute starts inside, ending behind ...
1471 [ # # ][ # # ]: 0 : else if ( ( pAttrib->GetStart() >= nIndex ) && ( pAttrib->GetEnd() > nEndChanges ) )
[ # # ]
1472 : : {
1473 : : // Features not allowed to expand!
1474 [ # # ]: 0 : if ( pAttrib->IsFeature() )
1475 : : {
1476 : 0 : pAttrib->MoveBackward( nDeleted );
1477 : 0 : bResort = sal_True;
1478 : : }
1479 : : else
1480 : : {
1481 : 0 : pAttrib->GetStart() = nEndChanges;
1482 : 0 : pAttrib->MoveBackward( nDeleted );
1483 : : }
1484 : : }
1485 : : }
1486 : : DBG_ASSERT( !pAttrib->IsFeature() || ( pAttrib->GetLen() == 1 ), "Expand: FeaturesLen != 1" );
1487 : :
1488 : : DBG_ASSERT( pAttrib->GetStart() <= pAttrib->GetEnd(), "Collaps: Attribut distorted!" );
1489 : : DBG_ASSERT( ( pAttrib->GetEnd() <= Len()) || bDelAttr, "Collaps: Attribute larger than paragraph!" );
1490 [ + - ]: 99 : if ( bDelAttr )
1491 : : {
1492 : 99 : bResort = true;
1493 : 99 : rItemPool.Remove( *pAttrib->GetItem() );
1494 : 99 : rAttribs.erase(rAttribs.begin()+nAttr);
1495 : 99 : nAttr--;
1496 : : }
1497 [ # # ]: 0 : else if ( pAttrib->IsEmpty() )
1498 : 0 : aCharAttribList.SetHasEmptyAttribs(true);
1499 : :
1500 : 99 : nAttr++;
1501 : 99 : pAttrib = GetAttrib(rAttribs, nAttr);
1502 : : }
1503 : :
1504 [ + + ]: 234 : if ( bResort )
1505 : 99 : aCharAttribList.ResortAttribs();
1506 : :
1507 [ + + ]: 234 : if ( pWrongList )
1508 : 81 : pWrongList->TextDeleted( nIndex, nDeleted );
1509 : :
1510 : : #if OSL_DEBUG_LEVEL > 2
1511 : : OSL_ENSURE( CheckOrderedList( aCharAttribList.GetAttribs(), sal_True ), "Collaps: Start list distorted" );
1512 : : #endif
1513 : : }
1514 : :
1515 : 1832 : void ContentNode::CopyAndCutAttribs( ContentNode* pPrevNode, SfxItemPool& rPool, sal_Bool bKeepEndingAttribs )
1516 : : {
1517 : : DBG_ASSERT( pPrevNode, "Copy of attributes to a null pointer?" );
1518 : :
1519 : 1832 : sal_uInt16 nCut = pPrevNode->Len();
1520 : :
1521 : 1832 : size_t nAttr = 0;
1522 : 1832 : CharAttribList::AttribsType& rPrevAttribs = pPrevNode->GetCharAttribs().GetAttribs();
1523 : 1832 : EditCharAttrib* pAttrib = GetAttrib(rPrevAttribs, nAttr);
1524 [ + + ]: 2869 : while ( pAttrib )
1525 : : {
1526 [ + + ]: 1037 : if ( pAttrib->GetEnd() < nCut )
1527 : : {
1528 : : // remain unchanged ....
1529 : : ;
1530 : : }
1531 [ + + ]: 639 : else if ( pAttrib->GetEnd() == nCut )
1532 : : {
1533 : : // must be copied as an empty attributes.
1534 [ + - ][ + + ]: 638 : if ( bKeepEndingAttribs && !pAttrib->IsFeature() && !aCharAttribList.FindAttrib( pAttrib->GetItem()->Which(), 0 ) )
[ + - ][ + + ]
1535 : : {
1536 : 180 : EditCharAttrib* pNewAttrib = MakeCharAttrib( rPool, *(pAttrib->GetItem()), 0, 0 );
1537 : : DBG_ASSERT( pNewAttrib, "MakeCharAttrib failed!" );
1538 : 180 : aCharAttribList.InsertAttrib( pNewAttrib );
1539 : : }
1540 : : }
1541 [ + - ][ - + ]: 1 : else if ( pAttrib->IsInside( nCut ) || ( !nCut && !pAttrib->GetStart() && !pAttrib->IsFeature() ) )
[ # # ][ # # ]
[ - + ]
1542 : : {
1543 : : // If cut is done right at the front then the attribute must be
1544 : : // kept! Has to be copied and changed.
1545 : 0 : EditCharAttrib* pNewAttrib = MakeCharAttrib( rPool, *(pAttrib->GetItem()), 0, pAttrib->GetEnd()-nCut );
1546 : : DBG_ASSERT( pNewAttrib, "MakeCharAttrib failed!" );
1547 : 0 : aCharAttribList.InsertAttrib( pNewAttrib );
1548 : 0 : pAttrib->GetEnd() = nCut;
1549 : : }
1550 : : else
1551 : : {
1552 : : // Move all attributes in the current node (this)
1553 [ + - ][ + - ]: 1 : CharAttribList::AttribsType::iterator it = rPrevAttribs.begin() + nAttr;
1554 [ + - ][ + - ]: 1 : aCharAttribList.InsertAttrib(rPrevAttribs.release(it).release());
[ + - ][ + - ]
1555 : :
1556 : : DBG_ASSERT( pAttrib->GetStart() >= nCut, "Start < nCut!" );
1557 : : DBG_ASSERT( pAttrib->GetEnd() >= nCut, "End < nCut!" );
1558 : 1 : pAttrib->GetStart() = pAttrib->GetStart() - nCut;
1559 : 1 : pAttrib->GetEnd() = pAttrib->GetEnd() - nCut;
1560 : 1 : nAttr--;
1561 : : }
1562 : 1037 : nAttr++;
1563 : 1037 : pAttrib = GetAttrib(rPrevAttribs, nAttr);
1564 : : }
1565 : 1832 : }
1566 : :
1567 : 810 : void ContentNode::AppendAttribs( ContentNode* pNextNode )
1568 : : {
1569 : : DBG_ASSERT( pNextNode, "Copy of attributes to a null pointer?" );
1570 : :
1571 : 810 : sal_uInt16 nNewStart = maString.Len();
1572 : :
1573 : : #if OSL_DEBUG_LEVEL > 2
1574 : : OSL_ENSURE( aCharAttribList.DbgCheckAttribs(), "Attribute before AppendAttribs broken" );
1575 : : #endif
1576 : :
1577 : 810 : size_t nAttr = 0;
1578 : 810 : CharAttribList::AttribsType& rNextAttribs = pNextNode->GetCharAttribs().GetAttribs();
1579 : 810 : EditCharAttrib* pAttrib = GetAttrib(rNextAttribs, nAttr);
1580 [ - + ]: 810 : while ( pAttrib )
1581 : : {
1582 : : // Move all attributes in the current node (this)
1583 : 0 : bool bMelted = false;
1584 [ # # ][ # # ]: 0 : if ( ( pAttrib->GetStart() == 0 ) && ( !pAttrib->IsFeature() ) )
[ # # ]
1585 : : {
1586 : : // Attributes can possibly be summarized as:
1587 : 0 : size_t nTmpAttr = 0;
1588 : 0 : EditCharAttrib* pTmpAttrib = GetAttrib( aCharAttribList.GetAttribs(), nTmpAttr );
1589 [ # # ][ # # ]: 0 : while ( !bMelted && pTmpAttrib )
[ # # ]
1590 : : {
1591 [ # # ]: 0 : if ( pTmpAttrib->GetEnd() == nNewStart )
1592 : : {
1593 [ # # # # ]: 0 : if ( ( pTmpAttrib->Which() == pAttrib->Which() ) &&
[ # # ]
1594 : 0 : ( *(pTmpAttrib->GetItem()) == *(pAttrib->GetItem() ) ) )
1595 : : {
1596 : 0 : pTmpAttrib->GetEnd() =
1597 : 0 : pTmpAttrib->GetEnd() + pAttrib->GetLen();
1598 : 0 : rNextAttribs.erase(rNextAttribs.begin()+nAttr);
1599 : : // Unsubscribe from the pool?!
1600 : 0 : bMelted = true;
1601 : : }
1602 : : }
1603 : 0 : ++nTmpAttr;
1604 : 0 : pTmpAttrib = GetAttrib( aCharAttribList.GetAttribs(), nTmpAttr );
1605 : : }
1606 : : }
1607 : :
1608 [ # # ]: 0 : if ( !bMelted )
1609 : : {
1610 : 0 : pAttrib->GetStart() = pAttrib->GetStart() + nNewStart;
1611 : 0 : pAttrib->GetEnd() = pAttrib->GetEnd() + nNewStart;
1612 [ # # ][ # # ]: 0 : CharAttribList::AttribsType::iterator it = rNextAttribs.begin() + nAttr;
1613 [ # # ][ # # ]: 0 : aCharAttribList.InsertAttrib(rNextAttribs.release(it).release());
[ # # ][ # # ]
1614 : : }
1615 : 0 : pAttrib = GetAttrib(rNextAttribs, nAttr);
1616 : : }
1617 : : // For the Attributes that just moved over:
1618 : 810 : rNextAttribs.clear();
1619 : :
1620 : : #if OSL_DEBUG_LEVEL > 2
1621 : : OSL_ENSURE( aCharAttribList.DbgCheckAttribs(), "Attribute after AppendAttribs broken" );
1622 : : #endif
1623 : 810 : }
1624 : :
1625 : 371602 : void ContentNode::CreateDefFont()
1626 : : {
1627 : : // First use the information from the style ...
1628 : 371602 : SfxStyleSheet* pS = aContentAttribs.GetStyleSheet();
1629 [ + + ]: 371602 : if ( pS )
1630 : 41679 : CreateFont( GetCharAttribs().GetDefFont(), pS->GetItemSet() );
1631 : :
1632 : : // ... then iron out the hard paragraph formatting...
1633 : 371602 : CreateFont( GetCharAttribs().GetDefFont(),
1634 : 743204 : GetContentAttribs().GetItems(), pS == NULL );
1635 : 371602 : }
1636 : :
1637 : 0 : void ContentNode::SetStyleSheet( SfxStyleSheet* pS, const SvxFont& rFontFromStyle )
1638 : : {
1639 : 0 : aContentAttribs.SetStyleSheet( pS );
1640 : :
1641 : :
1642 : : // First use the information from the style ...
1643 : 0 : GetCharAttribs().GetDefFont() = rFontFromStyle;
1644 : : // ... then iron out the hard paragraph formatting...
1645 : 0 : CreateFont( GetCharAttribs().GetDefFont(),
1646 : 0 : GetContentAttribs().GetItems(), pS == NULL );
1647 : 0 : }
1648 : :
1649 : 163481 : void ContentNode::SetStyleSheet( SfxStyleSheet* pS, sal_Bool bRecalcFont )
1650 : : {
1651 : 163481 : aContentAttribs.SetStyleSheet( pS );
1652 [ + + ]: 163481 : if ( bRecalcFont )
1653 : 20452 : CreateDefFont();
1654 : 163481 : }
1655 : :
1656 : 11871 : void ContentNode::DestroyWrongList()
1657 : : {
1658 [ + - ]: 11871 : delete pWrongList;
1659 : 11871 : pWrongList = NULL;
1660 : 11871 : }
1661 : :
1662 : 20066 : bool ContentNode::IsFeature( sal_uInt16 nPos ) const
1663 : : {
1664 : 20066 : return maString.GetChar(nPos) == CH_FEATURE;
1665 : : }
1666 : :
1667 : 6625255 : sal_uInt16 ContentNode::Len() const
1668 : : {
1669 : 6625255 : return maString.Len();
1670 : : }
1671 : :
1672 : 751340 : const XubString& ContentNode::GetString() const
1673 : : {
1674 : 751340 : return maString;
1675 : : }
1676 : :
1677 : 0 : void ContentNode::SetChar(sal_uInt16 nPos, sal_Unicode c)
1678 : : {
1679 : 0 : maString.SetChar(nPos, c);
1680 : 0 : }
1681 : :
1682 : 177408 : void ContentNode::Insert(const XubString& rStr, sal_uInt16 nPos)
1683 : : {
1684 : 177408 : maString.Insert(rStr, nPos);
1685 : 177408 : }
1686 : :
1687 : 810 : void ContentNode::Append(const XubString& rStr)
1688 : : {
1689 : 810 : maString.Append(rStr);
1690 : 810 : }
1691 : :
1692 : 1832 : void ContentNode::Erase(sal_uInt16 nPos)
1693 : : {
1694 : 1832 : maString.Erase(nPos);
1695 : 1832 : }
1696 : :
1697 : 1848 : void ContentNode::Erase(sal_uInt16 nPos, sal_uInt16 nCount)
1698 : : {
1699 : 1848 : maString.Erase(nPos, nCount);
1700 : 1848 : }
1701 : :
1702 : 1832 : XubString ContentNode::Copy(sal_uInt16 nPos) const
1703 : : {
1704 : 1832 : return maString.Copy(nPos);
1705 : : }
1706 : :
1707 : 69382 : XubString ContentNode::Copy(sal_uInt16 nPos, sal_uInt16 nCount) const
1708 : : {
1709 : 69382 : return maString.Copy(nPos, nCount);
1710 : : }
1711 : :
1712 : 224692 : sal_Unicode ContentNode::GetChar(sal_uInt16 nPos) const
1713 : : {
1714 : 224692 : return maString.GetChar(nPos);
1715 : : }
1716 : :
1717 : 37883 : void ContentNode::CreateWrongList()
1718 : : {
1719 : : DBG_ASSERT( !pWrongList, "WrongList already exist!" );
1720 [ + - ]: 37883 : pWrongList = new WrongList;
1721 : 37883 : }
1722 : :
1723 : 11583 : void ContentNode::SetWrongList( WrongList* p )
1724 : : {
1725 : : DBG_ASSERT( !pWrongList, "WrongList already exist!" );
1726 : 11583 : pWrongList = p;
1727 : 11583 : }
1728 : :
1729 : 319256 : ContentAttribs::ContentAttribs( SfxItemPool& rPool ) :
1730 : 319256 : aAttribSet( rPool, EE_PARA_START, EE_CHAR_END )
1731 : : {
1732 : 319256 : pStyle = 0;
1733 : 319256 : }
1734 : :
1735 : 3664 : ContentAttribs::ContentAttribs( const ContentAttribs& rRef ) :
1736 : 3664 : aAttribSet( rRef.aAttribSet )
1737 : : {
1738 : 3664 : pStyle = rRef.pStyle;
1739 : 3664 : }
1740 : :
1741 : 322672 : ContentAttribs::~ContentAttribs()
1742 : : {
1743 : 322672 : }
1744 : :
1745 : 0 : SvxTabStop ContentAttribs::FindTabStop( long nCurPos, sal_uInt16 nDefTab )
1746 : : {
1747 [ # # ]: 0 : const SvxTabStopItem& rTabs = (const SvxTabStopItem&) GetItem( EE_PARA_TABS );
1748 [ # # ]: 0 : for ( sal_uInt16 i = 0; i < rTabs.Count(); i++ )
1749 : : {
1750 [ # # ]: 0 : const SvxTabStop& rTab = rTabs[i];
1751 [ # # ]: 0 : if ( rTab.GetTabPos() > nCurPos )
1752 : 0 : return rTab;
1753 : : }
1754 : :
1755 : : // Determine DefTab ...
1756 [ # # ]: 0 : SvxTabStop aTabStop;
1757 : 0 : long x = nCurPos / nDefTab + 1;
1758 : 0 : aTabStop.GetTabPos() = nDefTab * x;
1759 : 0 : return aTabStop;
1760 : : }
1761 : :
1762 : 163481 : void ContentAttribs::SetStyleSheet( SfxStyleSheet* pS )
1763 : : {
1764 : 163481 : sal_Bool bStyleChanged = ( pStyle != pS );
1765 : 163481 : pStyle = pS;
1766 : : // Only when other style sheet, not when current style sheet modified
1767 [ + + ][ + - ]: 163481 : if ( pStyle && bStyleChanged )
1768 : : {
1769 : : // Selectively remove the attributes from the paragraph formatting
1770 : : // which are specified in the style, so that the attributes of the
1771 : : // style can have an affect.
1772 : 20452 : const SfxItemSet& rStyleAttribs = pStyle->GetItemSet();
1773 [ + + ]: 1002148 : for ( sal_uInt16 nWhich = EE_PARA_START; nWhich <= EE_CHAR_END; nWhich++ )
1774 : : {
1775 : : // Don't change bullet on/off
1776 [ + + ][ + + ]: 981696 : if ( ( nWhich != EE_PARA_BULLETSTATE ) && ( rStyleAttribs.GetItemState( nWhich ) == SFX_ITEM_ON ) )
[ + + ]
1777 : 448590 : aAttribSet.ClearItem( nWhich );
1778 : : }
1779 : : }
1780 : 163481 : }
1781 : :
1782 : 5739434 : const SfxPoolItem& ContentAttribs::GetItem( sal_uInt16 nWhich ) const
1783 : : {
1784 : : // Hard paragraph attributes take precedence!
1785 : 5739434 : const SfxItemSet* pTakeFrom = &aAttribSet;
1786 [ + + ][ + + ]: 5739434 : if ( pStyle && ( aAttribSet.GetItemState( nWhich, sal_False ) != SFX_ITEM_ON ) )
[ + + ]
1787 : 511216 : pTakeFrom = &pStyle->GetItemSet();
1788 : :
1789 : 5739434 : return pTakeFrom->Get( nWhich );
1790 : : }
1791 : :
1792 : 8925 : bool ContentAttribs::HasItem( sal_uInt16 nWhich ) const
1793 : : {
1794 : 8925 : bool bHasItem = false;
1795 [ - + ]: 8925 : if ( aAttribSet.GetItemState( nWhich, sal_False ) == SFX_ITEM_ON )
1796 : 0 : bHasItem = true;
1797 [ - + ][ # # ]: 8925 : else if ( pStyle && pStyle->GetItemSet().GetItemState( nWhich ) == SFX_ITEM_ON )
[ - + ]
1798 : 0 : bHasItem = true;
1799 : :
1800 : 8925 : return bHasItem;
1801 : : }
1802 : :
1803 : :
1804 : 0 : ItemList::ItemList() : CurrentItem( 0 )
1805 : : {
1806 : 0 : }
1807 : :
1808 : 0 : const SfxPoolItem* ItemList::First()
1809 : : {
1810 : 0 : CurrentItem = 0;
1811 [ # # ]: 0 : return aItemPool.empty() ? NULL : aItemPool[ 0 ];
1812 : : }
1813 : :
1814 : 0 : const SfxPoolItem* ItemList::Next()
1815 : : {
1816 [ # # ]: 0 : if ( CurrentItem + 1 < aItemPool.size() )
1817 : : {
1818 : 0 : ++CurrentItem;
1819 : 0 : return aItemPool[ CurrentItem ];
1820 : : }
1821 : 0 : return NULL;
1822 : : }
1823 : :
1824 : 0 : void ItemList::Insert( const SfxPoolItem* pItem )
1825 : : {
1826 : 0 : aItemPool.push_back( pItem );
1827 : 0 : CurrentItem = aItemPool.size() - 1;
1828 : 0 : }
1829 : :
1830 : :
1831 : 30636 : EditDoc::EditDoc( SfxItemPool* pPool ) :
1832 : : nLastCache(0),
1833 [ + - ]: 9 : pItemPool(pPool ? pPool : new EditEngineItemPool(false)),
1834 : : nDefTab(DEFTAB),
1835 : : bIsVertical(false),
1836 : : bIsFixedCellHeight(false),
1837 : : bOwnerOfPool(pPool ? false : true),
1838 [ + + ][ + - ]: 30645 : bModified(false)
[ + - ][ + - ]
1839 : : {
1840 : : // Don't create a empty node, Clear() will be called in EditEngine-CTOR
1841 : 30636 : };
1842 : :
1843 [ + - ]: 30388 : EditDoc::~EditDoc()
1844 : : {
1845 [ + - ]: 30388 : ImplDestroyContents();
1846 [ + + ]: 30388 : if ( bOwnerOfPool )
1847 [ + - ]: 9 : SfxItemPool::Free(pItemPool);
1848 : 30388 : }
1849 : :
1850 : : namespace {
1851 : :
1852 : : class RemoveEachItemFromPool : std::unary_function<ContentNode, void>
1853 : : {
1854 : : EditDoc& mrDoc;
1855 : : public:
1856 : 339984 : RemoveEachItemFromPool(EditDoc& rDoc) : mrDoc(rDoc) {}
1857 : 320018 : void operator() (const ContentNode& rNode)
1858 : : {
1859 : 320018 : mrDoc.RemoveItemsFromPool(rNode);
1860 : 320018 : }
1861 : : };
1862 : :
1863 : : }
1864 : :
1865 : 339984 : void EditDoc::ImplDestroyContents()
1866 : : {
1867 [ + - ][ + - ]: 339984 : std::for_each(maContents.begin(), maContents.end(), RemoveEachItemFromPool(*this));
[ + - ]
1868 : 339984 : maContents.clear();
1869 : 339984 : }
1870 : :
1871 : 320828 : void EditDoc::RemoveItemsFromPool(const ContentNode& rNode)
1872 : : {
1873 [ + + ]: 408322 : for (size_t nAttr = 0; nAttr < rNode.GetCharAttribs().Count(); ++nAttr)
1874 : : {
1875 : 87494 : const EditCharAttrib& rAttr = rNode.GetCharAttribs().GetAttribs()[nAttr];
1876 : 87494 : GetItemPool().Remove(*rAttr.GetItem());
1877 : : }
1878 : 320828 : }
1879 : :
1880 : 582493 : void CreateFont( SvxFont& rFont, const SfxItemSet& rSet, bool bSearchInParent, short nScriptType )
1881 : : {
1882 [ + - ]: 582493 : Font aPrevFont( rFont );
1883 [ + - ]: 582493 : rFont.SetAlign( ALIGN_BASELINE );
1884 [ + - ]: 582493 : rFont.SetTransparent( sal_True );
1885 : :
1886 : 582493 : sal_uInt16 nWhich_FontInfo = GetScriptItemId( EE_CHAR_FONTINFO, nScriptType );
1887 : 582493 : sal_uInt16 nWhich_Language = GetScriptItemId( EE_CHAR_LANGUAGE, nScriptType );
1888 : 582493 : sal_uInt16 nWhich_FontHeight = GetScriptItemId( EE_CHAR_FONTHEIGHT, nScriptType );
1889 : 582493 : sal_uInt16 nWhich_Weight = GetScriptItemId( EE_CHAR_WEIGHT, nScriptType );
1890 : 582493 : sal_uInt16 nWhich_Italic = GetScriptItemId( EE_CHAR_ITALIC, nScriptType );
1891 : :
1892 [ + - ][ + + ]: 582493 : if ( bSearchInParent || ( rSet.GetItemState( nWhich_FontInfo ) == SFX_ITEM_ON ) )
[ + + ][ + + ]
1893 : : {
1894 [ + - ]: 541270 : const SvxFontItem& rFontItem = (const SvxFontItem&)rSet.Get( nWhich_FontInfo );
1895 [ + - ][ + - ]: 541270 : rFont.SetName( rFontItem.GetFamilyName() );
1896 [ + - ]: 541270 : rFont.SetFamily( rFontItem.GetFamily() );
1897 [ + - ]: 541270 : rFont.SetPitch( rFontItem.GetPitch() );
1898 [ + - ]: 541270 : rFont.SetCharSet( rFontItem.GetCharSet() );
1899 : : }
1900 [ + + ][ + - ]: 582493 : if ( bSearchInParent || ( rSet.GetItemState( nWhich_Language ) == SFX_ITEM_ON ) )
[ + + ][ + + ]
1901 [ + - ][ + - ]: 541234 : rFont.SetLanguage( ((const SvxLanguageItem&)rSet.Get( nWhich_Language )).GetLanguage() );
1902 [ + + ][ + - ]: 582493 : if ( bSearchInParent || ( rSet.GetItemState( EE_CHAR_COLOR ) == SFX_ITEM_ON ) )
[ + + ][ + + ]
1903 [ + - ][ + - ]: 541168 : rFont.SetColor( ((const SvxColorItem&)rSet.Get( EE_CHAR_COLOR )).GetValue() );
1904 [ + + ][ + - ]: 582493 : if ( bSearchInParent || ( rSet.GetItemState( nWhich_FontHeight ) == SFX_ITEM_ON ) )
[ + + ][ + + ]
1905 [ + - ][ + - ]: 543434 : rFont.SetSize( Size( rFont.GetSize().Width(), ((const SvxFontHeightItem&)rSet.Get( nWhich_FontHeight ) ).GetHeight() ) );
[ + - ]
1906 [ + + ][ + - ]: 582493 : if ( bSearchInParent || ( rSet.GetItemState( nWhich_Weight ) == SFX_ITEM_ON ) )
[ + + ][ + + ]
1907 [ + - ][ + - ]: 541188 : rFont.SetWeight( ((const SvxWeightItem&)rSet.Get( nWhich_Weight )).GetWeight() );
1908 [ + + ][ + - ]: 582493 : if ( bSearchInParent || ( rSet.GetItemState( EE_CHAR_UNDERLINE ) == SFX_ITEM_ON ) )
[ + + ][ + + ]
1909 [ + - ][ + - ]: 541265 : rFont.SetUnderline( ((const SvxUnderlineItem&)rSet.Get( EE_CHAR_UNDERLINE )).GetLineStyle() );
1910 [ + + ][ + - ]: 582493 : if ( bSearchInParent || ( rSet.GetItemState( EE_CHAR_OVERLINE ) == SFX_ITEM_ON ) )
[ + + ][ + + ]
1911 [ + - ][ + - ]: 541275 : rFont.SetOverline( ((const SvxOverlineItem&)rSet.Get( EE_CHAR_OVERLINE )).GetLineStyle() );
1912 [ + + ][ + - ]: 582493 : if ( bSearchInParent || ( rSet.GetItemState( EE_CHAR_STRIKEOUT ) == SFX_ITEM_ON ) )
[ + + ][ + + ]
1913 [ + - ][ + - ]: 541286 : rFont.SetStrikeout( ((const SvxCrossedOutItem&)rSet.Get( EE_CHAR_STRIKEOUT )).GetStrikeout() );
1914 [ + + ][ + - ]: 582493 : if ( bSearchInParent || ( rSet.GetItemState( nWhich_Italic ) == SFX_ITEM_ON ) )
[ + + ][ + + ]
1915 [ + - ][ + - ]: 541315 : rFont.SetItalic( ((const SvxPostureItem&)rSet.Get( nWhich_Italic )).GetPosture() );
1916 [ + + ][ + - ]: 582493 : if ( bSearchInParent || ( rSet.GetItemState( EE_CHAR_OUTLINE ) == SFX_ITEM_ON ) )
[ + + ][ + + ]
1917 [ + - ][ + - ]: 541214 : rFont.SetOutline( ((const SvxContourItem&)rSet.Get( EE_CHAR_OUTLINE )).GetValue() );
1918 [ + + ][ + - ]: 582493 : if ( bSearchInParent || ( rSet.GetItemState( EE_CHAR_SHADOW ) == SFX_ITEM_ON ) )
[ + + ][ + + ]
1919 [ + - ][ + - ]: 541302 : rFont.SetShadow( ((const SvxShadowedItem&)rSet.Get( EE_CHAR_SHADOW )).GetValue() );
1920 [ + + ][ + - ]: 582493 : if ( bSearchInParent || ( rSet.GetItemState( EE_CHAR_ESCAPEMENT ) == SFX_ITEM_ON ) )
[ + + ][ + + ]
1921 : : {
1922 [ + - ]: 541408 : const SvxEscapementItem& rEsc = (const SvxEscapementItem&) rSet.Get( EE_CHAR_ESCAPEMENT );
1923 : :
1924 : 541408 : sal_uInt16 nProp = rEsc.GetProp();
1925 : 541408 : rFont.SetPropr( (sal_uInt8)nProp );
1926 : :
1927 : 541408 : short nEsc = rEsc.GetEsc();
1928 [ - + ]: 541408 : if ( nEsc == DFLT_ESC_AUTO_SUPER )
1929 : 0 : nEsc = 100 - nProp;
1930 [ - + ]: 541408 : else if ( nEsc == DFLT_ESC_AUTO_SUB )
1931 : 0 : nEsc = sal::static_int_cast< short >( -( 100 - nProp ) );
1932 : 541408 : rFont.SetEscapement( nEsc );
1933 : : }
1934 [ + + ][ + - ]: 582493 : if ( bSearchInParent || ( rSet.GetItemState( EE_CHAR_PAIRKERNING ) == SFX_ITEM_ON ) )
[ + + ][ + + ]
1935 [ + - ][ + - ]: 541369 : rFont.SetKerning( ((const SvxAutoKernItem&)rSet.Get( EE_CHAR_PAIRKERNING )).GetValue() );
1936 [ + + ][ + - ]: 582493 : if ( bSearchInParent || ( rSet.GetItemState( EE_CHAR_KERNING ) == SFX_ITEM_ON ) )
[ + + ][ + + ]
1937 [ + - ]: 541319 : rFont.SetFixKerning( ((const SvxKerningItem&)rSet.Get( EE_CHAR_KERNING )).GetValue() );
1938 [ + + ][ + - ]: 582493 : if ( bSearchInParent || ( rSet.GetItemState( EE_CHAR_WLM ) == SFX_ITEM_ON ) )
[ + + ][ + + ]
1939 [ + - ][ + - ]: 541296 : rFont.SetWordLineMode( ((const SvxWordLineModeItem&)rSet.Get( EE_CHAR_WLM )).GetValue() );
1940 [ + + ][ + - ]: 582493 : if ( bSearchInParent || ( rSet.GetItemState( EE_CHAR_EMPHASISMARK ) == SFX_ITEM_ON ) )
[ + + ][ + + ]
1941 [ + - ][ + - ]: 541309 : rFont.SetEmphasisMark( ((const SvxEmphasisMarkItem&)rSet.Get( EE_CHAR_EMPHASISMARK )).GetValue() );
1942 [ + + ][ + - ]: 582493 : if ( bSearchInParent || ( rSet.GetItemState( EE_CHAR_RELIEF ) == SFX_ITEM_ON ) )
[ - + ][ + + ]
1943 [ + - ][ + - ]: 540814 : rFont.SetRelief( (FontRelief)((const SvxCharReliefItem&)rSet.Get( EE_CHAR_RELIEF )).GetValue() );
1944 : :
1945 : : // If comparing the entire font, or if checking before each alteration
1946 : : // whether the value changes, remains relatively the same thing.
1947 : : // So possible one MakeUniqFont more in the font, but as a result a quicker
1948 : : // abortion of the query, or one must each time check bChanged.
1949 [ + - ][ + + ]: 582493 : if ( rFont == aPrevFont )
1950 [ + - ][ + - ]: 582493 : rFont = aPrevFont; // => The same ImpPointer for IsSameInstance
1951 : 582493 : }
1952 : :
1953 : 166567 : void EditDoc::CreateDefFont( sal_Bool bUseStyles )
1954 : : {
1955 [ + - ]: 166567 : SfxItemSet aTmpSet( GetItemPool(), EE_PARA_START, EE_CHAR_END );
1956 [ + - ]: 166567 : CreateFont( aDefFont, aTmpSet );
1957 [ + - ]: 166567 : aDefFont.SetVertical( IsVertical() );
1958 [ - + ][ + - ]: 166567 : aDefFont.SetOrientation( IsVertical() ? 2700 : 0 );
1959 : :
1960 [ + - ][ + + ]: 333134 : for ( sal_uInt16 nNode = 0; nNode < Count(); nNode++ )
1961 : : {
1962 [ + - ]: 166567 : ContentNode* pNode = GetObject( nNode );
1963 [ + - ]: 166567 : pNode->GetCharAttribs().GetDefFont() = aDefFont;
1964 [ - + ]: 166567 : if ( bUseStyles )
1965 [ # # ]: 0 : pNode->CreateDefFont();
1966 [ + - ]: 166567 : }
1967 : 166567 : }
1968 : :
1969 : : static const sal_Unicode aCR[] = { 0x0d, 0x00 };
1970 : : static const sal_Unicode aLF[] = { 0x0a, 0x00 };
1971 : : static const sal_Unicode aCRLF[] = { 0x0d, 0x0a, 0x00 };
1972 : :
1973 : 3288474 : size_t EditDoc::GetPos(const ContentNode* p) const
1974 : : {
1975 : 3288474 : return FastGetPos(maContents, p, nLastCache);
1976 : : }
1977 : :
1978 : 2689611 : const ContentNode* EditDoc::GetObject(size_t nPos) const
1979 : : {
1980 [ + - ]: 2689611 : return nPos < maContents.size() ? &maContents[nPos] : NULL;
1981 : : }
1982 : :
1983 : 2643990 : ContentNode* EditDoc::GetObject(size_t nPos)
1984 : : {
1985 [ + + ]: 2643990 : return nPos < maContents.size() ? &maContents[nPos] : NULL;
1986 : : }
1987 : :
1988 : 0 : const ContentNode* EditDoc::operator[](size_t nPos) const
1989 : : {
1990 : 0 : return GetObject(nPos);
1991 : : }
1992 : :
1993 : 481953 : ContentNode* EditDoc::operator[](size_t nPos)
1994 : : {
1995 : 481953 : return GetObject(nPos);
1996 : : }
1997 : :
1998 : 321088 : void EditDoc::Insert(size_t nPos, ContentNode* p)
1999 : : {
2000 : 321088 : maContents.insert(maContents.begin()+nPos, p);
2001 : 321088 : }
2002 : :
2003 : 810 : void EditDoc::Remove(size_t nPos)
2004 : : {
2005 [ - + ]: 810 : if (nPos >= maContents.size())
2006 : 810 : return;
2007 : :
2008 : 810 : maContents.erase(maContents.begin() + nPos);
2009 : : }
2010 : :
2011 : 12 : void EditDoc::Release(size_t nPos)
2012 : : {
2013 [ - + ]: 12 : if (nPos >= maContents.size())
2014 : 12 : return;
2015 : :
2016 [ + - ]: 12 : maContents.release(maContents.begin() + nPos).release();
2017 : : }
2018 : :
2019 : 949599 : size_t EditDoc::Count() const
2020 : : {
2021 : 949599 : return maContents.size();
2022 : : }
2023 : :
2024 : 5470 : rtl::OUString EditDoc::GetSepStr( LineEnd eEnd )
2025 : : {
2026 : 5470 : rtl::OUString aSep;
2027 [ - + ]: 5470 : if ( eEnd == LINEEND_CR )
2028 : 0 : aSep = aCR;
2029 [ + - ]: 5470 : else if ( eEnd == LINEEND_LF )
2030 : 5470 : aSep = aLF;
2031 : : else
2032 : 0 : aSep = aCRLF;
2033 : 5470 : return aSep;
2034 : : }
2035 : :
2036 : 1886 : XubString EditDoc::GetText( LineEnd eEnd ) const
2037 : : {
2038 [ + - ]: 1886 : sal_uLong nLen = GetTextLen();
2039 [ + - ]: 1886 : size_t nNodes = Count();
2040 [ - + ]: 1886 : if (nNodes == 0)
2041 [ # # ]: 0 : return rtl::OUString();
2042 : :
2043 : 1886 : rtl::OUString aSep = EditDoc::GetSepStr( eEnd );
2044 : 1886 : sal_Int32 nSepSize = aSep.getLength();
2045 : :
2046 [ + - ]: 1886 : if ( nSepSize )
2047 : 1886 : nLen += (nNodes - 1) * nSepSize;
2048 : :
2049 [ + - ]: 1886 : rtl_uString* newStr = comphelper::string::rtl_uString_alloc(nLen);
2050 : 1886 : xub_Unicode* pCur = newStr->buffer;
2051 : 1886 : size_t nLastNode = nNodes-1;
2052 [ + + ]: 3773 : for ( sal_uInt16 nNode = 0; nNode < nNodes; nNode++ )
2053 : : {
2054 [ + - ][ + - ]: 1887 : String aTmp( GetParaAsString( GetObject(nNode) ) );
2055 : 1887 : memcpy( pCur, aTmp.GetBuffer(), aTmp.Len()*sizeof(sal_Unicode) );
2056 : 1887 : pCur += aTmp.Len();
2057 [ + + ][ + - ]: 1887 : if ( nSepSize && ( nNode != nLastNode ) )
2058 : : {
2059 : 1 : memcpy( pCur, aSep.getStr(), nSepSize*sizeof(sal_Unicode ) );
2060 : 1 : pCur += nSepSize;
2061 : : }
2062 [ + - ]: 1887 : }
2063 : : assert(pCur - newStr->buffer == newStr->length);
2064 [ + - ]: 1886 : return rtl::OUString(newStr, SAL_NO_ACQUIRE);
2065 : : }
2066 : :
2067 : 24127 : XubString EditDoc::GetParaAsString( sal_uInt16 nNode ) const
2068 : : {
2069 : 24127 : return GetParaAsString( GetObject( nNode ) );
2070 : : }
2071 : :
2072 : 29651 : XubString EditDoc::GetParaAsString(
2073 : : const ContentNode* pNode, sal_uInt16 nStartPos, sal_uInt16 nEndPos, bool bResolveFields) const
2074 : : {
2075 [ + + ]: 29651 : if ( nEndPos > pNode->Len() )
2076 : 26014 : nEndPos = pNode->Len();
2077 : :
2078 : : DBG_ASSERT( nStartPos <= nEndPos, "Start and End reversed?" );
2079 : :
2080 : 29651 : sal_uInt16 nIndex = nStartPos;
2081 : 29651 : XubString aStr;
2082 [ + - ]: 29651 : const EditCharAttrib* pNextFeature = pNode->GetCharAttribs().FindFeature( nIndex );
2083 [ + + ]: 35086 : while ( nIndex < nEndPos )
2084 : : {
2085 : 5435 : sal_uInt16 nEnd = nEndPos;
2086 [ + + ][ + + ]: 5435 : if ( pNextFeature && ( pNextFeature->GetStart() < nEnd ) )
[ + + ]
2087 : 332 : nEnd = pNextFeature->GetStart();
2088 : : else
2089 : 5103 : pNextFeature = 0; // Feature does not interest the below
2090 : :
2091 : : DBG_ASSERT( nEnd >= nIndex, "End in front of the index?" );
2092 : : //!! beware of sub string length of -1 which is also defined as STRING_LEN and
2093 : : //!! thus would result in adding the whole sub string up to the end of the node !!
2094 [ + + ]: 5435 : if (nEnd > nIndex)
2095 [ + - ][ + - ]: 5132 : aStr += XubString(pNode->GetString(), nIndex, nEnd - nIndex);
[ + - ]
2096 : :
2097 [ + + ]: 5435 : if ( pNextFeature )
2098 : : {
2099 [ - + + - ]: 332 : switch ( pNextFeature->GetItem()->Which() )
2100 : : {
2101 [ # # ]: 0 : case EE_FEATURE_TAB: aStr += '\t';
2102 : 0 : break;
2103 [ + - ]: 13 : case EE_FEATURE_LINEBR: aStr += '\x0A';
2104 : 13 : break;
2105 : : case EE_FEATURE_FIELD:
2106 [ + - ]: 319 : if ( bResolveFields )
2107 [ + - ][ + - ]: 319 : aStr += static_cast<const EditCharAttribField*>(pNextFeature)->GetFieldValue();
2108 : 319 : break;
2109 : : default: OSL_FAIL( "What feature?" );
2110 : : }
2111 [ + - ]: 332 : pNextFeature = pNode->GetCharAttribs().FindFeature( ++nEnd );
2112 : : }
2113 : 5435 : nIndex = nEnd;
2114 : : }
2115 : 29651 : return aStr;
2116 : : }
2117 : :
2118 : 564225 : EditPaM EditDoc::GetStartPaM() const
2119 : : {
2120 : 564225 : ContentNode* p = const_cast<ContentNode*>(GetObject(0));
2121 : 564225 : return EditPaM(p, 0);
2122 : : }
2123 : :
2124 : 9591 : EditPaM EditDoc::GetEndPaM() const
2125 : : {
2126 : 9591 : ContentNode* pLastNode = const_cast<ContentNode*>(GetObject(Count()-1));
2127 : 9591 : return EditPaM( pLastNode, pLastNode->Len() );
2128 : : }
2129 : :
2130 : 1912 : sal_uLong EditDoc::GetTextLen() const
2131 : : {
2132 : 1912 : sal_uLong nLen = 0;
2133 [ + + ]: 3825 : for ( sal_uInt16 nNode = 0; nNode < Count(); nNode++ )
2134 : : {
2135 : 1913 : const ContentNode* pNode = GetObject( nNode );
2136 : 1913 : nLen += pNode->Len();
2137 : : // Fields can be longer than the placeholder in the Node
2138 : 1913 : const CharAttribList::AttribsType& rAttrs = pNode->GetCharAttribs().GetAttribs();
2139 [ + + ]: 22626 : for (size_t nAttr = rAttrs.size(); nAttr; )
2140 : : {
2141 : 20713 : const EditCharAttrib& rAttr = rAttrs[--nAttr];
2142 [ - + ]: 20713 : if (rAttr.Which() == EE_FEATURE_FIELD)
2143 : : {
2144 : 0 : sal_Int32 nFieldLen = static_cast<const EditCharAttribField&>(rAttr).GetFieldValue().getLength();
2145 [ # # ]: 0 : if ( !nFieldLen )
2146 : 0 : nLen--;
2147 : : else
2148 : 0 : nLen += nFieldLen-1;
2149 : : }
2150 : : }
2151 : : }
2152 : 1912 : return nLen;
2153 : : }
2154 : :
2155 : 166567 : EditPaM EditDoc::Clear()
2156 : : {
2157 : 166567 : ImplDestroyContents();
2158 : :
2159 [ + - ]: 166567 : ContentNode* pNode = new ContentNode( GetItemPool() );
2160 : 166567 : Insert(0, pNode);
2161 : :
2162 : 166567 : CreateDefFont(false);
2163 : :
2164 : 166567 : SetModified(false);
2165 : :
2166 : 166567 : EditPaM aPaM( pNode, 0 );
2167 : 166567 : return aPaM;
2168 : : }
2169 : :
2170 : 914322 : void EditDoc::SetModified( bool b )
2171 : : {
2172 : 914322 : bModified = b;
2173 [ + + ]: 914322 : if ( bModified )
2174 : : {
2175 : 747697 : aModifyHdl.Call( NULL );
2176 : : }
2177 : 914322 : }
2178 : :
2179 : 143029 : EditPaM EditDoc::RemoveText()
2180 : : {
2181 : : // Keep the old ItemSet, to keep the chart Font.
2182 [ + - ]: 143029 : ContentNode* pPrevFirstNode = GetObject(0);
2183 : 143029 : SfxStyleSheet* pPrevStyle = pPrevFirstNode->GetStyleSheet();
2184 [ + - ]: 143029 : SfxItemSet aPrevSet( pPrevFirstNode->GetContentAttribs().GetItems() );
2185 [ + - ]: 143029 : Font aPrevFont( pPrevFirstNode->GetCharAttribs().GetDefFont() );
2186 : :
2187 [ + - ]: 143029 : ImplDestroyContents();
2188 : :
2189 [ + - ][ + - ]: 143029 : ContentNode* pNode = new ContentNode( GetItemPool() );
2190 [ + - ]: 143029 : Insert(0, pNode);
2191 : :
2192 [ + - ]: 143029 : pNode->SetStyleSheet(pPrevStyle, false);
2193 [ + - ]: 143029 : pNode->GetContentAttribs().GetItems().Set( aPrevSet );
2194 [ + - ]: 143029 : pNode->GetCharAttribs().GetDefFont() = aPrevFont;
2195 : :
2196 [ + - ]: 143029 : SetModified(true);
2197 : :
2198 : 143029 : EditPaM aPaM( pNode, 0 );
2199 [ + - ][ + - ]: 143029 : return aPaM;
2200 : : }
2201 : :
2202 : 172384 : EditPaM EditDoc::InsertText( EditPaM aPaM, const XubString& rStr )
2203 : : {
2204 : : DBG_ASSERT( rStr.Search( 0x0A ) == STRING_NOTFOUND, "EditDoc::InsertText: Newlines prohibited in paragraph!" );
2205 : : DBG_ASSERT( rStr.Search( 0x0D ) == STRING_NOTFOUND, "EditDoc::InsertText: Newlines prohibited in paragraph!" );
2206 : : DBG_ASSERT( rStr.Search( '\t' ) == STRING_NOTFOUND, "EditDoc::InsertText: Newlines prohibited in paragraph!" );
2207 : : DBG_ASSERT( aPaM.GetNode(), "Blinder PaM in EditDoc::InsertText1" );
2208 : :
2209 : 172384 : aPaM.GetNode()->Insert( rStr, aPaM.GetIndex() );
2210 : 172384 : aPaM.GetNode()->ExpandAttribs( aPaM.GetIndex(), rStr.Len(), GetItemPool() );
2211 : 172384 : aPaM.GetIndex() = aPaM.GetIndex() + rStr.Len();
2212 : :
2213 : 172384 : SetModified( sal_True );
2214 : :
2215 : 172384 : return aPaM;
2216 : : }
2217 : :
2218 : 1832 : EditPaM EditDoc::InsertParaBreak( EditPaM aPaM, sal_Bool bKeepEndingAttribs )
2219 : : {
2220 : : DBG_ASSERT( aPaM.GetNode(), "Blinder PaM in EditDoc::InsertParaBreak" );
2221 : 1832 : ContentNode* pCurNode = aPaM.GetNode();
2222 [ + - ]: 1832 : sal_uInt16 nPos = GetPos( pCurNode );
2223 [ + - ]: 1832 : XubString aStr = aPaM.GetNode()->Copy( aPaM.GetIndex() );
2224 [ + - ]: 1832 : aPaM.GetNode()->Erase( aPaM.GetIndex() );
2225 : :
2226 : : // the paragraph attributes...
2227 [ + - ]: 1832 : ContentAttribs aContentAttribs( aPaM.GetNode()->GetContentAttribs() );
2228 : :
2229 : : // for a new paragraph we like to have the bullet/numbering visible by default
2230 [ + - ][ + - ]: 1832 : aContentAttribs.GetItems().Put( SfxBoolItem( EE_PARA_BULLETSTATE, sal_True), EE_PARA_BULLETSTATE );
[ + - ]
2231 : :
2232 : : // ContenNode constructor copies also the paragraph attributes
2233 [ + - ][ + - ]: 1832 : ContentNode* pNode = new ContentNode( aStr, aContentAttribs );
2234 : :
2235 : : // Copy the Default Font
2236 [ + - ]: 1832 : pNode->GetCharAttribs().GetDefFont() = aPaM.GetNode()->GetCharAttribs().GetDefFont();
2237 : 1832 : SfxStyleSheet* pStyle = aPaM.GetNode()->GetStyleSheet();
2238 [ + + ]: 1832 : if ( pStyle )
2239 : : {
2240 [ + - ][ + - ]: 860 : XubString aFollow( pStyle->GetFollow() );
2241 [ + - ][ + - ]: 860 : if ( aFollow.Len() && ( aFollow != pStyle->GetName() ) )
[ + - ][ - + ]
[ - + ]
2242 : : {
2243 [ # # ]: 0 : SfxStyleSheetBase* pNext = pStyle->GetPool().Find( aFollow, pStyle->GetFamily() );
2244 [ # # ]: 0 : pNode->SetStyleSheet( (SfxStyleSheet*)pNext );
2245 [ + - ]: 860 : }
2246 : : }
2247 : :
2248 : : // Character attributes may need to be copied or trimmed:
2249 [ + - ]: 1832 : pNode->CopyAndCutAttribs( aPaM.GetNode(), GetItemPool(), bKeepEndingAttribs );
2250 : :
2251 [ + - ]: 1832 : Insert(nPos+1, pNode);
2252 : :
2253 [ + - ]: 1832 : SetModified(true);
2254 : :
2255 : 1832 : aPaM.SetNode( pNode );
2256 : 1832 : aPaM.SetIndex( 0 );
2257 [ + - ][ + - ]: 1832 : return aPaM;
2258 : : }
2259 : :
2260 : 5024 : EditPaM EditDoc::InsertFeature( EditPaM aPaM, const SfxPoolItem& rItem )
2261 : : {
2262 : : DBG_ASSERT( aPaM.GetNode(), "Blinder PaM in EditDoc::InsertFeature" );
2263 : :
2264 [ + - ][ + - ]: 5024 : aPaM.GetNode()->Insert( rtl::OUString(CH_FEATURE), aPaM.GetIndex() );
[ + - ]
2265 : 5024 : aPaM.GetNode()->ExpandAttribs( aPaM.GetIndex(), 1, GetItemPool() );
2266 : :
2267 : : // Create a feature-attribute for the feature...
2268 : 5024 : EditCharAttrib* pAttrib = MakeCharAttrib( GetItemPool(), rItem, aPaM.GetIndex(), aPaM.GetIndex()+1 );
2269 : : DBG_ASSERT( pAttrib, "Why can not the feature be created?" );
2270 : 5024 : aPaM.GetNode()->GetCharAttribs().InsertAttrib( pAttrib );
2271 : :
2272 : 5024 : SetModified( sal_True );
2273 : :
2274 : 5024 : aPaM.GetIndex()++;
2275 : 5024 : return aPaM;
2276 : : }
2277 : :
2278 : 810 : EditPaM EditDoc::ConnectParagraphs( ContentNode* pLeft, ContentNode* pRight )
2279 : : {
2280 : 810 : const EditPaM aPaM( pLeft, pLeft->Len() );
2281 : :
2282 : : // First the attributes, otherwise nLen will not be correct!
2283 : 810 : pLeft->AppendAttribs( pRight );
2284 : : // then the Text...
2285 : 810 : pLeft->Append(pRight->GetString());
2286 : :
2287 : : // the one to the right disappears.
2288 : 810 : RemoveItemsFromPool(*pRight);
2289 : 810 : sal_uInt16 nRight = GetPos( pRight );
2290 : 810 : Remove( nRight );
2291 : :
2292 : 810 : SetModified(true);
2293 : :
2294 : 810 : return aPaM;
2295 : : }
2296 : :
2297 : 1848 : EditPaM EditDoc::RemoveChars( EditPaM aPaM, sal_uInt16 nChars )
2298 : : {
2299 : : // Maybe remove Features!
2300 : 1848 : aPaM.GetNode()->Erase( aPaM.GetIndex(), nChars );
2301 : 1848 : aPaM.GetNode()->CollapsAttribs( aPaM.GetIndex(), nChars, GetItemPool() );
2302 : :
2303 : 1848 : SetModified( sal_True );
2304 : :
2305 : 1848 : return aPaM;
2306 : : }
2307 : :
2308 : 14617 : void EditDoc::InsertAttribInSelection( ContentNode* pNode, sal_uInt16 nStart, sal_uInt16 nEnd, const SfxPoolItem& rPoolItem )
2309 : : {
2310 : : DBG_ASSERT( pNode, "What to do with the attribute?" );
2311 : : DBG_ASSERT( nEnd <= pNode->Len(), "InsertAttrib: Attribute to large!" );
2312 : :
2313 : : // for Optimization:
2314 : : // This ends at the beginning of the selection => can be expanded
2315 : 14617 : EditCharAttrib* pEndingAttrib = 0;
2316 : : // This starts at the end of the selection => can be expanded
2317 : 14617 : EditCharAttrib* pStartingAttrib = 0;
2318 : :
2319 : : DBG_ASSERT( nStart <= nEnd, "Small miscalculations in InsertAttribInSelection" );
2320 : :
2321 [ + - ]: 14617 : RemoveAttribs( pNode, nStart, nEnd, pStartingAttrib, pEndingAttrib, rPoolItem.Which() );
2322 : :
2323 [ - + ][ # # ]: 14617 : if ( pStartingAttrib && pEndingAttrib &&
[ # # ][ # # ]
[ - + ]
2324 [ # # ]: 0 : ( *(pStartingAttrib->GetItem()) == rPoolItem ) &&
2325 [ # # ]: 0 : ( *(pEndingAttrib->GetItem()) == rPoolItem ) )
2326 : : {
2327 : : // Will become a large Attribute.
2328 : 0 : pEndingAttrib->GetEnd() = pStartingAttrib->GetEnd();
2329 [ # # ]: 0 : GetItemPool().Remove( *(pStartingAttrib->GetItem()) );
2330 [ # # ]: 0 : pNode->GetCharAttribs().Remove(pStartingAttrib);
2331 : : }
2332 [ - + ][ # # ]: 14617 : else if ( pStartingAttrib && ( *(pStartingAttrib->GetItem()) == rPoolItem ) )
[ # # ][ - + ]
2333 : 0 : pStartingAttrib->GetStart() = nStart;
2334 [ + + ][ + - ]: 14617 : else if ( pEndingAttrib && ( *(pEndingAttrib->GetItem()) == rPoolItem ) )
[ + + ][ + + ]
2335 : 1899 : pEndingAttrib->GetEnd() = nEnd;
2336 : : else
2337 [ + - ]: 12718 : InsertAttrib( rPoolItem, pNode, nStart, nEnd );
2338 : :
2339 [ - + ]: 14617 : if ( pStartingAttrib )
2340 [ # # ]: 0 : pNode->GetCharAttribs().ResortAttribs();
2341 : :
2342 [ + - ]: 14617 : SetModified(true);
2343 : 14617 : }
2344 : :
2345 : 76 : sal_Bool EditDoc::RemoveAttribs( ContentNode* pNode, sal_uInt16 nStart, sal_uInt16 nEnd, sal_uInt16 nWhich )
2346 : : {
2347 : : EditCharAttrib* pStarting;
2348 : : EditCharAttrib* pEnding;
2349 [ + - ]: 76 : return RemoveAttribs( pNode, nStart, nEnd, pStarting, pEnding, nWhich );
2350 : : }
2351 : :
2352 : 14693 : sal_Bool EditDoc::RemoveAttribs( ContentNode* pNode, sal_uInt16 nStart, sal_uInt16 nEnd, EditCharAttrib*& rpStarting, EditCharAttrib*& rpEnding, sal_uInt16 nWhich )
2353 : : {
2354 : :
2355 : : DBG_ASSERT( pNode, "What to do with the attribute?" );
2356 : : DBG_ASSERT( nEnd <= pNode->Len(), "InsertAttrib: Attribute to large!" );
2357 : :
2358 : : // This ends at the beginning of the selection => can be expanded
2359 : 14693 : rpEnding = 0;
2360 : : // This starts at the end of the selection => can be expanded
2361 : 14693 : rpStarting = 0;
2362 : :
2363 : 14693 : bool bChanged = false;
2364 : :
2365 : : DBG_ASSERT( nStart <= nEnd, "Small miscalculations in InsertAttribInSelection" );
2366 : :
2367 : : // iterate over the attributes ...
2368 : 14693 : size_t nAttr = 0;
2369 : 14693 : CharAttribList::AttribsType& rAttribs = pNode->GetCharAttribs().GetAttribs();
2370 : 14693 : EditCharAttrib* pAttr = GetAttrib(rAttribs, nAttr);
2371 [ + + ]: 181487 : while ( pAttr )
2372 : : {
2373 : 166794 : bool bRemoveAttrib = false;
2374 : 166794 : sal_uInt16 nAttrWhich = pAttr->Which();
2375 [ + - ][ + + ]: 166794 : if ( ( nAttrWhich < EE_FEATURE_START ) && ( !nWhich || ( nAttrWhich == nWhich ) ) )
[ + + ]
2376 : : {
2377 : : // Attribute starts in Selection
2378 [ + + ][ + - ]: 4315 : if ( ( pAttr->GetStart() >= nStart ) && ( pAttr->GetStart() <= nEnd ) )
[ + + ]
2379 : : {
2380 : 2155 : bChanged = sal_True;
2381 [ - + ]: 2155 : if ( pAttr->GetEnd() > nEnd )
2382 : : {
2383 : 0 : pAttr->GetStart() = nEnd; // then it starts after this
2384 : 0 : rpStarting = pAttr;
2385 [ # # ]: 0 : if ( nWhich )
2386 : 0 : break; // There can be no further attributes here
2387 : : }
2388 [ - + ][ # # ]: 2155 : else if ( !pAttr->IsFeature() || ( pAttr->GetStart() == nStart ) )
[ + - ]
2389 : : {
2390 : : // Delete feature only if on the exact spot
2391 : 2155 : bRemoveAttrib = sal_True;
2392 : : }
2393 : : }
2394 : :
2395 : : // Attribute ends in Selection
2396 [ + + ][ + - ]: 2160 : else if ( ( pAttr->GetEnd() >= nStart ) && ( pAttr->GetEnd() <= nEnd ) )
[ + + ]
2397 : : {
2398 : 2064 : bChanged = sal_True;
2399 [ + - ][ + - ]: 2064 : if ( ( pAttr->GetStart() < nStart ) && !pAttr->IsFeature() )
[ + - ]
2400 : : {
2401 : 2064 : pAttr->GetEnd() = nStart; // then it ends here
2402 : 2064 : rpEnding = pAttr;
2403 : : }
2404 [ # # ][ # # ]: 0 : else if ( !pAttr->IsFeature() || ( pAttr->GetStart() == nStart ) )
[ # # ]
2405 : : {
2406 : : // Delete feature only if on the exact spot
2407 : 0 : bRemoveAttrib = sal_True;
2408 : : }
2409 : : }
2410 : : // Attribute overlaps the selection
2411 [ + - ][ - + ]: 96 : else if ( ( pAttr->GetStart() <= nStart ) && ( pAttr->GetEnd() >= nEnd ) )
[ - + ]
2412 : : {
2413 : 0 : bChanged = sal_True;
2414 [ # # ]: 0 : if ( pAttr->GetStart() == nStart )
2415 : : {
2416 : 0 : pAttr->GetStart() = nEnd;
2417 : 0 : rpStarting = pAttr;
2418 [ # # ]: 0 : if ( nWhich )
2419 : 0 : break; // There can be further attributes!
2420 : : }
2421 [ # # ]: 0 : else if ( pAttr->GetEnd() == nEnd )
2422 : : {
2423 : 0 : pAttr->GetEnd() = nStart;
2424 : 0 : rpEnding = pAttr;
2425 [ # # ]: 0 : if ( nWhich )
2426 : 0 : break; // There can be further attributes!
2427 : : }
2428 : : else // Attribute must be split ...
2429 : : {
2430 : 0 : sal_uInt16 nOldEnd = pAttr->GetEnd();
2431 : 0 : pAttr->GetEnd() = nStart;
2432 : 0 : rpEnding = pAttr;
2433 : 0 : InsertAttrib( *pAttr->GetItem(), pNode, nEnd, nOldEnd );
2434 [ # # ]: 0 : if ( nWhich )
2435 : 0 : break; // There can be further attributes!
2436 : : }
2437 : : }
2438 : : }
2439 [ + + ]: 166794 : if ( bRemoveAttrib )
2440 : : {
2441 : : DBG_ASSERT( ( pAttr != rpStarting ) && ( pAttr != rpEnding ), "Delete and retain the same attribute?" );
2442 : : DBG_ASSERT( !pAttr->IsFeature(), "RemoveAttribs: Remove a feature?!" );
2443 : 2155 : GetItemPool().Remove( *pAttr->GetItem() );
2444 : 2155 : rAttribs.erase(rAttribs.begin()+nAttr);
2445 : 2155 : nAttr--;
2446 : : }
2447 : 166794 : nAttr++;
2448 : 166794 : pAttr = GetAttrib(rAttribs, nAttr);
2449 : : }
2450 : :
2451 [ + + ]: 14693 : if ( bChanged )
2452 : : {
2453 : : // char attributes need to be sorted by start again
2454 : 4219 : pNode->GetCharAttribs().ResortAttribs();
2455 : 4219 : SetModified(true);
2456 : : }
2457 : :
2458 : 14693 : return bChanged;
2459 : : }
2460 : :
2461 : 15797 : void EditDoc::InsertAttrib( const SfxPoolItem& rPoolItem, ContentNode* pNode, sal_uInt16 nStart, sal_uInt16 nEnd )
2462 : : {
2463 : : // This method no longer checks whether a corresponding attribute already
2464 : : // exists at this place!
2465 : 15797 : EditCharAttrib* pAttrib = MakeCharAttrib( GetItemPool(), rPoolItem, nStart, nEnd );
2466 : : DBG_ASSERT( pAttrib, "MakeCharAttrib failed!" );
2467 : 15797 : pNode->GetCharAttribs().InsertAttrib( pAttrib );
2468 : :
2469 : 15797 : SetModified( sal_True );
2470 : 15797 : }
2471 : :
2472 : 17924 : void EditDoc::InsertAttrib( ContentNode* pNode, sal_uInt16 nStart, sal_uInt16 nEnd, const SfxPoolItem& rPoolItem )
2473 : : {
2474 [ + + ]: 17924 : if ( nStart != nEnd )
2475 : : {
2476 : 14617 : InsertAttribInSelection( pNode, nStart, nEnd, rPoolItem );
2477 : : }
2478 : : else
2479 : : {
2480 : : // Check whether already a new attribute with WhichId exists at this place:
2481 : 3307 : CharAttribList& rAttrList = pNode->GetCharAttribs();
2482 : 3307 : EditCharAttrib* pAttr = rAttrList.FindEmptyAttrib( rPoolItem.Which(), nStart );
2483 [ + + ]: 3307 : if ( pAttr )
2484 : : {
2485 : : // Remove attribute....
2486 : 481 : rAttrList.Release(pAttr);
2487 : : }
2488 : :
2489 : : // check whether 'the same' attribute exist at this place.
2490 : 3307 : pAttr = rAttrList.FindAttrib( rPoolItem.Which(), nStart );
2491 [ + + ]: 3307 : if ( pAttr )
2492 : : {
2493 [ - + ]: 252 : if ( pAttr->IsInside( nStart ) ) // split
2494 : : {
2495 : : // check again if really splitting, or return !
2496 : 0 : sal_uInt16 nOldEnd = pAttr->GetEnd();
2497 : 0 : pAttr->GetEnd() = nStart;
2498 : 0 : EditCharAttrib* pNew = MakeCharAttrib( GetItemPool(), *(pAttr->GetItem()), nStart, nOldEnd );
2499 : 0 : rAttrList.InsertAttrib(pNew);
2500 : : }
2501 [ + - ]: 252 : else if ( pAttr->GetEnd() == nStart )
2502 : : {
2503 : : DBG_ASSERT( !pAttr->IsEmpty(), "Still an empty attribute?" );
2504 : : // Check if exactly the same attribute
2505 [ + + ]: 252 : if ( *(pAttr->GetItem()) == rPoolItem )
2506 : 17924 : return;
2507 : : }
2508 : : }
2509 : 3079 : InsertAttrib( rPoolItem, pNode, nStart, nStart );
2510 : : }
2511 : :
2512 : 17696 : SetModified( sal_True );
2513 : : }
2514 : :
2515 : 4412 : void EditDoc::FindAttribs( ContentNode* pNode, sal_uInt16 nStartPos, sal_uInt16 nEndPos, SfxItemSet& rCurSet )
2516 : : {
2517 : : DBG_ASSERT( pNode, "Where to search?" );
2518 : : DBG_ASSERT( nStartPos <= nEndPos, "Invalid region!" );
2519 : :
2520 : 4412 : sal_uInt16 nAttr = 0;
2521 : 4412 : EditCharAttrib* pAttr = GetAttrib( pNode->GetCharAttribs().GetAttribs(), nAttr );
2522 : : // No Selection...
2523 [ + + ]: 4412 : if ( nStartPos == nEndPos )
2524 : : {
2525 [ + + ][ + + ]: 10568 : while ( pAttr && ( pAttr->GetStart() <= nEndPos) )
[ + + ]
2526 : : {
2527 : 7399 : const SfxPoolItem* pItem = 0;
2528 : : // Attribute is about...
2529 [ - + ][ # # ]: 7399 : if ( ( pAttr->GetStart() < nStartPos ) && ( pAttr->GetEnd() > nStartPos ) )
[ - + ]
2530 : 0 : pItem = pAttr->GetItem();
2531 : : // Attribute ending here is not empty
2532 [ - + ][ # # ]: 7399 : else if ( ( pAttr->GetStart() < nStartPos ) && ( pAttr->GetEnd() == nStartPos ) )
[ - + ]
2533 : : {
2534 [ # # ]: 0 : if ( !pNode->GetCharAttribs().FindEmptyAttrib( pAttr->GetItem()->Which(), nStartPos ) )
2535 : 0 : pItem = pAttr->GetItem();
2536 : : }
2537 : : // Attribute ending here is empty
2538 [ + - ][ + + ]: 7399 : else if ( ( pAttr->GetStart() == nStartPos ) && ( pAttr->GetEnd() == nStartPos ) )
[ + + ]
2539 : : {
2540 : 7162 : pItem = pAttr->GetItem();
2541 : : }
2542 : : // Attribute starts here
2543 [ + - ][ + - ]: 237 : else if ( ( pAttr->GetStart() == nStartPos ) && ( pAttr->GetEnd() > nStartPos ) )
[ + - ]
2544 : : {
2545 [ + - ]: 237 : if ( nStartPos == 0 ) // special case
2546 : 237 : pItem = pAttr->GetItem();
2547 : : }
2548 : :
2549 [ + - ]: 7399 : if ( pItem )
2550 : : {
2551 : 7399 : sal_uInt16 nWhich = pItem->Which();
2552 [ + + ]: 7399 : if ( rCurSet.GetItemState( nWhich ) == SFX_ITEM_OFF )
2553 : : {
2554 : 273 : rCurSet.Put( *pItem );
2555 : : }
2556 [ + - ]: 7126 : else if ( rCurSet.GetItemState( nWhich ) == SFX_ITEM_ON )
2557 : : {
2558 : 7126 : const SfxPoolItem& rItem = rCurSet.Get( nWhich );
2559 [ - + ]: 7126 : if ( rItem != *pItem )
2560 : : {
2561 : 0 : rCurSet.InvalidateItem( nWhich );
2562 : : }
2563 : : }
2564 : : }
2565 : 7399 : nAttr++;
2566 : 7399 : pAttr = GetAttrib( pNode->GetCharAttribs().GetAttribs(), nAttr );
2567 : : }
2568 : : }
2569 : : else // Selection
2570 : : {
2571 [ + + ][ + - ]: 26173 : while ( pAttr && ( pAttr->GetStart() < nEndPos) )
[ + + ]
2572 : : {
2573 : 24930 : const SfxPoolItem* pItem = 0;
2574 : : // Attribut is about...
2575 [ + + ][ + + ]: 24930 : if ( ( pAttr->GetStart() <= nStartPos ) && ( pAttr->GetEnd() >= nEndPos ) )
[ + + ]
2576 : 24926 : pItem = pAttr->GetItem();
2577 : : // Attribute starts right in the middle ...
2578 [ + - ]: 4 : else if ( pAttr->GetStart() >= nStartPos )
2579 : : {
2580 : : // !!! pItem = pAttr->GetItem();
2581 : : // PItem is simply not enough, since one for example in case
2582 : : // of Shadow, would never find an unequal item, since such a
2583 : : // item represents its presence by absence!
2584 : : // If (...)
2585 : : // It needs to be examined on exactly the same attribute at the
2586 : : // breaki point, which is quite expensive.
2587 : : // Since optimazation is done when inserting the attributes
2588 : : // this case does not appear so fast ...
2589 : : // So based on the need for speed:
2590 : 4 : rCurSet.InvalidateItem( pAttr->GetItem()->Which() );
2591 : :
2592 : : }
2593 : : // Attribute ends in the middle of it ...
2594 [ # # ]: 0 : else if ( pAttr->GetEnd() > nStartPos )
2595 : : {
2596 : 0 : rCurSet.InvalidateItem( pAttr->GetItem()->Which() );
2597 : : }
2598 : :
2599 [ + + ]: 24930 : if ( pItem )
2600 : : {
2601 : 24926 : sal_uInt16 nWhich = pItem->Which();
2602 [ + + ]: 24926 : if ( rCurSet.GetItemState( nWhich ) == SFX_ITEM_OFF )
2603 : : {
2604 : 10674 : rCurSet.Put( *pItem );
2605 : : }
2606 [ + - ]: 14252 : else if ( rCurSet.GetItemState( nWhich ) == SFX_ITEM_ON )
2607 : : {
2608 : 14252 : const SfxPoolItem& rItem = rCurSet.Get( nWhich );
2609 [ - + ]: 14252 : if ( rItem != *pItem )
2610 : : {
2611 : 0 : rCurSet.InvalidateItem( nWhich );
2612 : : }
2613 : : }
2614 : : }
2615 : 24930 : nAttr++;
2616 : 24930 : pAttr = GetAttrib( pNode->GetCharAttribs().GetAttribs(), nAttr );
2617 : : }
2618 : : }
2619 : 4412 : }
2620 : :
2621 : : namespace {
2622 : :
2623 : : struct LessByStart : std::binary_function<EditCharAttrib, EditCharAttrib, bool>
2624 : : {
2625 : 169217 : bool operator() (const EditCharAttrib& left, const EditCharAttrib& right) const
2626 : : {
2627 : 169217 : return left.GetStart() < right.GetStart();
2628 : : }
2629 : : };
2630 : :
2631 : : }
2632 : :
2633 [ + - ]: 321088 : CharAttribList::CharAttribList()
2634 : : {
2635 : : DBG_CTOR( EE_CharAttribList, 0 );
2636 : 321088 : bHasEmptyAttribs = sal_False;
2637 : 321088 : }
2638 : :
2639 [ + - ]: 320840 : CharAttribList::~CharAttribList()
2640 : : {
2641 : : DBG_DTOR( EE_CharAttribList, 0 );
2642 : 320840 : }
2643 : :
2644 : 90490 : void CharAttribList::InsertAttrib( EditCharAttrib* pAttrib )
2645 : : {
2646 : : // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2647 : : // optimize: binary search? !
2648 : : // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2649 : :
2650 : : // Maybe just simply iterate backwards:
2651 : : // The most common and critical case: Attributes are already sorted
2652 : : // (InsertBinTextObject!) binary search would not be optimal here.
2653 : : // => Would bring something!
2654 : :
2655 : 90490 : const sal_uInt16 nStart = pAttrib->GetStart(); // may be better for Comp.Opt.
2656 : :
2657 [ + + ]: 90490 : if ( pAttrib->IsEmpty() )
2658 : 13904 : bHasEmptyAttribs = true;
2659 : :
2660 [ + + ]: 1018833 : for (size_t i = 0, n = aAttribs.size(); i < n; ++i)
2661 : : {
2662 : 931212 : const EditCharAttrib& rCurAttrib = aAttribs[i];
2663 [ + + ]: 931212 : if (rCurAttrib.GetStart() > nStart)
2664 : : {
2665 : 2869 : aAttribs.insert(aAttribs.begin()+i, pAttrib);
2666 : 90490 : return;
2667 : : }
2668 : : }
2669 : :
2670 : 87621 : aAttribs.push_back(pAttrib);
2671 : : }
2672 : :
2673 : 4710 : void CharAttribList::ResortAttribs()
2674 : : {
2675 [ + - ]: 4710 : aAttribs.sort(LessByStart());
2676 : 4710 : }
2677 : :
2678 : 15694 : void CharAttribList::OptimizeRanges( SfxItemPool& rItemPool )
2679 : : {
2680 [ + + ]: 92489 : for (size_t i = 0; i < aAttribs.size(); ++i)
2681 : : {
2682 : 76795 : EditCharAttrib& rAttr = aAttribs[i];
2683 [ + + ]: 885322 : for (size_t nNext = i+1; nNext < aAttribs.size(); ++nNext)
2684 : : {
2685 : 809114 : EditCharAttrib& rNext = aAttribs[nNext];
2686 [ + + ][ + + ]: 809114 : if (!rAttr.IsFeature() && rNext.GetStart() == rAttr.GetEnd() && rNext.Which() == rAttr.Which())
[ + + ][ + + ]
2687 : : {
2688 [ - + ]: 84 : if (*rNext.GetItem() == *rAttr.GetItem())
2689 : : {
2690 : 0 : rAttr.GetEnd() = rNext.GetEnd();
2691 : 0 : rItemPool.Remove(*rNext.GetItem());
2692 : 0 : aAttribs.erase(aAttribs.begin()+nNext);
2693 : : }
2694 : 84 : break; // only 1 attr with same which can start here.
2695 : : }
2696 [ + + ]: 809030 : else if (rNext.GetStart() > rAttr.GetEnd())
2697 : : {
2698 : 503 : break;
2699 : : }
2700 : : }
2701 : : }
2702 : 15694 : }
2703 : :
2704 : 583232 : size_t CharAttribList::Count() const
2705 : : {
2706 : 583232 : return aAttribs.size();
2707 : : }
2708 : :
2709 : 228959 : const EditCharAttrib* CharAttribList::FindAttrib( sal_uInt16 nWhich, sal_uInt16 nPos ) const
2710 : : {
2711 : : // Backwards, if one ends where the next starts.
2712 : : // => The starting one is the valid one ...
2713 [ + - ][ + - ]: 228959 : AttribsType::const_reverse_iterator it = aAttribs.rbegin(), itEnd = aAttribs.rend();
2714 [ + - ][ + - ]: 279876 : for (; it != itEnd; ++it)
[ + + ]
2715 : : {
2716 [ + - ]: 54670 : const EditCharAttrib& rAttr = *it;
2717 [ + + ][ + + ]: 54670 : if (rAttr.Which() == nWhich && rAttr.IsIn(nPos))
[ + + ]
2718 : 3753 : return &rAttr;
2719 : : }
2720 : 228959 : return NULL;
2721 : : }
2722 : :
2723 : 11236 : EditCharAttrib* CharAttribList::FindAttrib( sal_uInt16 nWhich, sal_uInt16 nPos )
2724 : : {
2725 : : // Backwards, if one ends where the next starts.
2726 : : // => The starting one is the valid one ...
2727 [ + - ][ + - ]: 11236 : AttribsType::reverse_iterator it = aAttribs.rbegin(), itEnd = aAttribs.rend();
2728 [ + - ][ + - ]: 56973 : for (; it != itEnd; ++it)
[ + + ]
2729 : : {
2730 [ + - ]: 46562 : EditCharAttrib& rAttr = *it;
2731 [ + + ][ + - ]: 46562 : if (rAttr.Which() == nWhich && rAttr.IsIn(nPos))
[ + + ]
2732 : 825 : return &rAttr;
2733 : : }
2734 : 11236 : return NULL;
2735 : : }
2736 : :
2737 : 185833 : const EditCharAttrib* CharAttribList::FindNextAttrib( sal_uInt16 nWhich, sal_uInt16 nFromPos ) const
2738 : : {
2739 : : DBG_ASSERT( nWhich, "FindNextAttrib: Which?" );
2740 [ + - ][ + - ]: 185833 : AttribsType::const_iterator it = aAttribs.begin(), itEnd = aAttribs.end();
2741 [ + - ][ + - ]: 299401 : for (; it != itEnd; ++it)
[ + + ]
2742 : : {
2743 [ + - ]: 124668 : const EditCharAttrib& rAttr = *it;
2744 [ + + ][ + + ]: 124668 : if (rAttr.GetStart() >= nFromPos && rAttr.Which() == nWhich)
[ + + ]
2745 : 11100 : return &rAttr;
2746 : : }
2747 : 185833 : return NULL;
2748 : : }
2749 : :
2750 : 0 : bool CharAttribList::HasAttrib( sal_uInt16 nStartPos, sal_uInt16 nEndPos ) const
2751 : : {
2752 [ # # ][ # # ]: 0 : AttribsType::const_reverse_iterator it = aAttribs.rbegin(), itEnd = aAttribs.rend();
2753 [ # # ][ # # ]: 0 : for (; it != itEnd; ++it)
[ # # ]
2754 : : {
2755 [ # # ]: 0 : const EditCharAttrib& rAttr = *it;
2756 [ # # ][ # # ]: 0 : if (rAttr.GetStart() < nEndPos && rAttr.GetEnd() > nStartPos)
[ # # ]
2757 : 0 : return true;
2758 : : }
2759 : 0 : return false;
2760 : : }
2761 : :
2762 : 1370446 : CharAttribList::AttribsType& CharAttribList::GetAttribs()
2763 : : {
2764 : 1370446 : return aAttribs;
2765 : : }
2766 : :
2767 : 89565 : const CharAttribList::AttribsType& CharAttribList::GetAttribs() const
2768 : : {
2769 : 89565 : return aAttribs;
2770 : : }
2771 : :
2772 : : namespace {
2773 : :
2774 : : class FindByAddress : std::unary_function<EditCharAttrib, bool>
2775 : : {
2776 : : const EditCharAttrib* mpAttr;
2777 : : public:
2778 : 481 : FindByAddress(const EditCharAttrib* p) : mpAttr(p) {}
2779 : 4275 : bool operator() (const EditCharAttrib& r) const
2780 : : {
2781 : 4275 : return &r == mpAttr;
2782 : : }
2783 : : };
2784 : :
2785 : : }
2786 : :
2787 : 0 : void CharAttribList::Remove(const EditCharAttrib* p)
2788 : : {
2789 [ # # ][ # # ]: 0 : AttribsType::iterator it = std::find_if(aAttribs.begin(), aAttribs.end(), FindByAddress(p));
[ # # ]
2790 [ # # ][ # # ]: 0 : if (it != aAttribs.end())
[ # # ]
2791 [ # # ]: 0 : aAttribs.erase(it);
2792 : 0 : }
2793 : :
2794 : 258 : void CharAttribList::Remove(size_t nPos)
2795 : : {
2796 [ - + ]: 258 : if (nPos >= aAttribs.size())
2797 : 258 : return;
2798 : :
2799 : 258 : aAttribs.erase(aAttribs.begin()+nPos);
2800 : : }
2801 : :
2802 : 481 : void CharAttribList::Release(const EditCharAttrib* p)
2803 : : {
2804 [ + - ][ + - ]: 481 : AttribsType::iterator it = std::find_if(aAttribs.begin(), aAttribs.end(), FindByAddress(p));
[ + - ]
2805 [ + - ][ + - ]: 481 : if (it != aAttribs.end())
[ + - ]
2806 [ + - ][ + - ]: 481 : aAttribs.release(it).release();
[ + - ]
2807 : 481 : }
2808 : :
2809 : 0 : void CharAttribList::SetHasEmptyAttribs(bool b)
2810 : : {
2811 : 0 : bHasEmptyAttribs = b;
2812 : 0 : }
2813 : :
2814 : 56 : bool CharAttribList::HasBoundingAttrib( sal_uInt16 nBound ) const
2815 : : {
2816 : : // Backwards, if one ends where the next starts.
2817 : : // => The starting one is the valid one ...
2818 [ + - ][ + - ]: 56 : AttribsType::const_reverse_iterator it = aAttribs.rbegin(), itEnd = aAttribs.rend();
2819 [ # # ][ + - ]: 56 : for (; it != itEnd; ++it)
[ + + ]
2820 : : {
2821 [ + - ]: 6 : const EditCharAttrib& rAttr = *it;
2822 [ - + ]: 6 : if (rAttr.GetEnd() < nBound)
2823 : 0 : return false;
2824 : :
2825 [ - + ][ # # ]: 6 : if (rAttr.GetStart() == nBound || rAttr.GetEnd() == nBound)
[ + - ]
2826 : 6 : return true;
2827 : : }
2828 : 56 : return false;
2829 : : }
2830 : :
2831 : 0 : const EditCharAttrib* CharAttribList::FindEmptyAttrib( sal_uInt16 nWhich, sal_uInt16 nPos ) const
2832 : : {
2833 [ # # ]: 0 : if ( !bHasEmptyAttribs )
2834 : 0 : return NULL;
2835 : :
2836 [ # # ][ # # ]: 0 : AttribsType::const_iterator it = aAttribs.begin(), itEnd = aAttribs.end();
2837 [ # # ][ # # ]: 0 : for (; it != itEnd; ++it)
[ # # ]
2838 : : {
2839 [ # # ]: 0 : const EditCharAttrib& rAttr = *it;
2840 [ # # ][ # # ]: 0 : if (rAttr.GetStart() == nPos && rAttr.GetEnd() == nPos && rAttr.Which() == nWhich)
[ # # ][ # # ]
2841 : 0 : return &rAttr;
2842 : : }
2843 : 0 : return NULL;
2844 : : }
2845 : :
2846 : 3559 : EditCharAttrib* CharAttribList::FindEmptyAttrib( sal_uInt16 nWhich, sal_uInt16 nPos )
2847 : : {
2848 [ + + ]: 3559 : if ( !bHasEmptyAttribs )
2849 : 293 : return NULL;
2850 : :
2851 [ + - ][ + - ]: 3266 : AttribsType::iterator it = aAttribs.begin(), itEnd = aAttribs.end();
2852 [ + - ][ + - ]: 32820 : for (; it != itEnd; ++it)
[ + + ]
2853 : : {
2854 [ + - ]: 30059 : EditCharAttrib& rAttr = *it;
2855 [ + + ][ + - ]: 30059 : if (rAttr.GetStart() == nPos && rAttr.GetEnd() == nPos && rAttr.Which() == nWhich)
[ + + ][ + + ]
2856 : 505 : return &rAttr;
2857 : : }
2858 : 3559 : return NULL;
2859 : : }
2860 : :
2861 : : namespace {
2862 : :
2863 : : class FindByStartPos : std::unary_function<EditCharAttrib, bool>
2864 : : {
2865 : : sal_uInt16 mnPos;
2866 : : public:
2867 : 244819 : FindByStartPos(sal_uInt16 nPos) : mnPos(nPos) {}
2868 : 62507 : bool operator() (const EditCharAttrib& r) const
2869 : : {
2870 : 62507 : return r.GetStart() >= mnPos;
2871 : : }
2872 : : };
2873 : :
2874 : : }
2875 : :
2876 : 244819 : const EditCharAttrib* CharAttribList::FindFeature( sal_uInt16 nPos ) const
2877 : : {
2878 : : // First, find the first attribute that starts at or after specified position.
2879 : : AttribsType::const_iterator it =
2880 [ + - ][ + - ]: 244819 : std::find_if(aAttribs.begin(), aAttribs.end(), FindByStartPos(nPos));
[ + - ]
2881 : :
2882 [ + - ][ + - ]: 244819 : if (it == aAttribs.end())
[ + + ]
2883 : : // All attributes are before the specified position.
2884 : 233532 : return NULL;
2885 : :
2886 : : // And find the first attribute with feature.
2887 [ + - ][ + - ]: 11287 : it = std::find_if(it, aAttribs.end(), boost::bind(&EditCharAttrib::IsFeature, _1) == true);
[ + - ][ + - ]
2888 [ + - ][ + - ]: 244819 : return it == aAttribs.end() ? NULL : &(*it);
[ + + ][ + - ]
2889 : : }
2890 : :
2891 : : namespace {
2892 : :
2893 : : class RemoveEmptyAttrItem : std::unary_function<EditCharAttrib, void>
2894 : : {
2895 : : SfxItemPool& mrItemPool;
2896 : : public:
2897 : 78 : RemoveEmptyAttrItem(SfxItemPool& rPool) : mrItemPool(rPool) {}
2898 : 195 : void operator() (const EditCharAttrib& r)
2899 : : {
2900 [ - + ]: 195 : if (r.IsEmpty())
2901 : 0 : mrItemPool.Remove(*r.GetItem());
2902 : 195 : }
2903 : : };
2904 : :
2905 : : }
2906 : :
2907 : 78 : void CharAttribList::DeleteEmptyAttribs( SfxItemPool& rItemPool )
2908 : : {
2909 [ + - ][ + - ]: 78 : std::for_each(aAttribs.begin(), aAttribs.end(), RemoveEmptyAttrItem(rItemPool));
[ + - ]
2910 [ + - ][ + - ]: 78 : aAttribs.erase_if(boost::bind(&EditCharAttrib::IsEmpty, _1) == true);
2911 : 78 : bHasEmptyAttribs = false;
2912 : 78 : }
2913 : :
2914 : : #if OSL_DEBUG_LEVEL > 2
2915 : : bool CharAttribList::DbgCheckAttribs() const
2916 : : {
2917 : : bool bOK = true;
2918 : : AttribsType::const_iterator it = aAttribs.begin(), itEnd = aAttribs.end();
2919 : : for (; it != itEnd; ++it)
2920 : : {
2921 : : const EditCharAttrib& rAttr = *it;
2922 : : if (rAttr.GetStart() > rAttr.GetEnd())
2923 : : {
2924 : : bOK = false;
2925 : : OSL_FAIL( "Attribute is distorted" );
2926 : : }
2927 : : else if (rAttr.IsFeature() && rAttr.GetLen() != 1)
2928 : : {
2929 : : bOK = false;
2930 : : OSL_FAIL( "Feature, Len != 1" );
2931 : : }
2932 : : }
2933 : : return bOK;
2934 : : }
2935 : : #endif
2936 : :
2937 : :
2938 : 0 : SvxColorList::SvxColorList()
2939 : : {
2940 : 0 : }
2941 : :
2942 : 0 : SvxColorList::~SvxColorList()
2943 : : {
2944 [ # # ]: 0 : for ( size_t i = 0, n = aColorList.size(); i < n; ++i )
2945 [ # # ][ # # ]: 0 : delete aColorList[ i ];
[ # # ]
2946 : 0 : aColorList.clear();
2947 : 0 : }
2948 : :
2949 : 0 : size_t SvxColorList::GetId( const SvxColorItem& rColorItem )
2950 : : {
2951 [ # # ]: 0 : for ( size_t i = 0, n = aColorList.size(); i < n; ++i )
2952 [ # # ]: 0 : if ( *aColorList[ i ] == rColorItem )
2953 : 0 : return i;
2954 : : DBG_WARNING( "Color not found: GetId()" );
2955 : 0 : return 0;
2956 : : }
2957 : :
2958 : 0 : void SvxColorList::Insert( SvxColorItem* pItem, size_t nIndex )
2959 : : {
2960 [ # # ]: 0 : if ( nIndex >= aColorList.size() )
2961 : : {
2962 : 0 : aColorList.push_back( pItem );
2963 : : }
2964 : : else
2965 : : {
2966 : 0 : DummyColorList::iterator it = aColorList.begin();
2967 [ # # ]: 0 : ::std::advance( it, nIndex );
2968 [ # # ]: 0 : aColorList.insert( it, pItem );
2969 : : }
2970 : 0 : }
2971 : :
2972 : 0 : SvxColorItem* SvxColorList::GetObject( size_t nIndex )
2973 : : {
2974 [ # # ]: 0 : return ( nIndex >= aColorList.size() ) ? NULL : aColorList[ nIndex ];
2975 : : }
2976 : :
2977 : 31729 : EditEngineItemPool::EditEngineItemPool( sal_Bool bPersistenRefCounts )
2978 : : : SfxItemPool( String( "EditEngineItemPool", RTL_TEXTENCODING_ASCII_US ), EE_ITEMS_START, EE_ITEMS_END,
2979 [ + - ][ + - ]: 31729 : aItemInfos, 0, bPersistenRefCounts )
2980 : : {
2981 [ + - ]: 31729 : SetVersionMap( 1, 3999, 4015, aV1Map );
2982 [ + - ]: 31729 : SetVersionMap( 2, 3999, 4019, aV2Map );
2983 [ + - ]: 31729 : SetVersionMap( 3, 3997, 4020, aV3Map );
2984 [ + - ]: 31729 : SetVersionMap( 4, 3994, 4022, aV4Map );
2985 [ + - ]: 31729 : SetVersionMap( 5, 3994, 4037, aV5Map );
2986 : :
2987 [ + - ][ + - ]: 31729 : SfxPoolItem** ppDefItems = EE_DLL().GetGlobalData()->GetDefItems();
2988 [ + - ]: 31729 : SetDefaults( ppDefItems );
2989 : 31729 : }
2990 : :
2991 : 28648 : EditEngineItemPool::~EditEngineItemPool()
2992 : : {
2993 [ - + ]: 57296 : }
2994 : :
2995 : 3558 : SvStream& EditEngineItemPool::Store( SvStream& rStream ) const
2996 : : {
2997 : : // for a 3.1 export a hack has to be installed, as in there is a BUG in
2998 : : // SfxItemSet::Load, but not subsequently after 3.1.
2999 : :
3000 : : // The selected range must be kept after Store, because itemsets are not
3001 : : // stored until then...
3002 : :
3003 : 3558 : long nVersion = rStream.GetVersion();
3004 : : sal_Bool b31Format = ( nVersion && ( nVersion <= SOFFICE_FILEFORMAT_31 ) )
3005 [ # # ][ - + ]: 3558 : ? sal_True : sal_False;
3006 : :
3007 : 3558 : EditEngineItemPool* pThis = (EditEngineItemPool*)this;
3008 [ - + ]: 3558 : if ( b31Format )
3009 : 0 : pThis->SetStoringRange( 3997, 4022 );
3010 : : else
3011 : 3558 : pThis->SetStoringRange( EE_ITEMS_START, EE_ITEMS_END );
3012 : :
3013 : 3558 : return SfxItemPool::Store( rStream );
3014 [ + - ][ + - ]: 477 : }
3015 : :
3016 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|