xref: /trunk/main/sw/source/core/crsr/crbm.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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