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 #include "precompiled_sw.hxx" 29 30 #include <list.hxx> 31 32 #include <vector> 33 #include <numrule.hxx> 34 #include <ndarr.hxx> 35 #include <node.hxx> 36 #include <pam.hxx> 37 #include <SwNodeNum.hxx> 38 39 // ---------------------------------------------------------------------------- 40 // SwListImpl 41 // implementation class for SwList 42 // ---------------------------------------------------------------------------- 43 class SwListImpl 44 { 45 public: 46 SwListImpl( const String sListId, 47 SwNumRule& rDefaultListStyle, 48 const SwNodes& rNodes ); 49 ~SwListImpl(); 50 51 const String GetListId() const; 52 53 const String GetDefaultListStyleName() const; 54 55 void InsertListItem( SwNodeNum& rNodeNum, 56 const int nLevel ); 57 void RemoveListItem( SwNodeNum& rNodeNum ); 58 59 void InvalidateListTree(); 60 void ValidateListTree(); 61 62 void MarkListLevel( const int nListLevel, 63 const sal_Bool bValue ); 64 65 bool IsListLevelMarked( const int nListLevel ) const; 66 67 private: 68 // unique identifier of the list 69 const String msListId; 70 // default list style for the list items, identified by the list style name 71 String msDefaultListStyleName; 72 73 // list trees for certain document ranges 74 typedef std::pair<SwNodeNum*, SwPaM*> tListTreeForRange; 75 typedef std::vector<tListTreeForRange> tListTrees; 76 tListTrees maListTrees; 77 78 int mnMarkedListLevel; 79 80 void NotifyItemsOnListLevel( const int nLevel ); 81 }; 82 83 SwListImpl::SwListImpl( const String sListId, 84 SwNumRule& rDefaultListStyle, 85 const SwNodes& rNodes ) 86 : msListId( sListId ), 87 msDefaultListStyleName( rDefaultListStyle.GetName() ), 88 maListTrees(), 89 mnMarkedListLevel( MAXLEVEL ) 90 { 91 // create empty list trees for the document ranges 92 const SwNode* pNode = rNodes[0]; 93 do 94 { 95 SwPaM aPam( *pNode, *pNode->EndOfSectionNode() ); 96 97 SwNodeNum* pNumberTreeRootNode = new SwNodeNum( &rDefaultListStyle ); 98 SwPaM* pPam = new SwPaM( *(aPam.Start()), *(aPam.End()) ); 99 tListTreeForRange aListTreeForRange( pNumberTreeRootNode, pPam ); 100 maListTrees.push_back( aListTreeForRange ); 101 102 pNode = pNode->EndOfSectionNode(); 103 if (pNode != &rNodes.GetEndOfContent()) 104 { 105 sal_uLong nIndex = pNode->GetIndex(); 106 nIndex++; 107 pNode = rNodes[nIndex]; 108 } 109 } 110 while ( pNode != &rNodes.GetEndOfContent() ); 111 } 112 113 SwListImpl::~SwListImpl() 114 { 115 tListTrees::iterator aNumberTreeIter; 116 for ( aNumberTreeIter = maListTrees.begin(); 117 aNumberTreeIter != maListTrees.end(); 118 ++aNumberTreeIter ) 119 { 120 SwNodeNum::HandleNumberTreeRootNodeDelete( *((*aNumberTreeIter).first) ); 121 delete (*aNumberTreeIter).first; 122 delete (*aNumberTreeIter).second; 123 } 124 } 125 126 const String SwListImpl::GetListId() const 127 { 128 return msListId; 129 } 130 131 const String SwListImpl::GetDefaultListStyleName() const 132 { 133 return msDefaultListStyleName; 134 } 135 136 void SwListImpl::InsertListItem( SwNodeNum& rNodeNum, 137 const int nLevel ) 138 { 139 const SwPosition aPosOfNodeNum( rNodeNum.GetPosition() ); 140 const SwNodes* pNodesOfNodeNum = &(aPosOfNodeNum.nNode.GetNode().GetNodes()); 141 142 tListTrees::const_iterator aNumberTreeIter; 143 for ( aNumberTreeIter = maListTrees.begin(); 144 aNumberTreeIter != maListTrees.end(); 145 ++aNumberTreeIter ) 146 { 147 const SwPosition* pStart = (*aNumberTreeIter).second->Start(); 148 const SwPosition* pEnd = (*aNumberTreeIter).second->End(); 149 const SwNodes* pRangeNodes = &(pStart->nNode.GetNode().GetNodes()); 150 151 if ( pRangeNodes == pNodesOfNodeNum && 152 *pStart <= aPosOfNodeNum && aPosOfNodeNum <= *pEnd) 153 { 154 (*aNumberTreeIter).first->AddChild( &rNodeNum, nLevel ); 155 156 break; 157 } 158 } 159 } 160 161 void SwListImpl::RemoveListItem( SwNodeNum& rNodeNum ) 162 { 163 rNodeNum.RemoveMe(); 164 } 165 166 void SwListImpl::InvalidateListTree() 167 { 168 tListTrees::iterator aNumberTreeIter; 169 for ( aNumberTreeIter = maListTrees.begin(); 170 aNumberTreeIter != maListTrees.end(); 171 ++aNumberTreeIter ) 172 { 173 (*aNumberTreeIter).first->InvalidateTree(); 174 } 175 } 176 177 void SwListImpl::ValidateListTree() 178 { 179 tListTrees::iterator aNumberTreeIter; 180 for ( aNumberTreeIter = maListTrees.begin(); 181 aNumberTreeIter != maListTrees.end(); 182 ++aNumberTreeIter ) 183 { 184 (*aNumberTreeIter).first->NotifyInvalidChildren(); 185 } 186 } 187 188 void SwListImpl::MarkListLevel( const int nListLevel, 189 const sal_Bool bValue ) 190 { 191 if ( bValue ) 192 { 193 if ( nListLevel != mnMarkedListLevel ) 194 { 195 if ( mnMarkedListLevel != MAXLEVEL ) 196 { 197 // notify former marked list nodes 198 NotifyItemsOnListLevel( mnMarkedListLevel ); 199 } 200 201 mnMarkedListLevel = nListLevel; 202 203 // notify new marked list nodes 204 NotifyItemsOnListLevel( mnMarkedListLevel ); 205 } 206 } 207 else 208 { 209 if ( mnMarkedListLevel != MAXLEVEL ) 210 { 211 // notify former marked list nodes 212 NotifyItemsOnListLevel( mnMarkedListLevel ); 213 } 214 215 mnMarkedListLevel = MAXLEVEL; 216 } 217 } 218 219 bool SwListImpl::IsListLevelMarked( const int nListLevel ) const 220 { 221 return nListLevel == mnMarkedListLevel; 222 } 223 224 void SwListImpl::NotifyItemsOnListLevel( const int nLevel ) 225 { 226 tListTrees::iterator aNumberTreeIter; 227 for ( aNumberTreeIter = maListTrees.begin(); 228 aNumberTreeIter != maListTrees.end(); 229 ++aNumberTreeIter ) 230 { 231 (*aNumberTreeIter).first->NotifyNodesOnListLevel( nLevel ); 232 } 233 } 234 235 // ---------------------------------------------------------------------------- 236 // SwList 237 // ---------------------------------------------------------------------------- 238 SwList::SwList( const String sListId, 239 SwNumRule& rDefaultListStyle, 240 const SwNodes& rNodes ) 241 : mpListImpl( new SwListImpl( sListId, rDefaultListStyle, rNodes ) ) 242 { 243 } 244 245 SwList::~SwList() 246 { 247 delete mpListImpl; 248 } 249 250 const String SwList::GetListId() const 251 { 252 return mpListImpl->GetListId(); 253 } 254 255 const String SwList::GetDefaultListStyleName() const 256 { 257 return mpListImpl->GetDefaultListStyleName(); 258 } 259 260 void SwList::InsertListItem( SwNodeNum& rNodeNum, 261 const int nLevel ) 262 { 263 mpListImpl->InsertListItem( rNodeNum, nLevel ); 264 } 265 266 void SwList::RemoveListItem( SwNodeNum& rNodeNum ) 267 { 268 mpListImpl->RemoveListItem( rNodeNum ); 269 } 270 271 void SwList::InvalidateListTree() 272 { 273 mpListImpl->InvalidateListTree(); 274 } 275 276 void SwList::ValidateListTree() 277 { 278 mpListImpl->ValidateListTree(); 279 } 280 281 void SwList::MarkListLevel( const int nListLevel, 282 const sal_Bool bValue ) 283 { 284 mpListImpl->MarkListLevel( nListLevel, bValue ); 285 } 286 287 bool SwList::IsListLevelMarked( const int nListLevel ) const 288 { 289 return mpListImpl->IsListLevelMarked( nListLevel ); 290 } 291 292 //void SwList::ContinueList( SwList& rList ) 293 //{ 294 // mpListImpl->ContinueList( rList ); 295 //} 296 //const SwList* SwList::GetContinuedList() const 297 //{ 298 // return mpListImpl->GetContinuedList(); 299 //} 300 //void SwList::ClearContinuation() 301 //{ 302 // mpListImpl->ClearContinuation(); 303 //} 304