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