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 : :
30 : : #include <UndoManager.hxx>
31 : :
32 : : #include <vcl/wrkwin.hxx>
33 : :
34 : : #include <svx/svdmodel.hxx>
35 : :
36 : : #include <swmodule.hxx>
37 : : #include <doc.hxx>
38 : : #include <ndarr.hxx>
39 : : #include <pam.hxx>
40 : : #include <ndtxt.hxx>
41 : : #include <swundo.hxx>
42 : : #include <UndoCore.hxx>
43 : : #include <rolbck.hxx>
44 : : #include <undo.hrc>
45 : : #include <editsh.hxx>
46 : : #include <unobaseclass.hxx>
47 : : #include <limits>
48 : :
49 : : using namespace ::com::sun::star;
50 : :
51 : :
52 : : // the undo array should never grow beyond this limit:
53 : : #define UNDO_ACTION_LIMIT (USHRT_MAX - 1000)
54 : :
55 : :
56 : : // UndoManager ///////////////////////////////////////////////////////////
57 : :
58 : : namespace sw {
59 : :
60 : : SAL_WNODEPRECATED_DECLARATIONS_PUSH
61 : 1549 : UndoManager::UndoManager(::std::auto_ptr<SwNodes> pUndoNodes,
62 : : IDocumentDrawModelAccess & rDrawModelAccess,
63 : : IDocumentRedlineAccess & rRedlineAccess,
64 : : IDocumentState & rState)
65 : : : m_rDrawModelAccess(rDrawModelAccess)
66 : : , m_rRedlineAccess(rRedlineAccess)
67 : : , m_rState(rState)
68 : : , m_pUndoNodes(pUndoNodes)
69 : : , m_bGroupUndo(true)
70 : : , m_bDrawUndo(true)
71 : : , m_bLockUndoNoModifiedPosition(false)
72 [ + - ]: 1549 : , m_UndoSaveMark(MARK_INVALID)
73 : : {
74 : : OSL_ASSERT(m_pUndoNodes.get());
75 : : // writer expects it to be disabled initially
76 : : // Undo is enabled by SwEditShell constructor
77 [ + - ]: 1549 : SfxUndoManager::EnableUndo(false);
78 : 1549 : }
79 : : SAL_WNODEPRECATED_DECLARATIONS_POP
80 : :
81 : 0 : SwNodes const& UndoManager::GetUndoNodes() const
82 : : {
83 : 0 : return *m_pUndoNodes;
84 : : }
85 : :
86 : 31604 : SwNodes & UndoManager::GetUndoNodes()
87 : : {
88 : 31604 : return *m_pUndoNodes;
89 : : }
90 : :
91 : 3330 : bool UndoManager::IsUndoNodes(SwNodes const& rNodes) const
92 : : {
93 : 3330 : return & rNodes == m_pUndoNodes.get();
94 : : }
95 : :
96 : 25024 : void UndoManager::DoUndo(bool const bDoUndo)
97 : : {
98 : 25024 : EnableUndo(bDoUndo);
99 : :
100 : 25024 : SdrModel *const pSdrModel = m_rDrawModelAccess.GetDrawModel();
101 [ + + ]: 25024 : if( pSdrModel )
102 : : {
103 : 18140 : pSdrModel->EnableUndo(bDoUndo);
104 : : }
105 : 25024 : }
106 : :
107 : 316673 : bool UndoManager::DoesUndo() const
108 : : {
109 : 316673 : return IsUndoEnabled();
110 : : }
111 : :
112 : 37478 : void UndoManager::DoGroupUndo(bool const bDoUndo)
113 : : {
114 : 37478 : m_bGroupUndo = bDoUndo;
115 : 37478 : }
116 : :
117 : 26975 : bool UndoManager::DoesGroupUndo() const
118 : : {
119 : 26975 : return m_bGroupUndo;
120 : : }
121 : :
122 : 30 : void UndoManager::DoDrawUndo(bool const bDoUndo)
123 : : {
124 : 30 : m_bDrawUndo = bDoUndo;
125 : 30 : }
126 : :
127 : 11249 : bool UndoManager::DoesDrawUndo() const
128 : : {
129 : 11249 : return m_bDrawUndo;
130 : : }
131 : :
132 : :
133 : 2649 : bool UndoManager::IsUndoNoResetModified() const
134 : : {
135 : 2649 : return MARK_INVALID == m_UndoSaveMark;
136 : : }
137 : :
138 : 43 : void UndoManager::SetUndoNoResetModified()
139 : : {
140 [ + - ]: 43 : if (MARK_INVALID != m_UndoSaveMark)
141 : : {
142 : 43 : RemoveMark(m_UndoSaveMark);
143 : 43 : m_UndoSaveMark = MARK_INVALID;
144 : : }
145 : 43 : }
146 : :
147 : 13418 : void UndoManager::SetUndoNoModifiedPosition()
148 : : {
149 [ + + ]: 13418 : if (!m_bLockUndoNoModifiedPosition)
150 : : {
151 : 13366 : m_UndoSaveMark = MarkTopUndoAction();
152 : : }
153 : 13418 : }
154 : :
155 : 19 : void UndoManager::LockUndoNoModifiedPosition()
156 : : {
157 : 19 : m_bLockUndoNoModifiedPosition = true;
158 : 19 : }
159 : :
160 : 6 : void UndoManager::UnLockUndoNoModifiedPosition()
161 : : {
162 : 6 : m_bLockUndoNoModifiedPosition = false;
163 : 6 : }
164 : :
165 : :
166 : 1116 : SwUndo* UndoManager::GetLastUndo()
167 : : {
168 [ + + ]: 1116 : if (!SfxUndoManager::GetUndoActionCount(CurrentLevel))
169 : : {
170 : 944 : return 0;
171 : : }
172 : 172 : SfxUndoAction *const pAction( SfxUndoManager::GetUndoAction(0) );
173 [ + - ]: 1116 : return dynamic_cast<SwUndo*>(pAction);
174 : : }
175 : :
176 : 28409 : void UndoManager::AppendUndo(SwUndo *const pUndo)
177 : : {
178 : 28409 : AddUndoAction(pUndo);
179 : 28409 : }
180 : :
181 : 12234 : void UndoManager::ClearRedo()
182 : : {
183 : 12234 : return SfxUndoManager::ImplClearRedo_NoLock(TopLevel);
184 : : }
185 : :
186 : 1532 : void UndoManager::DelAllUndoObj()
187 : : {
188 [ + - ]: 1532 : ::sw::UndoGuard const undoGuard(*this);
189 : :
190 [ + - ]: 1532 : SfxUndoManager::ClearAllLevels();
191 : :
192 [ + - ]: 1532 : m_UndoSaveMark = MARK_INVALID;
193 : 1532 : }
194 : :
195 : :
196 : : /**************** UNDO ******************/
197 : :
198 : : SwUndoId
199 : 15188 : UndoManager::StartUndo(SwUndoId const i_eUndoId,
200 : : SwRewriter const*const pRewriter)
201 : : {
202 [ + - ][ + + ]: 15188 : if (!IsUndoEnabled())
203 : : {
204 : 7129 : return UNDO_EMPTY;
205 : : }
206 : :
207 [ + + ]: 8059 : SwUndoId const eUndoId( (0 == i_eUndoId) ? UNDO_START : i_eUndoId );
208 : :
209 : : OSL_ASSERT(UNDO_END != eUndoId);
210 : : String comment( (UNDO_START == eUndoId)
211 : : ? String("??", RTL_TEXTENCODING_ASCII_US)
212 [ + + ][ + - ]: 8059 : : String(SW_RES(UNDO_BASE + eUndoId)) );
[ + - ][ + + ]
[ # # ]
213 [ + + ]: 8059 : if (pRewriter)
214 : : {
215 : : OSL_ASSERT(UNDO_START != eUndoId);
216 [ + - ][ + - ]: 302 : comment = pRewriter->Apply(comment);
[ + - ]
217 : : }
218 : :
219 [ + - ]: 8059 : SfxUndoManager::EnterListAction(comment, comment, eUndoId);
220 : :
221 [ + - ]: 15188 : return eUndoId;
222 : : }
223 : :
224 : :
225 : : SwUndoId
226 : 15128 : UndoManager::EndUndo(SwUndoId const i_eUndoId, SwRewriter const*const pRewriter)
227 : : {
228 [ + + ]: 15128 : if (!IsUndoEnabled())
229 : : {
230 : 7069 : return UNDO_EMPTY;
231 : : }
232 : :
233 : : SwUndoId const eUndoId( ((0 == i_eUndoId) || (UNDO_START == i_eUndoId))
234 [ + + ][ + + ]: 8059 : ? UNDO_END : i_eUndoId );
235 : : OSL_ENSURE(!((UNDO_END == eUndoId) && pRewriter),
236 : : "EndUndo(): no Undo ID, but rewriter given?");
237 : :
238 : : SfxUndoAction *const pLastUndo(
239 : 8059 : (0 == SfxUndoManager::GetUndoActionCount(CurrentLevel))
240 [ + + ]: 8059 : ? 0 : SfxUndoManager::GetUndoAction(0) );
241 : :
242 : 8059 : int const nCount = LeaveListAction();
243 : :
244 [ + + ]: 8059 : if (nCount) // otherwise: empty list action not inserted!
245 : : {
246 : : OSL_ASSERT(pLastUndo);
247 : : OSL_ASSERT(UNDO_START != eUndoId);
248 : 7212 : SfxUndoAction *const pUndoAction(SfxUndoManager::GetUndoAction(0));
249 : : SfxListUndoAction *const pListAction(
250 [ - + ]: 7212 : dynamic_cast<SfxListUndoAction*>(pUndoAction));
251 : : OSL_ASSERT(pListAction);
252 [ + - ]: 7212 : if (pListAction)
253 : : {
254 [ + + ]: 7212 : if (UNDO_END != eUndoId)
255 : : {
256 : : OSL_ENSURE(pListAction->GetId() == eUndoId,
257 : : "EndUndo(): given ID different from StartUndo()");
258 : : // comment set by caller of EndUndo
259 [ + - ]: 6612 : String comment = String(SW_RES(UNDO_BASE + eUndoId));
260 [ + + ]: 6612 : if (pRewriter)
261 : : {
262 [ + - ][ + - ]: 4 : comment = pRewriter->Apply(comment);
[ + - ]
263 : : }
264 [ + - ][ + - ]: 6612 : pListAction->SetComment(comment);
265 : : }
266 [ + + ]: 600 : else if ((UNDO_START != pListAction->GetId()))
267 : : {
268 : : // comment set by caller of StartUndo: nothing to do here
269 : : }
270 [ + - ]: 302 : else if (pLastUndo)
271 : : {
272 : : // comment was not set at StartUndo or EndUndo:
273 : : // take comment of last contained action
274 : : // (note that this works recursively, i.e. the last contained
275 : : // action may be a list action created by StartUndo/EndUndo)
276 [ + - ][ + - ]: 302 : String const comment(pLastUndo->GetComment());
277 [ + - ][ + - ]: 302 : pListAction->SetComment(comment);
278 : : }
279 : : else
280 : : {
281 : : OSL_ENSURE(false, "EndUndo(): no comment?");
282 : : }
283 : : }
284 : : }
285 : :
286 : 15128 : return eUndoId;
287 : : }
288 : :
289 : : bool
290 : 2119 : UndoManager::GetLastUndoInfo(
291 : : ::rtl::OUString *const o_pStr, SwUndoId *const o_pId) const
292 : : {
293 : : // this is actually expected to work on the current level,
294 : : // but that was really not obvious from the previous implementation...
295 [ + + ]: 2119 : if (!SfxUndoManager::GetUndoActionCount(CurrentLevel))
296 : : {
297 : 633 : return false;
298 : : }
299 : :
300 : 1486 : SfxUndoAction *const pAction( SfxUndoManager::GetUndoAction(0) );
301 [ + + ]: 1486 : if (o_pStr)
302 : : {
303 : 740 : *o_pStr = pAction->GetComment();
304 : : }
305 [ + + ]: 1486 : if (o_pId)
306 : : {
307 : 6 : sal_uInt16 const nId(pAction->GetId());
308 : 6 : *o_pId = static_cast<SwUndoId>(nId);
309 : : }
310 : :
311 : 2119 : return true;
312 : : }
313 : :
314 : 0 : SwUndoComments_t UndoManager::GetUndoComments() const
315 : : {
316 : : OSL_ENSURE(!SfxUndoManager::IsInListAction(),
317 : : "GetUndoComments() called while in list action?");
318 : :
319 : 0 : SwUndoComments_t ret;
320 [ # # ]: 0 : sal_uInt16 const nUndoCount(SfxUndoManager::GetUndoActionCount(TopLevel));
321 [ # # ]: 0 : for (sal_uInt16 n = 0; n < nUndoCount; ++n)
322 : : {
323 : : ::rtl::OUString const comment(
324 [ # # ]: 0 : SfxUndoManager::GetUndoActionComment(n, TopLevel));
325 [ # # ]: 0 : ret.push_back(comment);
326 : 0 : }
327 : :
328 : 0 : return ret;
329 : : }
330 : :
331 : :
332 : : /**************** REDO ******************/
333 : 1371 : bool UndoManager::GetFirstRedoInfo(::rtl::OUString *const o_pStr) const
334 : : {
335 [ + + ]: 1371 : if (!SfxUndoManager::GetRedoActionCount(CurrentLevel))
336 : : {
337 : 1367 : return false;
338 : : }
339 : :
340 [ + + ]: 4 : if (o_pStr)
341 : : {
342 : 2 : *o_pStr = SfxUndoManager::GetRedoActionComment(0, CurrentLevel);
343 : : }
344 : :
345 : 1371 : return true;
346 : : }
347 : :
348 : :
349 : 0 : SwUndoComments_t UndoManager::GetRedoComments() const
350 : : {
351 : : OSL_ENSURE(!SfxUndoManager::IsInListAction(),
352 : : "GetRedoComments() called while in list action?");
353 : :
354 : 0 : SwUndoComments_t ret;
355 [ # # ]: 0 : sal_uInt16 const nRedoCount(SfxUndoManager::GetRedoActionCount(TopLevel));
356 [ # # ]: 0 : for (sal_uInt16 n = 0; n < nRedoCount; ++n)
357 : : {
358 : : ::rtl::OUString const comment(
359 [ # # ]: 0 : SfxUndoManager::GetRedoActionComment(n, TopLevel));
360 [ # # ]: 0 : ret.push_back(comment);
361 : 0 : }
362 : :
363 : 0 : return ret;
364 : : }
365 : :
366 : : /**************** REPEAT ******************/
367 : :
368 : 14 : SwUndoId UndoManager::GetRepeatInfo(::rtl::OUString *const o_pStr) const
369 : : {
370 : 14 : SwUndoId nRepeatId(UNDO_EMPTY);
371 [ + - ]: 14 : GetLastUndoInfo(o_pStr, & nRepeatId);
372 [ - + ][ # # ]: 14 : if( REPEAT_START <= nRepeatId && REPEAT_END > nRepeatId )
373 : : {
374 : 0 : return nRepeatId;
375 : : }
376 [ - + ]: 14 : if (o_pStr) // not repeatable -> clear comment
377 : : {
378 [ # # ][ # # ]: 0 : *o_pStr = String();
[ # # ]
379 : : }
380 : 14 : return UNDO_EMPTY;
381 : : }
382 : :
383 : 0 : SwUndo * UndoManager::RemoveLastUndo()
384 : : {
385 [ # # # # ]: 0 : if (SfxUndoManager::GetRedoActionCount(CurrentLevel) ||
[ # # ]
386 : 0 : SfxUndoManager::GetRedoActionCount(TopLevel))
387 : : {
388 : : OSL_ENSURE(false, "RemoveLastUndoAction(): there are Redo actions?");
389 : 0 : return 0;
390 : : }
391 [ # # ]: 0 : if (!SfxUndoManager::GetUndoActionCount(CurrentLevel))
392 : : {
393 : : OSL_ENSURE(false, "RemoveLastUndoAction(): no Undo actions");
394 : 0 : return 0;
395 : : }
396 : 0 : SfxUndoAction *const pLastUndo(GetUndoAction(0));
397 : 0 : SfxUndoManager::RemoveLastUndoAction();
398 [ # # ]: 0 : return dynamic_cast<SwUndo *>(pLastUndo);
399 : : }
400 : :
401 : : // svl::IUndoManager /////////////////////////////////////////////////////
402 : :
403 : 25036 : void UndoManager::EnableUndo(bool bEnable)
404 : : {
405 : : // SfxUndoManager does not have a counter anymore, but reverted to the old behavior of
406 : : // having a simple boolean flag for locking. So, simply forward.
407 : 25036 : SfxUndoManager::EnableUndo(bEnable);
408 : 25036 : }
409 : :
410 : 28491 : void UndoManager::AddUndoAction(SfxUndoAction *pAction, sal_Bool bTryMerge)
411 : : {
412 [ - + ]: 28491 : SwUndo *const pUndo( dynamic_cast<SwUndo *>(pAction) );
413 [ + + ]: 28491 : if (pUndo)
414 : : {
415 [ + - ]: 28409 : if (nsRedlineMode_t::REDLINE_NONE == pUndo->GetRedlineMode())
416 : : {
417 : 28409 : pUndo->SetRedlineMode( m_rRedlineAccess.GetRedlineMode() );
418 : : }
419 : : }
420 : 28491 : SfxUndoManager::AddUndoAction(pAction, bTryMerge);
421 : : // if the undo nodes array is too large, delete some actions
422 [ - + ]: 28491 : while (UNDO_ACTION_LIMIT < GetUndoNodes().Count())
423 : : {
424 : 0 : RemoveOldestUndoActions(1);
425 : : }
426 : 28491 : }
427 : :
428 : : class CursorGuard
429 : : {
430 : : public:
431 : 52 : CursorGuard(SwEditShell & rShell, bool const bSave)
432 : : : m_rShell(rShell)
433 : 52 : , m_bSaveCursor(bSave)
434 : : {
435 [ - + ]: 52 : if (m_bSaveCursor)
436 : : {
437 : 0 : m_rShell.Push(); // prevent modification of current cursor
438 : : }
439 : 52 : }
440 : 52 : ~CursorGuard()
441 : : {
442 [ - + ]: 52 : if (m_bSaveCursor)
443 : : {
444 : 0 : m_rShell.Pop();
445 : : }
446 : 52 : }
447 : : private:
448 : : SwEditShell & m_rShell;
449 : : bool const m_bSaveCursor;
450 : : };
451 : :
452 : 52 : bool UndoManager::impl_DoUndoRedo(UndoOrRedo_t const undoOrRedo)
453 : : {
454 : 52 : SwDoc & rDoc(*GetUndoNodes().GetDoc());
455 : :
456 [ + - ]: 52 : UnoActionContext c(& rDoc); // exception-safe StartAllAction/EndAllAction
457 : :
458 [ + - ]: 52 : SwEditShell *const pEditShell( rDoc.GetEditShell() );
459 : :
460 : : OSL_ENSURE(pEditShell, "sw::UndoManager needs a SwEditShell!");
461 [ - + ]: 52 : if (!pEditShell)
462 : : {
463 [ # # ]: 0 : throw uno::RuntimeException();
464 : : }
465 : :
466 : : // in case the model has controllers locked, the Undo should not
467 : : // change the view cursors!
468 [ + - ]: 52 : bool const bSaveCursors(pEditShell->CursorsLocked());
469 [ + - ][ + - ]: 52 : CursorGuard(*pEditShell, bSaveCursors);
470 [ + - ]: 52 : if (!bSaveCursors)
471 : : {
472 : : // (in case Undo was called via API) clear the cursors:
473 [ + - ]: 52 : pEditShell->KillPams();
474 [ + - ]: 52 : pEditShell->SetMark();
475 [ + - ]: 52 : pEditShell->ClearMark();
476 : : }
477 : :
478 : 52 : bool bRet(false);
479 : :
480 [ + - ]: 52 : ::sw::UndoRedoContext context(rDoc, *pEditShell);
481 : :
482 : : // N.B. these may throw!
483 [ + + ]: 52 : if (UNDO == undoOrRedo)
484 : : {
485 [ + + ]: 46 : bRet = SfxUndoManager::UndoWithContext(context);
486 : : }
487 : : else
488 : : {
489 [ + + ]: 6 : bRet = SfxUndoManager::RedoWithContext(context);
490 : : }
491 : :
492 [ + - ]: 44 : if (bRet)
493 : : {
494 : : // if we are at the "last save" position, the document is not modified
495 [ + - ][ - + ]: 44 : if (SfxUndoManager::HasTopUndoActionMark(m_UndoSaveMark))
496 : : {
497 [ # # ]: 0 : m_rState.ResetModified();
498 : : }
499 : : else
500 : : {
501 [ + - ]: 44 : m_rState.SetModified();
502 : : }
503 : : }
504 : :
505 [ + - ]: 44 : pEditShell->HandleUndoRedoContext(context);
506 : :
507 [ + - ][ + - ]: 52 : return bRet;
508 : : }
509 : :
510 : 46 : sal_Bool UndoManager::Undo()
511 : : {
512 : 46 : bool const bRet = impl_DoUndoRedo(UNDO);
513 : 42 : return bRet;
514 : : }
515 : :
516 : 6 : sal_Bool UndoManager::Redo()
517 : : {
518 : 6 : bool const bRet = impl_DoUndoRedo(REDO);
519 : 2 : return bRet;
520 : : }
521 : :
522 : : /** N.B.: this does _not_ call SfxUndoManager::Repeat because it is not
523 : : possible to wrap a list action around it:
524 : : calling EnterListAction here will cause SfxUndoManager::Repeat
525 : : to repeat the list action!
526 : : */
527 : : bool
528 : 0 : UndoManager::Repeat(::sw::RepeatContext & rContext,
529 : : sal_uInt16 const nRepeatCount)
530 : : {
531 [ # # ][ # # ]: 0 : if (SfxUndoManager::IsInListAction())
532 : : {
533 : : OSL_ENSURE(false, "repeat in open list action???");
534 : 0 : return false;
535 : : }
536 [ # # ][ # # ]: 0 : if (!SfxUndoManager::GetUndoActionCount(TopLevel))
537 : : {
538 : 0 : return false;
539 : : }
540 [ # # ]: 0 : SfxUndoAction *const pRepeatAction(GetUndoAction(0));
541 : : OSL_ASSERT(pRepeatAction);
542 [ # # ][ # # ]: 0 : if (!pRepeatAction || !pRepeatAction->CanRepeat(rContext))
[ # # ][ # # ]
543 : : {
544 : 0 : return false;
545 : : }
546 : :
547 [ # # ]: 0 : ::rtl::OUString const comment(pRepeatAction->GetComment());
548 [ # # ][ # # ]: 0 : ::rtl::OUString const rcomment(pRepeatAction->GetRepeatComment(rContext));
[ # # ]
549 [ # # ]: 0 : sal_uInt16 const nId(pRepeatAction->GetId());
550 [ # # ][ # # ]: 0 : if (DoesUndo())
551 : : {
552 [ # # ][ # # ]: 0 : EnterListAction(comment, rcomment, nId);
[ # # ][ # # ]
[ # # ]
553 : : }
554 : :
555 : 0 : SwPaM *const pFirstCursor(& rContext.GetRepeatPaM());
556 [ # # ]: 0 : do { // iterate over ring
557 [ # # ]: 0 : for (sal_uInt16 nRptCnt = nRepeatCount; nRptCnt > 0; --nRptCnt)
558 : : {
559 [ # # ]: 0 : pRepeatAction->Repeat(rContext);
560 : : }
561 : 0 : rContext.m_bDeleteRepeated = false; // reset for next PaM
562 : : rContext.m_pCurrentPaM =
563 : 0 : static_cast<SwPaM*>(rContext.m_pCurrentPaM->GetNext());
564 : 0 : } while (pFirstCursor != & rContext.GetRepeatPaM());
565 : :
566 [ # # ][ # # ]: 0 : if (DoesUndo())
567 : : {
568 [ # # ]: 0 : LeaveListAction();
569 : : }
570 : 0 : return true;
571 : : }
572 : :
573 : : } // namespace sw
574 : :
575 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|