Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <svx/svdview.hxx>
21 :
22 : #include <editsh.hxx>
23 : #include <fesh.hxx>
24 : #include <doc.hxx>
25 : #include <IDocumentUndoRedo.hxx>
26 : #include <pam.hxx>
27 : #include <UndoCore.hxx>
28 : #include <swundo.hxx>
29 : #include <dcontact.hxx>
30 : #include <flyfrm.hxx>
31 : #include <frmfmt.hxx>
32 : #include <viewimp.hxx>
33 : #include <docsh.hxx>
34 : #include <pagefrm.hxx>
35 :
36 : /** helper function to select all objects in an SdrMarkList;
37 : * implementation: see below */
38 : static void lcl_SelectSdrMarkList( SwEditShell* pShell,
39 : const SdrMarkList* pSdrMarkList );
40 :
41 0 : bool SwEditShell::CursorsLocked() const
42 : {
43 0 : return GetDoc()->GetDocShell()->GetModel()->hasControllersLocked();
44 : }
45 :
46 0 : void SwEditShell::HandleUndoRedoContext(::sw::UndoRedoContext & rContext)
47 : {
48 : // do nothing if somebody has locked controllers!
49 0 : if (CursorsLocked())
50 : {
51 0 : return;
52 : }
53 :
54 0 : SwFrmFmt * pSelFmt(0);
55 0 : SdrMarkList * pMarkList(0);
56 0 : rContext.GetSelections(pSelFmt, pMarkList);
57 :
58 0 : if (pSelFmt) // select frame
59 : {
60 0 : if (RES_DRAWFRMFMT == pSelFmt->Which())
61 : {
62 0 : SdrObject* pSObj = pSelFmt->FindSdrObject();
63 : static_cast<SwFEShell*>(this)->SelectObj(
64 0 : pSObj->GetCurrentBoundRect().Center() );
65 : }
66 : else
67 : {
68 0 : Point aPt;
69 : SwFlyFrm *const pFly =
70 0 : static_cast<SwFlyFrmFmt*>(pSelFmt)->GetFrm(& aPt, false);
71 0 : if (pFly)
72 : {
73 : // fdo#36681: Invalidate the content and layout to refresh
74 : // the picture anchoring properly
75 0 : SwPageFrm* pPageFrm = pFly->FindPageFrmOfAnchor();
76 0 : pPageFrm->InvalidateFlyLayout();
77 0 : pPageFrm->InvalidateCntnt();
78 :
79 0 : static_cast<SwFEShell*>(this)->SelectFlyFrm(*pFly, true);
80 : }
81 : }
82 : }
83 0 : else if (pMarkList)
84 : {
85 0 : lcl_SelectSdrMarkList( this, pMarkList );
86 : }
87 0 : else if (GetCrsr()->GetNext() != GetCrsr())
88 : {
89 : // current cursor is the last one:
90 : // go around the ring, to the first cursor
91 0 : GoNextCrsr();
92 : }
93 : }
94 :
95 0 : bool SwEditShell::Undo(sal_uInt16 const nCount)
96 : {
97 0 : SET_CURR_SHELL( this );
98 :
99 : // current undo state was not saved
100 0 : ::sw::UndoGuard const undoGuard(GetDoc()->GetIDocumentUndoRedo());
101 0 : bool bRet = false;
102 :
103 0 : StartAllAction();
104 : {
105 : // Actually it should be enough to just work on the current Cursor, i.e. if there is a cycle
106 : // cancel the latter temporarily, so that an insert during Undo is not done in all areas.
107 0 : KillPams();
108 0 : SetMark(); // Bound1 and Bound2 in the same Node
109 0 : ClearMark();
110 :
111 : // Keep Cursor - so that we're able to set it at
112 : // the same position for autoformat or autocorrection
113 0 : SwUndoId nLastUndoId(UNDO_EMPTY);
114 0 : GetLastUndoInfo(0, & nLastUndoId);
115 : const bool bRestoreCrsr = nCount == 1
116 0 : && ( UNDO_AUTOFORMAT == nLastUndoId
117 0 : || UNDO_AUTOCORRECT == nLastUndoId
118 0 : || UNDO_SETDEFTATTR == nLastUndoId );
119 0 : Push();
120 :
121 : // Destroy stored TableBoxPtr. A dection is only permitted for the new "Box"!
122 0 : ClearTblBoxCntnt();
123 :
124 0 : const RedlineMode_t eOld = GetDoc()->GetRedlineMode();
125 :
126 : try {
127 0 : for (sal_uInt16 i = 0; i < nCount; ++i)
128 : {
129 0 : bRet = GetDoc()->GetIDocumentUndoRedo().Undo()
130 0 : || bRet;
131 : }
132 0 : } catch (const ::com::sun::star::uno::Exception & e) {
133 : OSL_TRACE("SwEditShell::Undo(): exception caught:\n %s",
134 : OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8)
135 : .getStr());
136 : }
137 :
138 0 : if (bRestoreCrsr)
139 : { // fdo#39003 Pop does not touch the rest of the cursor ring
140 0 : KillPams(); // so call this first to get rid of unwanted cursors
141 : }
142 0 : Pop( !bRestoreCrsr );
143 :
144 0 : GetDoc()->SetRedlineMode( eOld );
145 0 : GetDoc()->CompressRedlines();
146 :
147 : // automatic detection of the new "Box"
148 0 : SaveTblBoxCntnt();
149 : }
150 0 : EndAllAction();
151 :
152 0 : return bRet;
153 : }
154 :
155 0 : bool SwEditShell::Redo(sal_uInt16 const nCount)
156 : {
157 0 : SET_CURR_SHELL( this );
158 :
159 0 : bool bRet = false;
160 :
161 : // undo state was not saved
162 0 : ::sw::UndoGuard const undoGuard(GetDoc()->GetIDocumentUndoRedo());
163 :
164 0 : StartAllAction();
165 :
166 : {
167 : // Actually it should be enough to just work on the current Cursor, i.e. if there is a cycle
168 : // cancel the latter temporarily, so that an insert during Undo is not done in all areas.
169 0 : KillPams();
170 0 : SetMark(); // Bound1 and Bound2 in the same Node
171 0 : ClearMark();
172 :
173 0 : SwUndoId nFirstRedoId(UNDO_EMPTY);
174 0 : GetDoc()->GetIDocumentUndoRedo().GetFirstRedoInfo(0, & nFirstRedoId);
175 0 : const bool bRestoreCrsr = nCount == 1 && UNDO_SETDEFTATTR == nFirstRedoId;
176 0 : Push();
177 :
178 : // Destroy stored TableBoxPtr. A dection is only permitted for the new "Box"!
179 0 : ClearTblBoxCntnt();
180 :
181 0 : RedlineMode_t eOld = GetDoc()->GetRedlineMode();
182 :
183 : try {
184 0 : for (sal_uInt16 i = 0; i < nCount; ++i)
185 : {
186 0 : bRet = GetDoc()->GetIDocumentUndoRedo().Redo()
187 0 : || bRet;
188 : }
189 0 : } catch (const ::com::sun::star::uno::Exception & e) {
190 : OSL_TRACE("SwEditShell::Redo(): exception caught:\n %s",
191 : OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8)
192 : .getStr());
193 : }
194 :
195 0 : Pop( !bRestoreCrsr );
196 :
197 0 : GetDoc()->SetRedlineMode( eOld );
198 0 : GetDoc()->CompressRedlines();
199 :
200 : // automatic detection of the new "Box"
201 0 : SaveTblBoxCntnt();
202 : }
203 :
204 0 : EndAllAction();
205 :
206 0 : return bRet;
207 : }
208 :
209 0 : bool SwEditShell::Repeat(sal_uInt16 const nCount)
210 : {
211 0 : SET_CURR_SHELL( this );
212 :
213 0 : bool bRet = false;
214 0 : StartAllAction();
215 :
216 : try {
217 0 : ::sw::RepeatContext context(*GetDoc(), *GetCrsr());
218 0 : bRet = GetDoc()->GetIDocumentUndoRedo().Repeat( context, nCount )
219 0 : || bRet;
220 0 : } catch (const ::com::sun::star::uno::Exception & e) {
221 : OSL_TRACE("SwEditShell::Repeat(): exception caught:\n %s",
222 : OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8)
223 : .getStr());
224 : }
225 :
226 0 : EndAllAction();
227 0 : return bRet;
228 : }
229 :
230 0 : static void lcl_SelectSdrMarkList( SwEditShell* pShell,
231 : const SdrMarkList* pSdrMarkList )
232 : {
233 : OSL_ENSURE( pShell != NULL, "need shell!" );
234 : OSL_ENSURE( pSdrMarkList != NULL, "need mark list" );
235 :
236 0 : if( pShell->ISA( SwFEShell ) )
237 : {
238 0 : SwFEShell* pFEShell = static_cast<SwFEShell*>( pShell );
239 0 : bool bFirst = true;
240 0 : for( sal_uInt16 i = 0; i < pSdrMarkList->GetMarkCount(); ++i )
241 : {
242 0 : SdrObject *pObj = pSdrMarkList->GetMark( i )->GetMarkedSdrObj();
243 0 : if( pObj )
244 : {
245 0 : pFEShell->SelectObj( Point(), bFirst ? 0 : SW_ADD_SELECT, pObj );
246 0 : bFirst = false;
247 : }
248 : }
249 :
250 : // the old implementation would always unselect
251 : // objects, even if no new ones were selected. If this
252 : // is a problem, we need to re-work this a little.
253 : OSL_ENSURE( pSdrMarkList->GetMarkCount() != 0, "empty mark list" );
254 : }
255 0 : }
256 :
257 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|