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 <vcl/wrkwin.hxx>
30 : : #include <vcl/dialog.hxx>
31 : : #include <vcl/msgbox.hxx>
32 : : #include <vcl/svapp.hxx>
33 : : #include <impedit.hxx>
34 : : #include <editeng/editeng.hxx>
35 : : #include <editdbg.hxx>
36 : : #include <svl/smplhint.hxx>
37 : : #include <editeng/lrspitem.hxx>
38 : :
39 : 24516 : void ImpEditEngine::SetStyleSheetPool( SfxStyleSheetPool* pSPool )
40 : : {
41 [ + + ]: 24516 : if ( pStylePool != pSPool )
42 : : {
43 : 899 : pStylePool = pSPool;
44 : : }
45 : 24516 : }
46 : :
47 : 0 : const SfxStyleSheet* ImpEditEngine::GetStyleSheet( sal_uInt16 nPara ) const
48 : : {
49 : 0 : const ContentNode* pNode = aEditDoc.GetObject( nPara );
50 [ # # ]: 0 : return pNode ? pNode->GetContentAttribs().GetStyleSheet() : NULL;
51 : : }
52 : :
53 : 2770 : SfxStyleSheet* ImpEditEngine::GetStyleSheet( sal_uInt16 nPara )
54 : : {
55 : 2770 : ContentNode* pNode = aEditDoc.GetObject( nPara );
56 [ + - ]: 2770 : return pNode ? pNode->GetContentAttribs().GetStyleSheet() : NULL;
57 : : }
58 : :
59 : 0 : void ImpEditEngine::SetStyleSheet( EditSelection aSel, SfxStyleSheet* pStyle )
60 : : {
61 : 0 : aSel.Adjust( aEditDoc );
62 : :
63 : 0 : sal_uInt16 nStartPara = aEditDoc.GetPos( aSel.Min().GetNode() );
64 : 0 : sal_uInt16 nEndPara = aEditDoc.GetPos( aSel.Max().GetNode() );
65 : :
66 : 0 : sal_Bool _bUpdate = GetUpdateMode();
67 : 0 : SetUpdateMode( sal_False );
68 : :
69 [ # # ]: 0 : for ( sal_uInt16 n = nStartPara; n <= nEndPara; n++ )
70 : 0 : SetStyleSheet( n, pStyle );
71 : :
72 : 0 : SetUpdateMode( _bUpdate, 0 );
73 : 0 : }
74 : :
75 : 23827 : void ImpEditEngine::SetStyleSheet( sal_uInt16 nPara, SfxStyleSheet* pStyle )
76 : : {
77 : : DBG_ASSERT( GetStyleSheetPool() || !pStyle, "SetStyleSheet: No StyleSheetPool registered!" );
78 : 23827 : ContentNode* pNode = aEditDoc.GetObject( nPara );
79 : 23827 : SfxStyleSheet* pCurStyle = pNode->GetStyleSheet();
80 [ + + ]: 23827 : if ( pStyle != pCurStyle )
81 : : {
82 [ + + ][ + - ]: 20452 : if ( IsUndoEnabled() && !IsInUndo() && aStatus.DoUndoAttribs() )
[ + - ][ + + ]
83 : : {
84 [ + - ]: 1926 : XubString aPrevStyleName;
85 [ + + ]: 1926 : if ( pCurStyle )
86 [ + - ][ + - ]: 1478 : aPrevStyleName = pCurStyle->GetName();
87 : :
88 [ + - ]: 1926 : XubString aNewStyleName;
89 [ + - ]: 1926 : if ( pStyle )
90 [ + - ][ + - ]: 1926 : aNewStyleName = pStyle->GetName();
91 : :
92 : : InsertUndo(
93 [ + - ]: 1926 : new EditUndoSetStyleSheet(pEditEngine, aEditDoc.GetPos( pNode ),
94 : 1478 : aPrevStyleName, pCurStyle ? pCurStyle->GetFamily() : SFX_STYLE_FAMILY_PARA,
95 : 1926 : aNewStyleName, pStyle ? pStyle->GetFamily() : SFX_STYLE_FAMILY_PARA,
96 [ + + ][ + - ]: 1926 : pNode->GetContentAttribs().GetItems() ) );
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
97 : : }
98 [ + + ]: 20452 : if ( pCurStyle )
99 : 1532 : EndListening( *pCurStyle, sal_False );
100 : 20452 : pNode->SetStyleSheet( pStyle, aStatus.UseCharAttribs() );
101 [ + - ]: 20452 : if ( pStyle )
102 : 20452 : StartListening( *pStyle, sal_False );
103 : 20452 : ParaAttribsChanged( pNode );
104 : : }
105 : 23827 : FormatAndUpdate();
106 : 23827 : }
107 : :
108 : 0 : void ImpEditEngine::UpdateParagraphsWithStyleSheet( SfxStyleSheet* pStyle )
109 : : {
110 [ # # ]: 0 : SvxFont aFontFromStyle;
111 [ # # ][ # # ]: 0 : CreateFont( aFontFromStyle, pStyle->GetItemSet() );
112 : :
113 : 0 : sal_Bool bUsed = sal_False;
114 [ # # ][ # # ]: 0 : for ( sal_uInt16 nNode = 0; nNode < aEditDoc.Count(); nNode++ )
115 : : {
116 [ # # ]: 0 : ContentNode* pNode = aEditDoc.GetObject( nNode );
117 [ # # ]: 0 : if ( pNode->GetStyleSheet() == pStyle )
118 : : {
119 : 0 : bUsed = sal_True;
120 [ # # ]: 0 : if ( aStatus.UseCharAttribs() )
121 [ # # ]: 0 : pNode->SetStyleSheet( pStyle, aFontFromStyle );
122 : : else
123 [ # # ]: 0 : pNode->SetStyleSheet( pStyle, sal_False );
124 : :
125 [ # # ]: 0 : ParaAttribsChanged( pNode );
126 : : }
127 : : }
128 [ # # ]: 0 : if ( bUsed )
129 : : {
130 [ # # ]: 0 : GetEditEnginePtr()->StyleSheetChanged( pStyle );
131 [ # # ]: 0 : FormatAndUpdate();
132 [ # # ]: 0 : }
133 : 0 : }
134 : :
135 : 0 : void ImpEditEngine::RemoveStyleFromParagraphs( SfxStyleSheet* pStyle )
136 : : {
137 [ # # ]: 0 : for ( sal_uInt16 nNode = 0; nNode < aEditDoc.Count(); nNode++ )
138 : : {
139 : 0 : ContentNode* pNode = aEditDoc.GetObject(nNode);
140 [ # # ]: 0 : if ( pNode->GetStyleSheet() == pStyle )
141 : : {
142 : 0 : pNode->SetStyleSheet( NULL );
143 : 0 : ParaAttribsChanged( pNode );
144 : : }
145 : : }
146 : 0 : FormatAndUpdate();
147 : 0 : }
148 : :
149 : 0 : void ImpEditEngine::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
150 : : {
151 : : // So that not a lot of unnecessary formatting is done when destructing:
152 [ # # ]: 0 : if ( !bDowning )
153 : : {
154 : : DBG_CHKOBJ( GetEditEnginePtr(), EditEngine, 0 );
155 : :
156 : 0 : SfxStyleSheet* pStyle = NULL;
157 : 0 : sal_uLong nId = 0;
158 : :
159 [ # # ]: 0 : if ( rHint.ISA( SfxStyleSheetHint ) )
160 : : {
161 : 0 : const SfxStyleSheetHint& rH = (const SfxStyleSheetHint&) rHint;
162 : : DBG_ASSERT( rH.GetStyleSheet()->ISA( SfxStyleSheet ), "No SfxStyleSheet!" );
163 : 0 : pStyle = (SfxStyleSheet*) rH.GetStyleSheet();
164 : 0 : nId = rH.GetHint();
165 : : }
166 [ # # ][ # # ]: 0 : else if ( ( rHint.Type() == TYPE(SfxSimpleHint ) ) && ( rBC.ISA( SfxStyleSheet ) ) )
[ # # ]
167 : : {
168 : 0 : pStyle = (SfxStyleSheet*)&rBC;
169 : 0 : nId = ((SfxSimpleHint&)rHint).GetId();
170 : : }
171 : :
172 [ # # ]: 0 : if ( pStyle )
173 : : {
174 [ # # ][ # # ]: 0 : if ( ( nId == SFX_HINT_DYING ) ||
[ # # ]
175 : : ( nId == SFX_STYLESHEET_INDESTRUCTION ) ||
176 : : ( nId == SFX_STYLESHEET_ERASED ) )
177 : : {
178 : 0 : RemoveStyleFromParagraphs( pStyle );
179 : : }
180 [ # # ][ # # ]: 0 : else if ( ( nId == SFX_HINT_DATACHANGED ) ||
181 : : ( nId == SFX_STYLESHEET_MODIFIED ) )
182 : : {
183 : 0 : UpdateParagraphsWithStyleSheet( pStyle );
184 : : }
185 : : }
186 : : }
187 : 0 : }
188 : :
189 : 1700 : EditUndoSetAttribs* ImpEditEngine::CreateAttribUndo( EditSelection aSel, const SfxItemSet& rSet )
190 : : {
191 : : DBG_ASSERT( !aSel.DbgIsBuggy( aEditDoc ), "CreateAttribUndo: Incorrect selection ");
192 [ + - ]: 1700 : aSel.Adjust( aEditDoc );
193 : :
194 [ + - ]: 1700 : ESelection aESel( CreateESel( aSel ) );
195 : :
196 [ + - ][ + - ]: 1700 : sal_uInt16 nStartNode = aEditDoc.GetPos( aSel.Min().GetNode() );
197 [ + - ][ + - ]: 1700 : sal_uInt16 nEndNode = aEditDoc.GetPos( aSel.Max().GetNode() );
198 : :
199 : : DBG_ASSERT( nStartNode <= nEndNode, "CreateAttribUndo: Start > End ?!" );
200 : :
201 : 1700 : EditUndoSetAttribs* pUndo = NULL;
202 [ - + ]: 1700 : if ( rSet.GetPool() != &aEditDoc.GetItemPool() )
203 : : {
204 [ # # ][ # # ]: 0 : SfxItemSet aTmpSet( GetEmptyItemSet() );
205 [ # # ]: 0 : aTmpSet.Put( rSet );
206 [ # # ][ # # ]: 0 : pUndo = new EditUndoSetAttribs(pEditEngine, aESel, aTmpSet);
[ # # ]
207 : : }
208 : : else
209 : : {
210 [ + - ][ + - ]: 1700 : pUndo = new EditUndoSetAttribs(pEditEngine, aESel, rSet);
211 : : }
212 : :
213 : 1700 : SfxItemPool* pPool = pUndo->GetNewAttribs().GetPool();
214 : :
215 [ + + ]: 4120 : for ( sal_uInt16 nPara = nStartNode; nPara <= nEndNode; nPara++ )
216 : : {
217 [ + - ]: 2420 : ContentNode* pNode = aEditDoc.GetObject( nPara );
218 : : DBG_ASSERT( aEditDoc.GetObject( nPara ), "Node not found: CreateAttribUndo" );
219 [ + - ][ + - ]: 2420 : ContentAttribsInfo* pInf = new ContentAttribsInfo( pNode->GetContentAttribs().GetItems() );
220 [ + - ]: 2420 : pUndo->AppendContentInfo(pInf);
221 : :
222 [ + - ][ + + ]: 32899 : for ( sal_uInt16 nAttr = 0; nAttr < pNode->GetCharAttribs().Count(); nAttr++ )
223 : : {
224 [ + - ][ + - ]: 30479 : const EditCharAttrib& rAttr = pNode->GetCharAttribs().GetAttribs()[nAttr];
225 [ + + ]: 30479 : if (rAttr.GetLen())
226 : : {
227 [ + - ]: 18552 : EditCharAttrib* pNew = MakeCharAttrib(*pPool, *rAttr.GetItem(), rAttr.GetStart(), rAttr.GetEnd());
228 [ + - ]: 18552 : pInf->AppendCharAttrib(pNew);
229 : : }
230 : : }
231 : : }
232 : 1700 : return pUndo;
233 : : }
234 : :
235 : 0 : void ImpEditEngine::UndoActionStart( sal_uInt16 nId, const ESelection& aSel )
236 : : {
237 [ # # ][ # # ]: 0 : if ( IsUndoEnabled() && !IsInUndo() )
[ # # ]
238 : : {
239 [ # # ][ # # ]: 0 : GetUndoManager().EnterListAction( GetEditEnginePtr()->GetUndoComment( nId ), XubString(), nId );
[ # # ]
240 : : DBG_ASSERT( !pUndoMarkSelection, "UndoAction SelectionMarker?" );
241 : 0 : pUndoMarkSelection = new ESelection( aSel );
242 : : }
243 : 0 : }
244 : :
245 : 508606 : void ImpEditEngine::UndoActionStart( sal_uInt16 nId )
246 : : {
247 [ + + ][ + - ]: 508606 : if ( IsUndoEnabled() && !IsInUndo() )
[ + + ]
248 : : {
249 [ + - ][ + - ]: 498491 : GetUndoManager().EnterListAction( GetEditEnginePtr()->GetUndoComment( nId ), XubString(), nId );
[ + - ]
250 : : DBG_ASSERT( !pUndoMarkSelection, "UndoAction SelectionMarker?" );
251 : : }
252 : 508606 : }
253 : :
254 : 508606 : void ImpEditEngine::UndoActionEnd( sal_uInt16 )
255 : : {
256 [ + + ][ + - ]: 508606 : if ( IsUndoEnabled() && !IsInUndo() )
[ + + ]
257 : : {
258 : 498491 : GetUndoManager().LeaveListAction();
259 : 498491 : delete pUndoMarkSelection;
260 : 498491 : pUndoMarkSelection = NULL;
261 : : }
262 : 508606 : }
263 : :
264 : 212116 : void ImpEditEngine::InsertUndo( EditUndo* pUndo, bool bTryMerge )
265 : : {
266 : : DBG_ASSERT( !IsInUndo(), "InsertUndo in Undomodus!" );
267 [ - + ]: 212116 : if ( pUndoMarkSelection )
268 : : {
269 [ # # ]: 0 : EditUndoMarkSelection* pU = new EditUndoMarkSelection(pEditEngine, *pUndoMarkSelection);
270 : 0 : GetUndoManager().AddUndoAction( pU, false );
271 : 0 : delete pUndoMarkSelection;
272 : 0 : pUndoMarkSelection = NULL;
273 : : }
274 : 212116 : GetUndoManager().AddUndoAction( pUndo, bTryMerge );
275 : :
276 : 212116 : mbLastTryMerge = bTryMerge;
277 : 212116 : }
278 : :
279 : 717576 : void ImpEditEngine::ResetUndoManager()
280 : : {
281 [ + + ]: 717576 : if ( HasUndoManager() )
282 : 656653 : GetUndoManager().Clear();
283 : 717576 : }
284 : :
285 : 833045 : void ImpEditEngine::EnableUndo( bool bEnable )
286 : : {
287 : : // When switching the mode Delete list:
288 [ + + ]: 833045 : if ( bEnable != IsUndoEnabled() )
289 : 306271 : ResetUndoManager();
290 : :
291 : 833045 : bUndoEnabled = bEnable;
292 : 833045 : }
293 : :
294 : 0 : sal_Bool ImpEditEngine::Undo( EditView* pView )
295 : : {
296 [ # # ][ # # ]: 0 : if ( HasUndoManager() && GetUndoManager().GetUndoActionCount() )
[ # # ]
297 : : {
298 : 0 : SetActiveView( pView );
299 : 0 : GetUndoManager().Undo();
300 : 0 : return sal_True;
301 : : }
302 : 0 : return sal_False;
303 : : }
304 : :
305 : 0 : sal_Bool ImpEditEngine::Redo( EditView* pView )
306 : : {
307 [ # # ][ # # ]: 0 : if ( HasUndoManager() && GetUndoManager().GetRedoActionCount() )
[ # # ]
308 : : {
309 : 0 : SetActiveView( pView );
310 : 0 : GetUndoManager().Redo();
311 : 0 : return sal_True;
312 : : }
313 : 0 : return sal_False;
314 : : }
315 : :
316 : 3512 : SfxItemSet ImpEditEngine::GetAttribs( EditSelection aSel, sal_Bool bOnlyHardAttrib )
317 : : {
318 : : DBG_CHKOBJ( GetEditEnginePtr(), EditEngine, 0 );
319 : :
320 : 3512 : aSel.Adjust( aEditDoc );
321 : :
322 : 3512 : SfxItemSet aCurSet( GetEmptyItemSet() );
323 : :
324 [ + - ][ + - ]: 3512 : sal_uInt16 nStartNode = aEditDoc.GetPos( aSel.Min().GetNode() );
325 [ + - ][ + - ]: 3512 : sal_uInt16 nEndNode = aEditDoc.GetPos( aSel.Max().GetNode() );
326 : :
327 : : // iterate over the paragraphs ...
328 [ + + ]: 7924 : for ( sal_uInt16 nNode = nStartNode; nNode <= nEndNode; nNode++ )
329 : : {
330 [ + - ]: 4412 : ContentNode* pNode = aEditDoc.GetObject( nNode );
331 : : DBG_ASSERT( aEditDoc.GetObject( nNode ), "Node not found: GetAttrib" );
332 : :
333 : 4412 : xub_StrLen nStartPos = 0;
334 [ + - ]: 4412 : xub_StrLen nEndPos = pNode->Len();
335 [ + + ]: 4412 : if ( nNode == nStartNode )
336 : 3512 : nStartPos = aSel.Min().GetIndex();
337 [ + + ]: 4412 : if ( nNode == nEndNode ) // Can also be == nStart!
338 : 3512 : nEndPos = aSel.Max().GetIndex();
339 : :
340 : : // Problem: Templates ....
341 : : // => Other way:
342 : : // 1) Hard character attributes, as usual ...
343 : : // 2) Examine Style and paragraph attributes only when OFF ...
344 : :
345 : : // First the very hard formatting ...
346 [ + - ]: 4412 : aEditDoc.FindAttribs( pNode, nStartPos, nEndPos, aCurSet );
347 : :
348 [ + + ]: 4412 : if( bOnlyHardAttrib != EditEngineAttribs_OnlyHard )
349 : : {
350 : : // and then paragraph formatting and template...
351 [ + + ]: 204673 : for ( sal_uInt16 nWhich = EE_ITEMS_START; nWhich <= EE_CHAR_END; nWhich++)
352 : : {
353 [ + - ][ + + ]: 200496 : if ( aCurSet.GetItemState( nWhich ) == SFX_ITEM_OFF )
354 : : {
355 [ + - ]: 149897 : if ( bOnlyHardAttrib == EditEngineAttribs_All )
356 : : {
357 [ + - ]: 149897 : const SfxPoolItem& rItem = pNode->GetContentAttribs().GetItem( nWhich );
358 [ + - ]: 149897 : aCurSet.Put( rItem );
359 : : }
360 [ # # ][ # # ]: 0 : else if ( pNode->GetContentAttribs().GetItems().GetItemState( nWhich ) == SFX_ITEM_ON )
361 : : {
362 [ # # ]: 0 : const SfxPoolItem& rItem = pNode->GetContentAttribs().GetItems().Get( nWhich );
363 [ # # ]: 0 : aCurSet.Put( rItem );
364 : : }
365 : : }
366 [ + - ][ + + ]: 50599 : else if ( aCurSet.GetItemState( nWhich ) == SFX_ITEM_ON )
367 : : {
368 : 49699 : const SfxPoolItem* pItem = NULL;
369 [ + - ]: 49699 : if ( bOnlyHardAttrib == EditEngineAttribs_All )
370 : : {
371 [ + - ]: 49699 : pItem = &pNode->GetContentAttribs().GetItem( nWhich );
372 : : }
373 [ # # ][ # # ]: 0 : else if ( pNode->GetContentAttribs().GetItems().GetItemState( nWhich ) == SFX_ITEM_ON )
374 : : {
375 [ # # ]: 0 : pItem = &pNode->GetContentAttribs().GetItems().Get( nWhich );
376 : : }
377 : : // pItem can only be NULL when bOnlyHardAttrib...
378 [ + - ][ + - ]: 49699 : if ( !pItem || ( *pItem != aCurSet.Get( nWhich ) ) )
[ + - ][ + + ]
[ + + ]
379 : : {
380 : : // Problem: When Paragraph style with for example font,
381 : : // but the Font is hard and completely different,
382 : : // wrong in selection if invalidated....
383 : : // => better not invalidate, instead CHANGE!
384 : : // It would be better to fill each paragraph with
385 : : // a itemset and compare this in large.
386 [ - + ]: 24533 : if ( nWhich <= EE_PARA_END )
387 [ # # ]: 0 : aCurSet.InvalidateItem( nWhich );
388 : : }
389 : : }
390 : : }
391 : : }
392 : : }
393 : :
394 : : // fill empty slots with defaults ...
395 [ + + ]: 3512 : if ( bOnlyHardAttrib == EditEngineAttribs_All )
396 : : {
397 [ + + ]: 160573 : for ( sal_uInt16 nWhich = EE_ITEMS_START; nWhich <= EE_CHAR_END; nWhich++ )
398 : : {
399 [ + - ][ - + ]: 157296 : if ( aCurSet.GetItemState( nWhich ) == SFX_ITEM_OFF )
400 : : {
401 [ # # ][ # # ]: 0 : aCurSet.Put( aEditDoc.GetItemPool().GetDefaultItem( nWhich ) );
402 : : }
403 : : }
404 : : }
405 : 3512 : return aCurSet;
406 : : }
407 : :
408 : :
409 : 15694 : SfxItemSet ImpEditEngine::GetAttribs( sal_uInt16 nPara, sal_uInt16 nStart, sal_uInt16 nEnd, sal_uInt8 nFlags ) const
410 : : {
411 : : // Optimized function with less Puts(), which cause unnecessary cloning from default items.
412 : : // If this works, change GetAttribs( EditSelection ) to use this for each paragraph and merge the results!
413 : :
414 : : DBG_CHKOBJ( GetEditEnginePtr(), EditEngine, 0 );
415 : :
416 : 15694 : ContentNode* pNode = const_cast<ContentNode*>(aEditDoc.GetObject(nPara));
417 : : DBG_ASSERT( pNode, "GetAttribs - unknown paragraph!" );
418 : : DBG_ASSERT( nStart <= nEnd, "getAttribs: Start > End not supported!" );
419 : :
420 : 15694 : SfxItemSet aAttribs( ((ImpEditEngine*)this)->GetEmptyItemSet() );
421 : :
422 [ + - ]: 15694 : if ( pNode )
423 : : {
424 [ + - ][ - + ]: 15694 : if ( nEnd > pNode->Len() )
425 [ # # ]: 0 : nEnd = pNode->Len();
426 : :
427 [ - + ]: 15694 : if ( nStart > nEnd )
428 : 0 : nStart = nEnd;
429 : :
430 : : // StyleSheet / Parattribs...
431 : :
432 [ + + ][ + + ]: 15694 : if ( pNode->GetStyleSheet() && ( nFlags & GETATTRIBS_STYLESHEET ) )
[ + + ]
433 [ + - ][ + - ]: 873 : aAttribs.Set(pNode->GetStyleSheet()->GetItemSet(), true);
434 : :
435 [ + + ]: 15694 : if ( nFlags & GETATTRIBS_PARAATTRIBS )
436 [ + - ]: 15403 : aAttribs.Put( pNode->GetContentAttribs().GetItems() );
437 : :
438 : : // CharAttribs...
439 : :
440 [ + - ]: 15694 : if ( nFlags & GETATTRIBS_CHARATTRIBS )
441 : : {
442 : : // Make testing easier...
443 : 15694 : const SfxItemPool& rPool = GetEditDoc().GetItemPool();
444 [ + - ]: 15694 : pNode->GetCharAttribs().OptimizeRanges(const_cast<SfxItemPool&>(rPool));
445 : :
446 [ + - ]: 15694 : const CharAttribList::AttribsType& rAttrs = pNode->GetCharAttribs().GetAttribs();
447 [ + + ]: 92489 : for (size_t nAttr = 0; nAttr < rAttrs.size(); ++nAttr)
448 : : {
449 [ + - ]: 76795 : const EditCharAttrib& rAttr = rAttrs[nAttr];
450 : :
451 [ + + ]: 76795 : if ( nStart == nEnd )
452 : : {
453 : 41416 : sal_uInt16 nCursorPos = nStart;
454 [ + - ][ + + ]: 41416 : if ( ( rAttr.GetStart() <= nCursorPos ) && ( rAttr.GetEnd() >= nCursorPos ) )
[ + + ]
455 : : {
456 : : // To be used the attribute has to start BEFORE the position, or it must be a
457 : : // new empty attr AT the position, or we are on position 0.
458 [ + + ][ - + ]: 41332 : if ( ( rAttr.GetStart() < nCursorPos ) || rAttr.IsEmpty() || !nCursorPos )
[ # # ][ + - ]
459 : : {
460 : : // maybe this attrib ends here and a new attrib with 0 Len may follow and be valid here,
461 : : // but that s no problem, the empty item will come later and win.
462 [ + - ]: 41332 : aAttribs.Put( *rAttr.GetItem() );
463 : : }
464 : : }
465 : : }
466 : : else
467 : : {
468 : : // Check every attribute covering the area, partial or full.
469 [ + + ][ + + ]: 35379 : if ( ( rAttr.GetStart() < nEnd ) && ( rAttr.GetEnd() > nStart ) )
[ + + ]
470 : : {
471 [ + + ][ + + ]: 34855 : if ( ( rAttr.GetStart() <= nStart ) && ( rAttr.GetEnd() >= nEnd ) )
[ + + ]
472 : : {
473 : : // full coverage
474 [ + - ]: 34141 : aAttribs.Put( *rAttr.GetItem() );
475 : : }
476 : : else
477 : : {
478 : : // OptimizeRagnge() assures that not the same attr can follow for full coverage
479 : : // only partial, check with current, when using para/styhe, otherwise invalid.
480 [ + - ][ + - ]: 1428 : if ( !( nFlags & (GETATTRIBS_PARAATTRIBS|GETATTRIBS_STYLESHEET) ) ||
[ + - ]
481 [ + - ][ + - ]: 714 : ( *rAttr.GetItem() != aAttribs.Get( rAttr.Which() ) ) )
482 : : {
483 [ + - ]: 714 : aAttribs.InvalidateItem( rAttr.Which() );
484 : : }
485 : : }
486 : : }
487 : : }
488 : :
489 [ + + ]: 76795 : if ( rAttr.GetStart() > nEnd )
490 : : {
491 : 88 : break;
492 : : }
493 : : }
494 : : }
495 : : }
496 : :
497 : 15694 : return aAttribs;
498 : : }
499 : :
500 : :
501 : 2794 : void ImpEditEngine::SetAttribs( EditSelection aSel, const SfxItemSet& rSet, sal_uInt8 nSpecial )
502 : : {
503 : 2794 : aSel.Adjust( aEditDoc );
504 : :
505 : : // When no selection => use the Attribute on the word.
506 : : // ( the RTF-parser should actually never call the Method whithout a Range )
507 [ + - ][ + + ]: 2794 : if ( ( nSpecial == ATTRSPECIAL_WHOLEWORD ) && !aSel.HasRange() )
[ + + ]
508 [ + - ]: 42 : aSel = SelectWord( aSel, ::com::sun::star::i18n::WordType::ANYWORD_IGNOREWHITESPACES, sal_False );
509 : :
510 : 2794 : sal_uInt16 nStartNode = aEditDoc.GetPos( aSel.Min().GetNode() );
511 : 2794 : sal_uInt16 nEndNode = aEditDoc.GetPos( aSel.Max().GetNode() );
512 : :
513 [ + - ][ + - ]: 2794 : if ( IsUndoEnabled() && !IsInUndo() && aStatus.DoUndoAttribs() )
[ + + ][ + + ]
514 : : {
515 [ + - ]: 1624 : EditUndoSetAttribs* pUndo = CreateAttribUndo( aSel, rSet );
516 : 1624 : pUndo->SetSpecial( nSpecial );
517 : 1624 : InsertUndo( pUndo );
518 : : }
519 : :
520 : 2794 : sal_Bool bCheckLanguage = sal_False;
521 [ + + ]: 2794 : if ( GetStatus().DoOnlineSpelling() )
522 : : {
523 : 493 : bCheckLanguage = ( rSet.GetItemState( EE_CHAR_LANGUAGE ) == SFX_ITEM_ON ) ||
524 : 195 : ( rSet.GetItemState( EE_CHAR_LANGUAGE_CJK ) == SFX_ITEM_ON ) ||
525 [ - + ]: 688 : ( rSet.GetItemState( EE_CHAR_LANGUAGE_CTL ) == SFX_ITEM_ON );
[ + + + - ]
526 : : }
527 : :
528 : : // iterate over the paragraphs ...
529 [ + + ]: 6311 : for ( sal_uInt16 nNode = nStartNode; nNode <= nEndNode; nNode++ )
530 : : {
531 : 3517 : sal_Bool bParaAttribFound = sal_False;
532 : 3517 : sal_Bool bCharAttribFound = sal_False;
533 : :
534 : : DBG_ASSERT( aEditDoc.GetObject( nNode ), "Node not founden: SetAttribs" );
535 : : DBG_ASSERT( GetParaPortions().SafeGetObject( nNode ), "Portion not found: SetAttribs" );
536 : :
537 : 3517 : ContentNode* pNode = aEditDoc.GetObject( nNode );
538 : 3517 : ParaPortion* pPortion = GetParaPortions()[nNode];
539 : :
540 : 3517 : xub_StrLen nStartPos = 0;
541 : 3517 : xub_StrLen nEndPos = pNode->Len();
542 [ + + ]: 3517 : if ( nNode == nStartNode )
543 : 2794 : nStartPos = aSel.Min().GetIndex();
544 [ + + ]: 3517 : if ( nNode == nEndNode ) // can also be == nStart!
545 : 2794 : nEndPos = aSel.Max().GetIndex();
546 : :
547 : : // Iterate over the Items...
548 [ + + ]: 172333 : for ( sal_uInt16 nWhich = EE_ITEMS_START; nWhich <= EE_CHAR_END; nWhich++)
549 : : {
550 [ + + ]: 168816 : if ( rSet.GetItemState( nWhich ) == SFX_ITEM_ON )
551 : : {
552 : 21197 : const SfxPoolItem& rItem = rSet.Get( nWhich );
553 [ + + ]: 21197 : if ( nWhich <= EE_PARA_END )
554 : : {
555 : 3273 : pNode->GetContentAttribs().GetItems().Put( rItem );
556 : 3273 : bParaAttribFound = sal_True;
557 : : }
558 : : else
559 : : {
560 : 17924 : aEditDoc.InsertAttrib( pNode, nStartPos, nEndPos, rItem );
561 : 17924 : bCharAttribFound = sal_True;
562 [ - + ]: 17924 : if ( nSpecial == ATTRSPECIAL_EDGE )
563 : : {
564 : 0 : CharAttribList::AttribsType& rAttribs = pNode->GetCharAttribs().GetAttribs();
565 [ # # ]: 0 : for (size_t i = 0, n = rAttribs.size(); i < n; ++i)
566 : : {
567 : 0 : EditCharAttrib& rAttr = rAttribs[i];
568 [ # # ]: 0 : if (rAttr.GetStart() > nEndPos)
569 : 0 : break;
570 : :
571 [ # # ][ # # ]: 0 : if (rAttr.GetEnd() == nEndPos && rAttr.Which() == nWhich)
[ # # ]
572 : : {
573 : 0 : rAttr.SetEdge(true);
574 : 0 : break;
575 : : }
576 : : }
577 : : }
578 : : }
579 : : }
580 : : }
581 : :
582 [ + + ]: 3517 : if ( bParaAttribFound )
583 : : {
584 : 610 : ParaAttribsChanged( pPortion->GetNode() );
585 : : }
586 [ + + ]: 2907 : else if ( bCharAttribFound )
587 : : {
588 : 2632 : bFormatted = false;
589 [ + + ][ + + ]: 2632 : if ( !pNode->Len() || ( nStartPos != nEndPos ) )
[ + + ]
590 : : {
591 : 2433 : pPortion->MarkSelectionInvalid( nStartPos, nEndPos-nStartPos );
592 [ + + ]: 2433 : if ( bCheckLanguage )
593 : 189 : pNode->GetWrongList()->MarkInvalid( nStartPos, nEndPos );
594 : : }
595 : : }
596 : : }
597 : 2794 : }
598 : :
599 : 76 : void ImpEditEngine::RemoveCharAttribs( EditSelection aSel, sal_Bool bRemoveParaAttribs, sal_uInt16 nWhich )
600 : : {
601 : 76 : aSel.Adjust( aEditDoc );
602 : :
603 : 76 : sal_uInt16 nStartNode = aEditDoc.GetPos( aSel.Min().GetNode() );
604 : 76 : sal_uInt16 nEndNode = aEditDoc.GetPos( aSel.Max().GetNode() );
605 : :
606 [ + + ]: 76 : const SfxItemSet* _pEmptyItemSet = bRemoveParaAttribs ? &GetEmptyItemSet() : 0;
607 : :
608 [ + - ][ + - ]: 76 : if ( IsUndoEnabled() && !IsInUndo() && aStatus.DoUndoAttribs() )
[ + - ][ + - ]
609 : : {
610 : : // Possibly a special Undo, or itemset*
611 [ + - ]: 76 : EditUndoSetAttribs* pUndo = CreateAttribUndo( aSel, GetEmptyItemSet() );
612 : 76 : pUndo->SetRemoveAttribs( sal_True );
613 : 76 : pUndo->SetRemoveParaAttribs( bRemoveParaAttribs );
614 : 76 : pUndo->SetRemoveWhich( nWhich );
615 : 76 : InsertUndo( pUndo );
616 : : }
617 : :
618 : : // iterate over the paragraphs ...
619 [ + + ]: 152 : for ( sal_uInt16 nNode = nStartNode; nNode <= nEndNode; nNode++ )
620 : : {
621 : 76 : ContentNode* pNode = aEditDoc.GetObject( nNode );
622 : 76 : ParaPortion* pPortion = GetParaPortions()[nNode];
623 : :
624 : : DBG_ASSERT( aEditDoc.GetObject( nNode ), "Node not found: SetAttribs" );
625 : : DBG_ASSERT( GetParaPortions().SafeGetObject( nNode ), "Portion not found: SetAttribs" );
626 : :
627 : 76 : xub_StrLen nStartPos = 0;
628 : 76 : xub_StrLen nEndPos = pNode->Len();
629 [ + - ]: 76 : if ( nNode == nStartNode )
630 : 76 : nStartPos = aSel.Min().GetIndex();
631 [ + - ]: 76 : if ( nNode == nEndNode ) // can also be == nStart!
632 : 76 : nEndPos = aSel.Max().GetIndex();
633 : :
634 : : // Optimize: If whole paragraph, then RemoveCharAttribs (nPara)?
635 : 76 : sal_Bool bChanged = aEditDoc.RemoveAttribs( pNode, nStartPos, nEndPos, nWhich );
636 [ + + ]: 76 : if ( bRemoveParaAttribs )
637 : : {
638 : 64 : SetParaAttribs( nNode, *_pEmptyItemSet ); // Invalidated
639 : : }
640 : : else
641 : : {
642 : : // For 'Format-Standard' also the character attributes should
643 : : // disappear, which were set as paragraph attributes by the
644 : : // DrawingEngine. These could not have been set by the user anyway.
645 : :
646 : : // #106871# Not when nWhich
647 : : // Would have been better to offer a separate method for format/standard...
648 [ + - ]: 12 : if ( !nWhich )
649 : : {
650 [ + - ][ + - ]: 12 : SfxItemSet aAttribs( GetParaAttribs( nNode ) );
651 [ + + ]: 372 : for ( sal_uInt16 nW = EE_CHAR_START; nW <= EE_CHAR_END; nW++ )
652 [ + - ]: 360 : aAttribs.ClearItem( nW );
653 [ + - ][ + - ]: 12 : SetParaAttribs( nNode, aAttribs );
654 : : }
655 : : }
656 : :
657 [ - + ][ # # ]: 76 : if ( bChanged && !bRemoveParaAttribs )
658 : : {
659 : 0 : bFormatted = false;
660 : 0 : pPortion->MarkSelectionInvalid( nStartPos, nEndPos-nStartPos );
661 : : }
662 : : }
663 : 76 : }
664 : :
665 : 25970 : void ImpEditEngine::RemoveCharAttribs( sal_uInt16 nPara, sal_uInt16 nWhich, sal_Bool bRemoveFeatures )
666 : : {
667 : 25970 : ContentNode* pNode = aEditDoc.GetObject( nPara );
668 : 25970 : ParaPortion* pPortion = GetParaPortions().SafeGetObject( nPara );
669 : :
670 : : DBG_ASSERT( pNode, "Node not found: RemoveCharAttribs" );
671 : : DBG_ASSERT( pPortion, "Portion not found: RemoveCharAttribs" );
672 : :
673 [ - + ]: 25970 : if ( !pNode )
674 : 25970 : return;
675 : :
676 : 25970 : size_t nAttr = 0;
677 : 25970 : CharAttribList::AttribsType& rAttrs = pNode->GetCharAttribs().GetAttribs();
678 : 25970 : EditCharAttrib* pAttr = GetAttrib(rAttrs, nAttr);
679 [ + + ]: 31119 : while ( pAttr )
680 : : {
681 [ + + ][ - + ]: 8911 : if ( ( !pAttr->IsFeature() || bRemoveFeatures ) &&
[ + + + + ]
[ + + ]
682 : 3762 : ( !nWhich || ( pAttr->GetItem()->Which() == nWhich ) ) )
683 : : {
684 : 258 : pNode->GetCharAttribs().Remove(nAttr);
685 : 258 : nAttr--;
686 : : }
687 : 5149 : nAttr++;
688 : 5149 : pAttr = GetAttrib(rAttrs, nAttr);
689 : : }
690 : :
691 : 25970 : pPortion->MarkSelectionInvalid( 0, pNode->Len() );
692 : : }
693 : :
694 : 725246 : void ImpEditEngine::SetParaAttribs( sal_uInt16 nPara, const SfxItemSet& rSet )
695 : : {
696 : 725246 : ContentNode* pNode = aEditDoc.GetObject( nPara );
697 : :
698 [ - + ]: 725246 : if ( !pNode )
699 : 725246 : return;
700 : :
701 [ + + ]: 725246 : if ( !( pNode->GetContentAttribs().GetItems() == rSet ) )
702 : : {
703 [ + + ][ + - ]: 346709 : if ( IsUndoEnabled() && !IsInUndo() && aStatus.DoUndoAttribs() )
[ + - ][ + + ]
704 : : {
705 [ - + ]: 181330 : if ( rSet.GetPool() != &aEditDoc.GetItemPool() )
706 : : {
707 [ # # ][ # # ]: 0 : SfxItemSet aTmpSet( GetEmptyItemSet() );
708 [ # # ]: 0 : aTmpSet.Put( rSet );
709 [ # # ][ # # ]: 0 : InsertUndo(new EditUndoSetParaAttribs(pEditEngine, nPara, pNode->GetContentAttribs().GetItems(), aTmpSet));
[ # # ][ # # ]
710 : : }
711 : : else
712 : : {
713 [ + - ]: 181330 : InsertUndo(new EditUndoSetParaAttribs(pEditEngine, nPara, pNode->GetContentAttribs().GetItems(), rSet));
714 : : }
715 : : }
716 : 346709 : pNode->GetContentAttribs().GetItems().Set( rSet );
717 [ + - ]: 346709 : if ( aStatus.UseCharAttribs() )
718 : 346709 : pNode->CreateDefFont();
719 : :
720 : 346709 : ParaAttribsChanged( pNode );
721 : : }
722 : : }
723 : :
724 : 593842 : const SfxItemSet& ImpEditEngine::GetParaAttribs( sal_uInt16 nPara ) const
725 : : {
726 : 593842 : const ContentNode* pNode = aEditDoc.GetObject( nPara );
727 : : DBG_ASSERT( pNode, "Node not found: GetParaAttribs" );
728 : 593842 : return pNode->GetContentAttribs().GetItems();
729 : : }
730 : :
731 : 8925 : bool ImpEditEngine::HasParaAttrib( sal_uInt16 nPara, sal_uInt16 nWhich ) const
732 : : {
733 : 8925 : const ContentNode* pNode = aEditDoc.GetObject( nPara );
734 : : DBG_ASSERT( pNode, "Node not found: HasParaAttrib" );
735 : :
736 : 8925 : return pNode->GetContentAttribs().HasItem( nWhich );
737 : : }
738 : :
739 : 1462916 : const SfxPoolItem& ImpEditEngine::GetParaAttrib( sal_uInt16 nPara, sal_uInt16 nWhich ) const
740 : : {
741 : 1462916 : const ContentNode* pNode = aEditDoc.GetObject( nPara );
742 : : DBG_ASSERT( pNode, "Node not found: GetParaAttrib" );
743 : :
744 : 1462916 : return pNode->GetContentAttribs().GetItem( nWhich );
745 : : }
746 : :
747 : 6 : void ImpEditEngine::GetCharAttribs( sal_uInt16 nPara, std::vector<EECharAttrib>& rLst ) const
748 : : {
749 : 6 : rLst.clear();
750 : 6 : const ContentNode* pNode = aEditDoc.GetObject( nPara );
751 [ + - ]: 6 : if ( pNode )
752 : : {
753 : 6 : rLst.reserve(pNode->GetCharAttribs().Count());
754 : 6 : const CharAttribList::AttribsType& rAttrs = pNode->GetCharAttribs().GetAttribs();
755 [ + + ]: 42 : for (size_t i = 0; i < rAttrs.size(); ++i)
756 : : {
757 [ + - ]: 36 : const EditCharAttrib& rAttr = rAttrs[i];
758 : : EECharAttrib aEEAttr;
759 : 36 : aEEAttr.pAttr = rAttr.GetItem();
760 : 36 : aEEAttr.nPara = nPara;
761 : 36 : aEEAttr.nStart = rAttr.GetStart();
762 : 36 : aEEAttr.nEnd = rAttr.GetEnd();
763 [ + - ]: 36 : rLst.push_back(aEEAttr);
764 : : }
765 : : }
766 : 6 : }
767 : :
768 : 0 : void ImpEditEngine::ParaAttribsToCharAttribs( ContentNode* pNode )
769 : : {
770 : 0 : pNode->GetCharAttribs().DeleteEmptyAttribs( GetEditDoc().GetItemPool() );
771 : 0 : xub_StrLen nEndPos = pNode->Len();
772 [ # # ]: 0 : for ( sal_uInt16 nWhich = EE_CHAR_START; nWhich <= EE_CHAR_END; nWhich++ )
773 : : {
774 [ # # ]: 0 : if ( pNode->GetContentAttribs().HasItem( nWhich ) )
775 : : {
776 : 0 : const SfxPoolItem& rItem = pNode->GetContentAttribs().GetItem( nWhich );
777 : : // Fill the gap:
778 : 0 : sal_uInt16 nLastEnd = 0;
779 : 0 : const EditCharAttrib* pAttr = pNode->GetCharAttribs().FindNextAttrib( nWhich, nLastEnd );
780 [ # # ]: 0 : while ( pAttr )
781 : : {
782 : 0 : nLastEnd = pAttr->GetEnd();
783 [ # # ]: 0 : if ( pAttr->GetStart() > nLastEnd )
784 : 0 : aEditDoc.InsertAttrib( pNode, nLastEnd, pAttr->GetStart(), rItem );
785 : : // #112831# Last Attr might go from 0xffff to 0x0000
786 [ # # ]: 0 : pAttr = nLastEnd ? pNode->GetCharAttribs().FindNextAttrib( nWhich, nLastEnd ) : NULL;
787 : : }
788 : :
789 : : // And the Rest:
790 [ # # ]: 0 : if ( nLastEnd < nEndPos )
791 : 0 : aEditDoc.InsertAttrib( pNode, nLastEnd, nEndPos, rItem );
792 : : }
793 : : }
794 : 0 : bFormatted = false;
795 : : // Portion does not need to be invalidated here, happens elsewhere.
796 : 0 : }
797 : :
798 : 30636 : IdleFormattter::IdleFormattter()
799 : : {
800 : 30636 : pView = 0;
801 : 30636 : nRestarts = 0;
802 : 30636 : }
803 : :
804 : 30388 : IdleFormattter::~IdleFormattter()
805 : : {
806 : 30388 : pView = 0;
807 [ - + ]: 30388 : }
808 : :
809 : 0 : void IdleFormattter::DoIdleFormat( EditView* pV )
810 : : {
811 : 0 : pView = pV;
812 : :
813 [ # # ]: 0 : if ( IsActive() )
814 : 0 : nRestarts++;
815 : :
816 [ # # ]: 0 : if ( nRestarts > 4 )
817 : 0 : ForceTimeout();
818 : : else
819 : 0 : Start();
820 : 0 : }
821 : :
822 : 1283 : void IdleFormattter::ForceTimeout()
823 : : {
824 [ - + ]: 1283 : if ( IsActive() )
825 : : {
826 : 0 : Stop();
827 : 0 : ((Link&)GetTimeoutHdl()).Call( this );
828 : : }
829 : 1283 : }
830 : :
831 : 0 : ImplIMEInfos::ImplIMEInfos( const EditPaM& rPos, const String& rOldTextAfterStartPos )
832 [ # # ]: 0 : : aOldTextAfterStartPos( rOldTextAfterStartPos )
833 : : {
834 [ # # ]: 0 : aPos = rPos;
835 : 0 : nLen = 0;
836 : 0 : bCursor = sal_True;
837 : 0 : pAttribs = NULL;
838 : 0 : bWasCursorOverwrite = sal_False;
839 : 0 : }
840 : :
841 : 0 : ImplIMEInfos::~ImplIMEInfos()
842 : : {
843 [ # # ]: 0 : delete[] pAttribs;
844 : 0 : }
845 : :
846 : 0 : void ImplIMEInfos::CopyAttribs( const sal_uInt16* pA, sal_uInt16 nL )
847 : : {
848 : 0 : nLen = nL;
849 [ # # ]: 0 : delete[] pAttribs;
850 : 0 : pAttribs = new sal_uInt16[ nL ];
851 : 0 : memcpy( pAttribs, pA, nL*sizeof(sal_uInt16) );
852 : 0 : }
853 : :
854 : 0 : void ImplIMEInfos::DestroyAttribs()
855 : : {
856 [ # # ]: 0 : delete[] pAttribs;
857 : 0 : pAttribs = NULL;
858 : 0 : nLen = 0;
859 : 0 : }
860 : :
861 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|