xref: /trunk/main/sw/source/core/edit/edundo.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sw.hxx"
30 
31 #include <svx/svdview.hxx>
32 
33 #include <editsh.hxx>
34 #include <fesh.hxx>
35 #include <doc.hxx>
36 #include <IDocumentUndoRedo.hxx>
37 #include <pam.hxx>
38 #include <UndoCore.hxx>
39 #include <swundo.hxx>
40 #include <dcontact.hxx>
41 #include <flyfrm.hxx>
42 #include <frmfmt.hxx>
43 #include <viewimp.hxx>
44 #include <docsh.hxx>
45 
46 
47 /** helper function to select all objects in an SdrMarkList;
48  * implementation: see below */
49 void lcl_SelectSdrMarkList( SwEditShell* pShell,
50                             const SdrMarkList* pSdrMarkList );
51 
52 bool SwEditShell::CursorsLocked() const
53 {
54 
55     return GetDoc()->GetDocShell()->GetModel()->hasControllersLocked();
56 }
57 
58 void
59 SwEditShell::HandleUndoRedoContext(::sw::UndoRedoContext & rContext)
60 {
61     // do nothing if somebody has locked controllers!
62     if (CursorsLocked())
63     {
64         return;
65     }
66 
67     SwFrmFmt * pSelFmt(0);
68     SdrMarkList * pMarkList(0);
69     rContext.GetSelections(pSelFmt, pMarkList);
70 
71     if (pSelFmt) // select frame
72     {
73         if (RES_DRAWFRMFMT == pSelFmt->Which())
74         {
75             SdrObject* pSObj = pSelFmt->FindSdrObject();
76             static_cast<SwFEShell*>(this)->SelectObj(
77                     pSObj->GetCurrentBoundRect().Center() );
78         }
79         else
80         {
81             Point aPt;
82             SwFlyFrm *const pFly =
83                 static_cast<SwFlyFrmFmt*>(pSelFmt)->GetFrm(& aPt, false);
84             if (pFly)
85             {
86                 static_cast<SwFEShell*>(this)->SelectFlyFrm(*pFly, true);
87             }
88         }
89     }
90     else if (pMarkList)
91     {
92         lcl_SelectSdrMarkList( this, pMarkList );
93     }
94     else if (GetCrsr()->GetNext() != GetCrsr())
95     {
96         // current cursor is the last one:
97         // go around the ring, to the first cursor
98         GoNextCrsr();
99     }
100 }
101 
102 bool SwEditShell::Undo(sal_uInt16 const nCount)
103 {
104 	SET_CURR_SHELL( this );
105 
106     // #105332# current undo state was not saved
107     ::sw::UndoGuard const undoGuard(GetDoc()->GetIDocumentUndoRedo());
108 	sal_Bool bRet = sal_False;
109 
110 	StartAllAction();
111 	{
112 		// eigentlich muesste ja nur der aktuelle Cursor berarbeitet
113 		// werden, d.H. falls ein Ring besteht, diesen temporaer aufheben,
114 		// damit nicht bei Einfuge-Operationen innerhalb von Undo
115 		// an allen Bereichen eingefuegt wird.
116 		KillPams();
117 		SetMark();          // Bound1 und Bound2 in den gleichen Node
118 		ClearMark();
119 
120 		// JP 02.04.98: Cursor merken - beim Auto-Format/-Korrektur
121 		// 				soll dieser wieder an die Position
122         SwUndoId nLastUndoId(UNDO_EMPTY);
123         GetDoc()->GetIDocumentUndoRedo().GetLastUndoInfo(0, & nLastUndoId);
124         bool bRestoreCrsr = 1 == nCount && (UNDO_AUTOFORMAT == nLastUndoId ||
125 										   UNDO_AUTOCORRECT == nLastUndoId );
126 		Push();
127 
128 		//JP 18.09.97: gesicherten TabellenBoxPtr zerstoeren, eine autom.
129 		//			Erkennung darf nur noch fuer die neue "Box" erfolgen!
130 		ClearTblBoxCntnt();
131 
132 		RedlineMode_t eOld = GetDoc()->GetRedlineMode();
133 
134         try {
135             for (sal_uInt16 i = 0; i < nCount; ++i)
136             {
137                 bRet = GetDoc()->GetIDocumentUndoRedo().Undo()
138                     || bRet;
139             }
140         } catch (::com::sun::star::uno::Exception & e) {
141             OSL_TRACE("SwEditShell::Undo(): exception caught:\n %s",
142                 ::rtl::OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8)
143                     .getStr());
144         }
145 
146 		Pop( !bRestoreCrsr );
147 
148 		GetDoc()->SetRedlineMode( eOld );
149 		GetDoc()->CompressRedlines();
150 
151 		//JP 18.09.97: autom. Erkennung  fuer die neue "Box"
152 		SaveTblBoxCntnt();
153 	}
154 	EndAllAction();
155 
156 	return bRet;
157 }
158 
159 bool SwEditShell::Redo(sal_uInt16 const nCount)
160 {
161 	SET_CURR_SHELL( this );
162 
163 	sal_Bool bRet = sal_False;
164 
165     // #105332# undo state was not saved
166     ::sw::UndoGuard const undoGuard(GetDoc()->GetIDocumentUndoRedo());
167 
168 	StartAllAction();
169 
170 	{
171 		// eigentlich muesste ja nur der aktuelle Cursor berarbeitet
172 		// werden, d.H. falls ein Ring besteht, diesen temporaer aufheben,
173 		// damit nicht bei Einfuge-Operationen innerhalb von Undo
174 		// an allen Bereichen eingefuegt wird.
175 		KillPams();
176 		SetMark();          // Bound1 und Bound2 in den gleichen Node
177 		ClearMark();
178 
179 		//JP 18.09.97: gesicherten TabellenBoxPtr zerstoeren, eine autom.
180 		//			Erkennung darf nur noch fuer die neue "Box" erfolgen!
181 		ClearTblBoxCntnt();
182 
183 		RedlineMode_t eOld = GetDoc()->GetRedlineMode();
184 
185         try {
186             for (sal_uInt16 i = 0; i < nCount; ++i)
187             {
188                 bRet = GetDoc()->GetIDocumentUndoRedo().Redo()
189                     || bRet;
190             }
191         } catch (::com::sun::star::uno::Exception & e) {
192             OSL_TRACE("SwEditShell::Redo(): exception caught:\n %s",
193                 ::rtl::OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8)
194                     .getStr());
195         }
196 
197 		GetDoc()->SetRedlineMode( eOld );
198 		GetDoc()->CompressRedlines();
199 
200 		//JP 18.09.97: autom. Erkennung  fuer die neue "Box"
201 		SaveTblBoxCntnt();
202 	}
203 
204 	EndAllAction();
205 
206 	return bRet;
207 }
208 
209 
210 bool SwEditShell::Repeat(sal_uInt16 const nCount)
211 {
212 	SET_CURR_SHELL( this );
213 
214 	sal_Bool bRet = sal_False;
215 	StartAllAction();
216 
217     try {
218         ::sw::RepeatContext context(*GetDoc(), *GetCrsr());
219         bRet = GetDoc()->GetIDocumentUndoRedo().Repeat( context, nCount )
220             || bRet;
221     } catch (::com::sun::star::uno::Exception & e) {
222         OSL_TRACE("SwEditShell::Repeat(): exception caught:\n %s",
223             ::rtl::OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8)
224                 .getStr());
225     }
226 
227 	EndAllAction();
228 	return bRet;
229 }
230 
231 
232 void lcl_SelectSdrMarkList( SwEditShell* pShell,
233                             const SdrMarkList* pSdrMarkList )
234 {
235     ASSERT( pShell != NULL, "need shell!" );
236     ASSERT( pSdrMarkList != NULL, "need mark list" );
237 
238     if( pShell->ISA( SwFEShell ) )
239     {
240         SwFEShell* pFEShell = static_cast<SwFEShell*>( pShell );
241         bool bFirst = true;
242         for( sal_uInt16 i = 0; i < pSdrMarkList->GetMarkCount(); ++i )
243         {
244             SdrObject *pObj = pSdrMarkList->GetMark( i )->GetMarkedSdrObj();
245             if( pObj )
246             {
247                 pFEShell->SelectObj( Point(), bFirst ? 0 : SW_ADD_SELECT, pObj );
248                 bFirst = false;
249             }
250         }
251 
252         // the old implementation would always unselect
253         // objects, even if no new ones were selected. If this
254         // is a problem, we need to re-work this a little.
255         ASSERT( pSdrMarkList->GetMarkCount() != 0, "empty mark list" );
256     }
257 }
258 
259