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