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 #include <iterator>
27
28
29 #include "crsrsh.hxx"
30 #include "ndtxt.hxx"
31 #include <docary.hxx>
32 #include <boost/bind.hpp>
33
34 #include "IMark.hxx"
35 #include "callnk.hxx"
36 #include "swcrsr.hxx"
37 #include <IDocumentMarkAccess.hxx>
38 #include <IDocumentSettingAccess.hxx>
39
40 using namespace std;
41
42 namespace
43 {
44 struct CrsrStateHelper
45 {
CrsrStateHelper__anondb1d64350111::CrsrStateHelper46 CrsrStateHelper(SwCrsrShell& rShell)
47 : m_aLink(rShell)
48 , m_pCrsr(rShell.GetSwCrsr())
49 , m_aSaveState(*m_pCrsr)
50 { }
51
SetCrsrToMark__anondb1d64350111::CrsrStateHelper52 void SetCrsrToMark(::sw::mark::IMark const * const pMark)
53 {
54 *(m_pCrsr->GetPoint()) = pMark->GetMarkStart();
55 if(pMark->IsExpanded())
56 {
57 m_pCrsr->SetMark();
58 *(m_pCrsr->GetMark()) = pMark->GetMarkEnd();
59 }
60 }
61
62 // returns true if the Cursor had been rolled back
RollbackIfIllegal__anondb1d64350111::CrsrStateHelper63 bool RollbackIfIllegal()
64 {
65 if(m_pCrsr->IsSelOvr(nsSwCursorSelOverFlags::SELOVER_CHECKNODESSECTION
66 | nsSwCursorSelOverFlags::SELOVER_TOGGLE))
67 {
68 m_pCrsr->DeleteMark();
69 m_pCrsr->RestoreSavePos();
70 return true;
71 }
72 return false;
73 }
74
75 SwCallLink m_aLink;
76 SwCursor* m_pCrsr;
77 SwCrsrSaveState m_aSaveState;
78 };
79
80
lcl_ReverseMarkOrderingByEnd(const IDocumentMarkAccess::pMark_t & rpFirst,const IDocumentMarkAccess::pMark_t & rpSecond)81 static bool lcl_ReverseMarkOrderingByEnd(const IDocumentMarkAccess::pMark_t& rpFirst,
82 const IDocumentMarkAccess::pMark_t& rpSecond)
83 {
84 return rpFirst->GetMarkEnd() > rpSecond->GetMarkEnd();
85 }
86
lcl_IsInvisibleBookmark(IDocumentMarkAccess::pMark_t pMark)87 static bool lcl_IsInvisibleBookmark(IDocumentMarkAccess::pMark_t pMark)
88 {
89 return IDocumentMarkAccess::GetType(*pMark) != IDocumentMarkAccess::BOOKMARK;
90 }
91 }
92
93 // at CurCrsr.SPoint
SetBookmark(const KeyCode & rCode,const::rtl::OUString & rName,const::rtl::OUString & rShortName,IDocumentMarkAccess::MarkType eMark)94 ::sw::mark::IMark* SwCrsrShell::SetBookmark(
95 const KeyCode& rCode,
96 const ::rtl::OUString& rName,
97 const ::rtl::OUString& rShortName,
98 IDocumentMarkAccess::MarkType eMark)
99 {
100 StartAction();
101 ::sw::mark::IMark* pMark = getIDocumentMarkAccess()->makeMark(
102 *GetCrsr(),
103 rName,
104 eMark);
105 ::sw::mark::IBookmark* pBookmark = dynamic_cast< ::sw::mark::IBookmark* >(pMark);
106 if(pBookmark)
107 {
108 pBookmark->SetKeyCode(rCode);
109 pBookmark->SetShortName(rShortName);
110 }
111 EndAction();
112 return pMark;
113 }
114 // setzt CurCrsr.SPoint
115
GotoMark(const::sw::mark::IMark * const pMark,bool bAtStart)116 bool SwCrsrShell::GotoMark(const ::sw::mark::IMark* const pMark, bool bAtStart)
117 {
118 // watch Crsr-Moves
119 CrsrStateHelper aCrsrSt(*this);
120 if ( bAtStart )
121 *(aCrsrSt.m_pCrsr)->GetPoint() = pMark->GetMarkStart();
122 else
123 *(aCrsrSt.m_pCrsr)->GetPoint() = pMark->GetMarkEnd();
124 if(aCrsrSt.RollbackIfIllegal()) return false;
125
126 UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY);
127 return true;
128 }
129
GotoMark(const::sw::mark::IMark * const pMark)130 bool SwCrsrShell::GotoMark(const ::sw::mark::IMark* const pMark)
131 {
132 // watch Crsr-Moves
133 CrsrStateHelper aCrsrSt(*this);
134 aCrsrSt.SetCrsrToMark(pMark);
135
136 if(aCrsrSt.RollbackIfIllegal()) return false;
137
138 UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY);
139 return true;
140 }
141
GoNextBookmark()142 bool SwCrsrShell::GoNextBookmark()
143 {
144 IDocumentMarkAccess* const pMarkAccess = getIDocumentMarkAccess();
145 IDocumentMarkAccess::container_t vCandidates;
146 remove_copy_if(
147 upper_bound(
148 pMarkAccess->getBookmarksBegin(),
149 pMarkAccess->getBookmarksEnd(),
150 *GetCrsr()->GetPoint(),
151 bind(&::sw::mark::IMark::StartsAfter, _2, _1)), // finds the first that is starting after
152 pMarkAccess->getBookmarksEnd(),
153 back_inserter(vCandidates),
154 &lcl_IsInvisibleBookmark);
155
156 // watch Crsr-Moves
157 CrsrStateHelper aCrsrSt(*this);
158 IDocumentMarkAccess::const_iterator_t ppMark = vCandidates.begin();
159 for(; ppMark!=vCandidates.end(); ++ppMark)
160 {
161 aCrsrSt.SetCrsrToMark(ppMark->get());
162 if(!aCrsrSt.RollbackIfIllegal())
163 break; // found legal move
164 }
165 if(ppMark==vCandidates.end())
166 {
167 SttEndDoc(false);
168 return false;
169 }
170
171 UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY);
172 return true;
173 }
174
GoPrevBookmark()175 bool SwCrsrShell::GoPrevBookmark()
176 {
177 IDocumentMarkAccess* const pMarkAccess = getIDocumentMarkAccess();
178 // candidates from which to choose the mark before
179 // no need to consider marks starting after rPos
180 IDocumentMarkAccess::container_t vCandidates;
181 remove_copy_if(
182 pMarkAccess->getBookmarksBegin(),
183 upper_bound(
184 pMarkAccess->getBookmarksBegin(),
185 pMarkAccess->getBookmarksEnd(),
186 *GetCrsr()->GetPoint(),
187 bind(&::sw::mark::IMark::StartsAfter, _2, _1)),
188 back_inserter(vCandidates),
189 &lcl_IsInvisibleBookmark);
190 sort(
191 vCandidates.begin(),
192 vCandidates.end(),
193 &lcl_ReverseMarkOrderingByEnd);
194
195 // watch Crsr-Moves
196 CrsrStateHelper aCrsrSt(*this);
197 IDocumentMarkAccess::const_iterator_t ppMark = vCandidates.begin();
198 for(; ppMark!=vCandidates.end(); ++ppMark)
199 {
200 // ignoring those not ending before the Crsr
201 // (we were only able to eliminate those starting
202 // behind the Crsr by the upper_bound(..)
203 // above)
204 if(!(**ppMark).EndsBefore(*GetCrsr()->GetPoint()))
205 continue;
206 aCrsrSt.SetCrsrToMark(ppMark->get());
207 if(!aCrsrSt.RollbackIfIllegal())
208 break; // found legal move
209 }
210 if(ppMark==vCandidates.end())
211 {
212 SttEndDoc(true);
213 return false;
214 }
215
216 UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY);
217 return true;
218 }
219
IsFormProtected()220 bool SwCrsrShell::IsFormProtected()
221 {
222 return getIDocumentSettingAccess()->get(IDocumentSettingAccess::PROTECT_FORM);
223 }
224
GetCurrentFieldmark()225 ::sw::mark::IFieldmark* SwCrsrShell::GetCurrentFieldmark()
226 {
227 // TODO: Refactor
228 SwPosition pos(*GetCrsr()->GetPoint());
229 return getIDocumentMarkAccess()->getFieldmarkFor(pos);
230 }
231
GetFieldmarkAfter()232 ::sw::mark::IFieldmark* SwCrsrShell::GetFieldmarkAfter()
233 {
234 SwPosition pos(*GetCrsr()->GetPoint());
235 return getIDocumentMarkAccess()->getFieldmarkAfter(pos);
236 }
237
GetFieldmarkBefore()238 ::sw::mark::IFieldmark* SwCrsrShell::GetFieldmarkBefore()
239 {
240 SwPosition pos(*GetCrsr()->GetPoint());
241 return getIDocumentMarkAccess()->getFieldmarkBefore(pos);
242 }
243
GotoFieldmark(::sw::mark::IFieldmark const * const pMark)244 bool SwCrsrShell::GotoFieldmark(::sw::mark::IFieldmark const * const pMark)
245 {
246 if(pMark==NULL) return false;
247
248 // watch Crsr-Moves
249 CrsrStateHelper aCrsrSt(*this);
250 aCrsrSt.SetCrsrToMark(pMark);
251 //aCrsrSt.m_pCrsr->GetPoint()->nContent--;
252 //aCrsrSt.m_pCrsr->GetMark()->nContent++;
253 if(aCrsrSt.RollbackIfIllegal()) return false;
254
255 UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY);
256 return true;
257 }
258