1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sw.hxx" 30 31 32 #include "crsrsh.hxx" 33 #include "ndtxt.hxx" 34 #include <docary.hxx> 35 #include <boost/bind.hpp> 36 37 #include "IMark.hxx" 38 #include "callnk.hxx" 39 #include "swcrsr.hxx" 40 #include <IDocumentMarkAccess.hxx> 41 #include <IDocumentSettingAccess.hxx> 42 43 using namespace std; 44 45 namespace 46 { 47 struct CrsrStateHelper 48 { 49 CrsrStateHelper(SwCrsrShell& rShell) 50 : m_aLink(rShell) 51 , m_pCrsr(rShell.GetSwCrsr()) 52 , m_aSaveState(*m_pCrsr) 53 { } 54 55 void SetCrsrToMark(::sw::mark::IMark const * const pMark) 56 { 57 *(m_pCrsr->GetPoint()) = pMark->GetMarkStart(); 58 if(pMark->IsExpanded()) 59 { 60 m_pCrsr->SetMark(); 61 *(m_pCrsr->GetMark()) = pMark->GetMarkEnd(); 62 } 63 } 64 65 // returns true if the Cursor had been rolled back 66 bool RollbackIfIllegal() 67 { 68 if(m_pCrsr->IsSelOvr(nsSwCursorSelOverFlags::SELOVER_CHECKNODESSECTION 69 | nsSwCursorSelOverFlags::SELOVER_TOGGLE)) 70 { 71 m_pCrsr->DeleteMark(); 72 m_pCrsr->RestoreSavePos(); 73 return true; 74 } 75 return false; 76 } 77 78 SwCallLink m_aLink; 79 SwCursor* m_pCrsr; 80 SwCrsrSaveState m_aSaveState; 81 }; 82 83 84 static bool lcl_ReverseMarkOrderingByEnd(const IDocumentMarkAccess::pMark_t& rpFirst, 85 const IDocumentMarkAccess::pMark_t& rpSecond) 86 { 87 return rpFirst->GetMarkEnd() > rpSecond->GetMarkEnd(); 88 } 89 90 static bool lcl_IsInvisibleBookmark(IDocumentMarkAccess::pMark_t pMark) 91 { 92 return IDocumentMarkAccess::GetType(*pMark) != IDocumentMarkAccess::BOOKMARK; 93 } 94 } 95 96 // at CurCrsr.SPoint 97 ::sw::mark::IMark* SwCrsrShell::SetBookmark( 98 const KeyCode& rCode, 99 const ::rtl::OUString& rName, 100 const ::rtl::OUString& rShortName, 101 IDocumentMarkAccess::MarkType eMark) 102 { 103 StartAction(); 104 ::sw::mark::IMark* pMark = getIDocumentMarkAccess()->makeMark( 105 *GetCrsr(), 106 rName, 107 eMark); 108 ::sw::mark::IBookmark* pBookmark = dynamic_cast< ::sw::mark::IBookmark* >(pMark); 109 if(pBookmark) 110 { 111 pBookmark->SetKeyCode(rCode); 112 pBookmark->SetShortName(rShortName); 113 } 114 EndAction(); 115 return pMark; 116 } 117 // setzt CurCrsr.SPoint 118 119 bool SwCrsrShell::GotoMark(const ::sw::mark::IMark* const pMark, bool bAtStart) 120 { 121 // watch Crsr-Moves 122 CrsrStateHelper aCrsrSt(*this); 123 if ( bAtStart ) 124 *(aCrsrSt.m_pCrsr)->GetPoint() = pMark->GetMarkStart(); 125 else 126 *(aCrsrSt.m_pCrsr)->GetPoint() = pMark->GetMarkEnd(); 127 if(aCrsrSt.RollbackIfIllegal()) return false; 128 129 UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY); 130 return true; 131 } 132 133 bool SwCrsrShell::GotoMark(const ::sw::mark::IMark* const pMark) 134 { 135 // watch Crsr-Moves 136 CrsrStateHelper aCrsrSt(*this); 137 aCrsrSt.SetCrsrToMark(pMark); 138 139 if(aCrsrSt.RollbackIfIllegal()) return false; 140 141 UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY); 142 return true; 143 } 144 145 bool SwCrsrShell::GoNextBookmark() 146 { 147 IDocumentMarkAccess* const pMarkAccess = getIDocumentMarkAccess(); 148 IDocumentMarkAccess::container_t vCandidates; 149 remove_copy_if( 150 upper_bound( 151 pMarkAccess->getBookmarksBegin(), 152 pMarkAccess->getBookmarksEnd(), 153 *GetCrsr()->GetPoint(), 154 bind(&::sw::mark::IMark::StartsAfter, _2, _1)), // finds the first that is starting after 155 pMarkAccess->getBookmarksEnd(), 156 back_inserter(vCandidates), 157 &lcl_IsInvisibleBookmark); 158 159 // watch Crsr-Moves 160 CrsrStateHelper aCrsrSt(*this); 161 IDocumentMarkAccess::const_iterator_t ppMark = vCandidates.begin(); 162 for(; ppMark!=vCandidates.end(); ++ppMark) 163 { 164 aCrsrSt.SetCrsrToMark(ppMark->get()); 165 if(!aCrsrSt.RollbackIfIllegal()) 166 break; // found legal move 167 } 168 if(ppMark==vCandidates.end()) 169 { 170 SttEndDoc(false); 171 return false; 172 } 173 174 UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY); 175 return true; 176 } 177 178 bool SwCrsrShell::GoPrevBookmark() 179 { 180 IDocumentMarkAccess* const pMarkAccess = getIDocumentMarkAccess(); 181 // candidates from which to choose the mark before 182 // no need to consider marks starting after rPos 183 IDocumentMarkAccess::container_t vCandidates; 184 remove_copy_if( 185 pMarkAccess->getBookmarksBegin(), 186 upper_bound( 187 pMarkAccess->getBookmarksBegin(), 188 pMarkAccess->getBookmarksEnd(), 189 *GetCrsr()->GetPoint(), 190 bind(&::sw::mark::IMark::StartsAfter, _2, _1)), 191 back_inserter(vCandidates), 192 &lcl_IsInvisibleBookmark); 193 sort( 194 vCandidates.begin(), 195 vCandidates.end(), 196 &lcl_ReverseMarkOrderingByEnd); 197 198 // watch Crsr-Moves 199 CrsrStateHelper aCrsrSt(*this); 200 IDocumentMarkAccess::const_iterator_t ppMark = vCandidates.begin(); 201 for(; ppMark!=vCandidates.end(); ++ppMark) 202 { 203 // ignoring those not ending before the Crsr 204 // (we were only able to eliminate those starting 205 // behind the Crsr by the upper_bound(..) 206 // above) 207 if(!(**ppMark).EndsBefore(*GetCrsr()->GetPoint())) 208 continue; 209 aCrsrSt.SetCrsrToMark(ppMark->get()); 210 if(!aCrsrSt.RollbackIfIllegal()) 211 break; // found legal move 212 } 213 if(ppMark==vCandidates.end()) 214 { 215 SttEndDoc(true); 216 return false; 217 } 218 219 UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY); 220 return true; 221 } 222 223 bool SwCrsrShell::IsFormProtected() 224 { 225 return getIDocumentSettingAccess()->get(IDocumentSettingAccess::PROTECT_FORM); 226 } 227 228 ::sw::mark::IFieldmark* SwCrsrShell::GetCurrentFieldmark() 229 { 230 // TODO: Refactor 231 SwPosition pos(*GetCrsr()->GetPoint()); 232 return getIDocumentMarkAccess()->getFieldmarkFor(pos); 233 } 234 235 ::sw::mark::IFieldmark* SwCrsrShell::GetFieldmarkAfter() 236 { 237 SwPosition pos(*GetCrsr()->GetPoint()); 238 return getIDocumentMarkAccess()->getFieldmarkAfter(pos); 239 } 240 241 ::sw::mark::IFieldmark* SwCrsrShell::GetFieldmarkBefore() 242 { 243 SwPosition pos(*GetCrsr()->GetPoint()); 244 return getIDocumentMarkAccess()->getFieldmarkBefore(pos); 245 } 246 247 bool SwCrsrShell::GotoFieldmark(::sw::mark::IFieldmark const * const pMark) 248 { 249 if(pMark==NULL) return false; 250 251 // watch Crsr-Moves 252 CrsrStateHelper aCrsrSt(*this); 253 aCrsrSt.SetCrsrToMark(pMark); 254 //aCrsrSt.m_pCrsr->GetPoint()->nContent--; 255 //aCrsrSt.m_pCrsr->GetMark()->nContent++; 256 if(aCrsrSt.RollbackIfIllegal()) return false; 257 258 UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY); 259 return true; 260 } 261