xref: /trunk/main/sw/source/core/edit/edundo.cxx (revision 89358e0f)
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         SwUndoId nLastUndoId(UNDO_EMPTY);
117         GetLastUndoInfo(0, & nLastUndoId);
118         const bool bRestoreCrsr = nCount == 1
119                                   && ( UNDO_AUTOFORMAT == nLastUndoId
120                                        || UNDO_AUTOCORRECT == nLastUndoId
121                                        || UNDO_SETDEFTATTR == 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         SwUndoId nFirstRedoId(UNDO_EMPTY);
176         GetDoc()->GetIDocumentUndoRedo().GetFirstRedoInfo(0, & nFirstRedoId);
177         const bool bRestoreCrsr = nCount == 1 && UNDO_SETDEFTATTR == nFirstRedoId;
178         Push();
179 
180         //JP 18.09.97: gesicherten TabellenBoxPtr zerstoeren, eine autom.
181         //			Erkennung darf nur noch fuer die neue "Box" erfolgen!
182         ClearTblBoxCntnt();
183 
184         RedlineMode_t eOld = GetDoc()->GetRedlineMode();
185 
186         try {
187             for (sal_uInt16 i = 0; i < nCount; ++i)
188             {
189                 bRet = GetDoc()->GetIDocumentUndoRedo().Redo()
190                     || bRet;
191             }
192         } catch (::com::sun::star::uno::Exception & e) {
193             OSL_TRACE("SwEditShell::Redo(): exception caught:\n %s",
194                 ::rtl::OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8)
195                     .getStr());
196         }
197 
198         Pop( !bRestoreCrsr );
199 
200         GetDoc()->SetRedlineMode( eOld );
201         GetDoc()->CompressRedlines();
202 
203         //JP 18.09.97: autom. Erkennung  fuer die neue "Box"
204         SaveTblBoxCntnt();
205     }
206 
207     EndAllAction();
208 
209     return bRet;
210 }
211 
212 
213 bool SwEditShell::Repeat(sal_uInt16 const nCount)
214 {
215 	SET_CURR_SHELL( this );
216 
217 	sal_Bool bRet = sal_False;
218 	StartAllAction();
219 
220     try {
221         ::sw::RepeatContext context(*GetDoc(), *GetCrsr());
222         bRet = GetDoc()->GetIDocumentUndoRedo().Repeat( context, nCount )
223             || bRet;
224     } catch (::com::sun::star::uno::Exception & e) {
225         OSL_TRACE("SwEditShell::Repeat(): exception caught:\n %s",
226             ::rtl::OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8)
227                 .getStr());
228     }
229 
230 	EndAllAction();
231 	return bRet;
232 }
233 
234 
235 void lcl_SelectSdrMarkList( SwEditShell* pShell,
236                             const SdrMarkList* pSdrMarkList )
237 {
238     ASSERT( pShell != NULL, "need shell!" );
239     ASSERT( pSdrMarkList != NULL, "need mark list" );
240 
241     if( pShell->ISA( SwFEShell ) )
242     {
243         SwFEShell* pFEShell = static_cast<SwFEShell*>( pShell );
244         bool bFirst = true;
245         for( sal_uInt16 i = 0; i < pSdrMarkList->GetMarkCount(); ++i )
246         {
247             SdrObject *pObj = pSdrMarkList->GetMark( i )->GetMarkedSdrObj();
248             if( pObj )
249             {
250                 pFEShell->SelectObj( Point(), bFirst ? 0 : SW_ADD_SELECT, pObj );
251                 bFirst = false;
252             }
253         }
254 
255         // the old implementation would always unselect
256         // objects, even if no new ones were selected. If this
257         // is a problem, we need to re-work this a little.
258         ASSERT( pSdrMarkList->GetMarkCount() != 0, "empty mark list" );
259     }
260 }
261 
262