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
CursorsLocked() const48 bool SwEditShell::CursorsLocked() const
49 {
50
51 return GetDoc()->GetDocShell()->GetModel()->hasControllersLocked();
52 }
53
54 void
HandleUndoRedoContext(::sw::UndoRedoContext & rContext)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
Undo(sal_uInt16 const nCount)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 const 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
Redo(sal_uInt16 const nCount)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
Repeat(sal_uInt16 const nCount)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
lcl_SelectSdrMarkList(SwEditShell * pShell,const SdrMarkList * pSdrMarkList)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