1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_tools.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #define _SV_MULTISEL_CXX 32*cdf0e10cSrcweir 33*cdf0e10cSrcweir #ifdef MI_DEBUG 34*cdf0e10cSrcweir #define private public 35*cdf0e10cSrcweir #include <stdio.h> 36*cdf0e10cSrcweir #endif 37*cdf0e10cSrcweir 38*cdf0e10cSrcweir #include <tools/debug.hxx> 39*cdf0e10cSrcweir #include <tools/multisel.hxx> 40*cdf0e10cSrcweir 41*cdf0e10cSrcweir #include "rtl/ustrbuf.hxx" 42*cdf0e10cSrcweir 43*cdf0e10cSrcweir #ifdef MI_DEBUG 44*cdf0e10cSrcweir #define DBG(x) x 45*cdf0e10cSrcweir #else 46*cdf0e10cSrcweir #define DBG(x) 47*cdf0e10cSrcweir #endif 48*cdf0e10cSrcweir 49*cdf0e10cSrcweir using namespace rtl; 50*cdf0e10cSrcweir 51*cdf0e10cSrcweir //================================================================== 52*cdf0e10cSrcweir 53*cdf0e10cSrcweir #ifdef MI_DEBUG 54*cdf0e10cSrcweir 55*cdf0e10cSrcweir static void Print( const MultiSelection* pSel ) 56*cdf0e10cSrcweir { 57*cdf0e10cSrcweir DbgOutf( "TotRange: %4ld-%4ld\n", 58*cdf0e10cSrcweir pSel->aTotRange.Min(), pSel->aTotRange.Max() ); 59*cdf0e10cSrcweir if ( pSel->bCurValid ) 60*cdf0e10cSrcweir { 61*cdf0e10cSrcweir DbgOutf( "CurSubSel: %4ld\n", pSel->nCurSubSel ); 62*cdf0e10cSrcweir DbgOutf( "CurIndex: %4ld\n", pSel->nCurIndex ); 63*cdf0e10cSrcweir } 64*cdf0e10cSrcweir DbgOutf( "SelCount: %4ld\n", pSel->nSelCount ); 65*cdf0e10cSrcweir DbgOutf( "SubCount: %4ld\n", pSel->aSels.Count() ); 66*cdf0e10cSrcweir for ( sal_uIntPtr nPos = 0; nPos < pSel->aSels.Count(); ++nPos ) 67*cdf0e10cSrcweir { 68*cdf0e10cSrcweir DbgOutf( "SubSel #%2ld: %4ld-%4ld\n", nPos, 69*cdf0e10cSrcweir pSel->aSels.GetObject(nPos)->Min(), 70*cdf0e10cSrcweir pSel->aSels.GetObject(nPos)->Max() ); 71*cdf0e10cSrcweir } 72*cdf0e10cSrcweir DbgOutf( "\n" ); 73*cdf0e10cSrcweir fclose( pFile ); 74*cdf0e10cSrcweir } 75*cdf0e10cSrcweir 76*cdf0e10cSrcweir #endif 77*cdf0e10cSrcweir 78*cdf0e10cSrcweir // ----------------------------------------------------------------------- 79*cdf0e10cSrcweir 80*cdf0e10cSrcweir void MultiSelection::ImplClear() 81*cdf0e10cSrcweir { 82*cdf0e10cSrcweir // no selected indexes 83*cdf0e10cSrcweir nSelCount = 0; 84*cdf0e10cSrcweir 85*cdf0e10cSrcweir Range* pRange = aSels.First(); 86*cdf0e10cSrcweir while ( pRange ) 87*cdf0e10cSrcweir { 88*cdf0e10cSrcweir delete pRange; 89*cdf0e10cSrcweir pRange = aSels.Next(); 90*cdf0e10cSrcweir } 91*cdf0e10cSrcweir aSels.Clear(); 92*cdf0e10cSrcweir } 93*cdf0e10cSrcweir 94*cdf0e10cSrcweir // ----------------------------------------------------------------------- 95*cdf0e10cSrcweir 96*cdf0e10cSrcweir sal_uIntPtr MultiSelection::ImplFindSubSelection( long nIndex ) const 97*cdf0e10cSrcweir { 98*cdf0e10cSrcweir // iterate through the sub selections 99*cdf0e10cSrcweir sal_uIntPtr n = 0; 100*cdf0e10cSrcweir for ( ; 101*cdf0e10cSrcweir n < aSels.Count() && nIndex > aSels.GetObject(n)->Max(); 102*cdf0e10cSrcweir ++n ) {} /* empty loop */ 103*cdf0e10cSrcweir return n; 104*cdf0e10cSrcweir } 105*cdf0e10cSrcweir 106*cdf0e10cSrcweir // ----------------------------------------------------------------------- 107*cdf0e10cSrcweir 108*cdf0e10cSrcweir sal_Bool MultiSelection::ImplMergeSubSelections( sal_uIntPtr nPos1, sal_uIntPtr nPos2 ) 109*cdf0e10cSrcweir { 110*cdf0e10cSrcweir // didn't a sub selection at nPos2 exist? 111*cdf0e10cSrcweir if ( nPos2 >= aSels.Count() ) 112*cdf0e10cSrcweir return sal_False; 113*cdf0e10cSrcweir 114*cdf0e10cSrcweir // did the sub selections touch each other? 115*cdf0e10cSrcweir if ( (aSels.GetObject(nPos1)->Max() + 1) == aSels.GetObject(nPos2)->Min() ) 116*cdf0e10cSrcweir { 117*cdf0e10cSrcweir // merge them 118*cdf0e10cSrcweir aSels.GetObject(nPos1)->Max() = aSels.GetObject(nPos2)->Max(); 119*cdf0e10cSrcweir delete aSels.Remove(nPos2); 120*cdf0e10cSrcweir return sal_True; 121*cdf0e10cSrcweir } 122*cdf0e10cSrcweir 123*cdf0e10cSrcweir return sal_False; 124*cdf0e10cSrcweir } 125*cdf0e10cSrcweir 126*cdf0e10cSrcweir // ----------------------------------------------------------------------- 127*cdf0e10cSrcweir 128*cdf0e10cSrcweir MultiSelection::MultiSelection(): 129*cdf0e10cSrcweir aTotRange( 0, -1 ), 130*cdf0e10cSrcweir nCurSubSel(0), 131*cdf0e10cSrcweir nSelCount(0), 132*cdf0e10cSrcweir bCurValid(sal_False), 133*cdf0e10cSrcweir bSelectNew(sal_False) 134*cdf0e10cSrcweir { 135*cdf0e10cSrcweir } 136*cdf0e10cSrcweir 137*cdf0e10cSrcweir // ----------------------------------------------------------------------- 138*cdf0e10cSrcweir 139*cdf0e10cSrcweir MultiSelection::MultiSelection( const UniString& rString, sal_Unicode cRange, sal_Unicode cSep ): 140*cdf0e10cSrcweir aTotRange(0,RANGE_MAX), 141*cdf0e10cSrcweir nCurSubSel(0), 142*cdf0e10cSrcweir nSelCount(0), 143*cdf0e10cSrcweir bCurValid(sal_False), 144*cdf0e10cSrcweir bSelectNew(sal_False) 145*cdf0e10cSrcweir { 146*cdf0e10cSrcweir // Dies ist nur ein Schnellschuss und sollte bald optimiert, 147*cdf0e10cSrcweir // an die verschiedenen Systeme (UNIX etc.) 148*cdf0e10cSrcweir // und die gewuenschte Eingabe-Syntax angepasst werden. 149*cdf0e10cSrcweir 150*cdf0e10cSrcweir UniString aStr( rString ); 151*cdf0e10cSrcweir sal_Unicode* pStr = aStr.GetBufferAccess(); 152*cdf0e10cSrcweir sal_Unicode* pOld = pStr; 153*cdf0e10cSrcweir sal_Bool bReady = sal_False; 154*cdf0e10cSrcweir sal_Bool bUntil = sal_False; 155*cdf0e10cSrcweir xub_StrLen nCut = 0; 156*cdf0e10cSrcweir 157*cdf0e10cSrcweir // Hier normieren wir den String, sodass nur Ziffern, 158*cdf0e10cSrcweir // Semikola als Trenn- und Minus als VonBis-Zeichen 159*cdf0e10cSrcweir // uebrigbleiben, z.B. "99-117;55;34;-17;37-43" 160*cdf0e10cSrcweir while ( *pOld ) 161*cdf0e10cSrcweir { 162*cdf0e10cSrcweir switch( *pOld ) 163*cdf0e10cSrcweir { 164*cdf0e10cSrcweir case '0': 165*cdf0e10cSrcweir case '1': 166*cdf0e10cSrcweir case '2': 167*cdf0e10cSrcweir case '3': 168*cdf0e10cSrcweir case '4': 169*cdf0e10cSrcweir case '5': 170*cdf0e10cSrcweir case '6': 171*cdf0e10cSrcweir case '7': 172*cdf0e10cSrcweir case '8': 173*cdf0e10cSrcweir case '9': 174*cdf0e10cSrcweir DBG_ASSERT( *pOld != cRange, "digit for range char not allowed" ); 175*cdf0e10cSrcweir DBG_ASSERT( *pOld != cSep, "digit for separator not allowed" ); 176*cdf0e10cSrcweir if( bReady ) 177*cdf0e10cSrcweir { 178*cdf0e10cSrcweir *pStr++ = ';'; 179*cdf0e10cSrcweir nCut++; 180*cdf0e10cSrcweir bReady = sal_False; 181*cdf0e10cSrcweir } 182*cdf0e10cSrcweir *pStr++ = *pOld; 183*cdf0e10cSrcweir nCut++; 184*cdf0e10cSrcweir bUntil = sal_False; 185*cdf0e10cSrcweir break; 186*cdf0e10cSrcweir 187*cdf0e10cSrcweir case '-': 188*cdf0e10cSrcweir case ':': 189*cdf0e10cSrcweir case '/': 190*cdf0e10cSrcweir if ( *pOld != cSep ) 191*cdf0e10cSrcweir { 192*cdf0e10cSrcweir if ( !bUntil ) 193*cdf0e10cSrcweir { 194*cdf0e10cSrcweir *pStr++ = '-'; 195*cdf0e10cSrcweir nCut++; 196*cdf0e10cSrcweir bUntil = sal_True; 197*cdf0e10cSrcweir } 198*cdf0e10cSrcweir bReady = sal_False; 199*cdf0e10cSrcweir } 200*cdf0e10cSrcweir else 201*cdf0e10cSrcweir bReady = sal_True; 202*cdf0e10cSrcweir break; 203*cdf0e10cSrcweir 204*cdf0e10cSrcweir case ' ': 205*cdf0e10cSrcweir DBG_ASSERT( *pOld != cRange, "SPACE for range char not allowed" ); 206*cdf0e10cSrcweir DBG_ASSERT( *pOld != cSep, "SPACE for separator not allowed" ); 207*cdf0e10cSrcweir bReady = !bUntil; 208*cdf0e10cSrcweir break; 209*cdf0e10cSrcweir 210*cdf0e10cSrcweir default: 211*cdf0e10cSrcweir if ( *pOld == cRange ) 212*cdf0e10cSrcweir { 213*cdf0e10cSrcweir if ( !bUntil ) 214*cdf0e10cSrcweir { 215*cdf0e10cSrcweir *pStr++ = '-'; 216*cdf0e10cSrcweir nCut++; 217*cdf0e10cSrcweir bUntil = sal_True; 218*cdf0e10cSrcweir } 219*cdf0e10cSrcweir bReady = sal_False; 220*cdf0e10cSrcweir } 221*cdf0e10cSrcweir else 222*cdf0e10cSrcweir bReady = sal_True; 223*cdf0e10cSrcweir break; 224*cdf0e10cSrcweir } 225*cdf0e10cSrcweir 226*cdf0e10cSrcweir pOld++; 227*cdf0e10cSrcweir } 228*cdf0e10cSrcweir aStr.ReleaseBufferAccess( nCut ); 229*cdf0e10cSrcweir 230*cdf0e10cSrcweir // Jetzt wird der normierte String ausgewertet .. 231*cdf0e10cSrcweir UniString aNumStr; 232*cdf0e10cSrcweir Range aRg( 1, RANGE_MAX ); 233*cdf0e10cSrcweir const sal_Unicode* pCStr = aStr.GetBuffer(); 234*cdf0e10cSrcweir long nPage = 1; 235*cdf0e10cSrcweir long nNum = 1; 236*cdf0e10cSrcweir bUntil = sal_False; 237*cdf0e10cSrcweir while ( *pCStr ) 238*cdf0e10cSrcweir { 239*cdf0e10cSrcweir switch ( *pCStr ) 240*cdf0e10cSrcweir { 241*cdf0e10cSrcweir case '0': 242*cdf0e10cSrcweir case '1': 243*cdf0e10cSrcweir case '2': 244*cdf0e10cSrcweir case '3': 245*cdf0e10cSrcweir case '4': 246*cdf0e10cSrcweir case '5': 247*cdf0e10cSrcweir case '6': 248*cdf0e10cSrcweir case '7': 249*cdf0e10cSrcweir case '8': 250*cdf0e10cSrcweir case '9': 251*cdf0e10cSrcweir aNumStr += *pCStr; 252*cdf0e10cSrcweir break; 253*cdf0e10cSrcweir case ';': 254*cdf0e10cSrcweir nNum = aNumStr.ToInt32(); 255*cdf0e10cSrcweir if ( bUntil ) 256*cdf0e10cSrcweir { 257*cdf0e10cSrcweir if ( !aNumStr.Len() ) 258*cdf0e10cSrcweir nNum = RANGE_MAX; 259*cdf0e10cSrcweir aRg.Min() = nPage; 260*cdf0e10cSrcweir aRg.Max() = nNum; 261*cdf0e10cSrcweir aRg.Justify(); 262*cdf0e10cSrcweir Select( aRg ); 263*cdf0e10cSrcweir } 264*cdf0e10cSrcweir else 265*cdf0e10cSrcweir Select( nNum ); 266*cdf0e10cSrcweir nPage = 0; 267*cdf0e10cSrcweir aNumStr.Erase(); 268*cdf0e10cSrcweir bUntil = sal_False; 269*cdf0e10cSrcweir break; 270*cdf0e10cSrcweir 271*cdf0e10cSrcweir case '-': 272*cdf0e10cSrcweir nPage = aNumStr.ToInt32(); 273*cdf0e10cSrcweir aNumStr.Erase(); 274*cdf0e10cSrcweir bUntil = sal_True; 275*cdf0e10cSrcweir break; 276*cdf0e10cSrcweir } 277*cdf0e10cSrcweir 278*cdf0e10cSrcweir pCStr++; 279*cdf0e10cSrcweir } 280*cdf0e10cSrcweir 281*cdf0e10cSrcweir nNum = aNumStr.ToInt32(); 282*cdf0e10cSrcweir if ( bUntil ) 283*cdf0e10cSrcweir { 284*cdf0e10cSrcweir if ( !aNumStr.Len() ) 285*cdf0e10cSrcweir nNum = RANGE_MAX; 286*cdf0e10cSrcweir aRg.Min() = nPage; 287*cdf0e10cSrcweir aRg.Max() = nNum; 288*cdf0e10cSrcweir aRg.Justify(); 289*cdf0e10cSrcweir Select( aRg ); 290*cdf0e10cSrcweir } 291*cdf0e10cSrcweir else 292*cdf0e10cSrcweir Select( nNum ); 293*cdf0e10cSrcweir } 294*cdf0e10cSrcweir 295*cdf0e10cSrcweir // ----------------------------------------------------------------------- 296*cdf0e10cSrcweir 297*cdf0e10cSrcweir MultiSelection::MultiSelection( const MultiSelection& rOrig ) : 298*cdf0e10cSrcweir aTotRange(rOrig.aTotRange), 299*cdf0e10cSrcweir nSelCount(rOrig.nSelCount), 300*cdf0e10cSrcweir bCurValid(rOrig.bCurValid), 301*cdf0e10cSrcweir bSelectNew(sal_False) 302*cdf0e10cSrcweir { 303*cdf0e10cSrcweir if ( bCurValid ) 304*cdf0e10cSrcweir { 305*cdf0e10cSrcweir nCurSubSel = rOrig.nCurSubSel; 306*cdf0e10cSrcweir nCurIndex = rOrig.nCurIndex; 307*cdf0e10cSrcweir } 308*cdf0e10cSrcweir 309*cdf0e10cSrcweir // copy the sub selections 310*cdf0e10cSrcweir for ( sal_uIntPtr n = 0; n < rOrig.aSels.Count(); ++n ) 311*cdf0e10cSrcweir aSels.Insert( new Range( *rOrig.aSels.GetObject(n) ), LIST_APPEND ); 312*cdf0e10cSrcweir } 313*cdf0e10cSrcweir 314*cdf0e10cSrcweir // ----------------------------------------------------------------------- 315*cdf0e10cSrcweir 316*cdf0e10cSrcweir MultiSelection::MultiSelection( const Range& rRange ): 317*cdf0e10cSrcweir aTotRange(rRange), 318*cdf0e10cSrcweir nCurSubSel(0), 319*cdf0e10cSrcweir nSelCount(0), 320*cdf0e10cSrcweir bCurValid(sal_False), 321*cdf0e10cSrcweir bSelectNew(sal_False) 322*cdf0e10cSrcweir { 323*cdf0e10cSrcweir } 324*cdf0e10cSrcweir 325*cdf0e10cSrcweir // ----------------------------------------------------------------------- 326*cdf0e10cSrcweir 327*cdf0e10cSrcweir MultiSelection::~MultiSelection() 328*cdf0e10cSrcweir { 329*cdf0e10cSrcweir Range* pRange = aSels.First(); 330*cdf0e10cSrcweir while ( pRange ) 331*cdf0e10cSrcweir { 332*cdf0e10cSrcweir delete pRange; 333*cdf0e10cSrcweir pRange = aSels.Next(); 334*cdf0e10cSrcweir } 335*cdf0e10cSrcweir } 336*cdf0e10cSrcweir 337*cdf0e10cSrcweir // ----------------------------------------------------------------------- 338*cdf0e10cSrcweir 339*cdf0e10cSrcweir MultiSelection& MultiSelection::operator= ( const MultiSelection& rOrig ) 340*cdf0e10cSrcweir { 341*cdf0e10cSrcweir aTotRange = rOrig.aTotRange; 342*cdf0e10cSrcweir bCurValid = rOrig.bCurValid; 343*cdf0e10cSrcweir if ( bCurValid ) 344*cdf0e10cSrcweir { 345*cdf0e10cSrcweir nCurSubSel = rOrig.nCurSubSel; 346*cdf0e10cSrcweir nCurIndex = rOrig.nCurIndex; 347*cdf0e10cSrcweir } 348*cdf0e10cSrcweir 349*cdf0e10cSrcweir // clear the old and copy the sub selections 350*cdf0e10cSrcweir ImplClear(); 351*cdf0e10cSrcweir for ( sal_uIntPtr n = 0; n < rOrig.aSels.Count(); ++n ) 352*cdf0e10cSrcweir aSels.Insert( new Range( *rOrig.aSels.GetObject(n) ), LIST_APPEND ); 353*cdf0e10cSrcweir nSelCount = rOrig.nSelCount; 354*cdf0e10cSrcweir 355*cdf0e10cSrcweir return *this; 356*cdf0e10cSrcweir } 357*cdf0e10cSrcweir 358*cdf0e10cSrcweir // ----------------------------------------------------------------------- 359*cdf0e10cSrcweir 360*cdf0e10cSrcweir sal_Bool MultiSelection::operator== ( MultiSelection& rWith ) 361*cdf0e10cSrcweir { 362*cdf0e10cSrcweir if ( aTotRange != rWith.aTotRange || nSelCount != rWith.nSelCount || 363*cdf0e10cSrcweir aSels.Count() != rWith.aSels.Count() ) 364*cdf0e10cSrcweir return sal_False; 365*cdf0e10cSrcweir 366*cdf0e10cSrcweir // compare the sub seletions 367*cdf0e10cSrcweir for ( sal_uIntPtr n = 0; n < aSels.Count(); ++n ) 368*cdf0e10cSrcweir if ( *aSels.GetObject(n) != *rWith.aSels.GetObject(n) ) 369*cdf0e10cSrcweir return sal_False; 370*cdf0e10cSrcweir return sal_True; 371*cdf0e10cSrcweir } 372*cdf0e10cSrcweir 373*cdf0e10cSrcweir // ----------------------------------------------------------------------- 374*cdf0e10cSrcweir 375*cdf0e10cSrcweir void MultiSelection::SelectAll( sal_Bool bSelect ) 376*cdf0e10cSrcweir { 377*cdf0e10cSrcweir DBG(DbgOutf( "::SelectAll(%s)\n", bSelect ? "sal_True" : "sal_False" )); 378*cdf0e10cSrcweir 379*cdf0e10cSrcweir ImplClear(); 380*cdf0e10cSrcweir if ( bSelect ) 381*cdf0e10cSrcweir { 382*cdf0e10cSrcweir aSels.Insert( new Range(aTotRange), LIST_APPEND ); 383*cdf0e10cSrcweir nSelCount = aTotRange.Len(); 384*cdf0e10cSrcweir } 385*cdf0e10cSrcweir 386*cdf0e10cSrcweir DBG(Print( this )); 387*cdf0e10cSrcweir } 388*cdf0e10cSrcweir 389*cdf0e10cSrcweir // ----------------------------------------------------------------------- 390*cdf0e10cSrcweir 391*cdf0e10cSrcweir sal_Bool MultiSelection::Select( long nIndex, sal_Bool bSelect ) 392*cdf0e10cSrcweir { 393*cdf0e10cSrcweir DBG_ASSERT( aTotRange.IsInside(nIndex), "selected index out of range" ); 394*cdf0e10cSrcweir 395*cdf0e10cSrcweir // out of range? 396*cdf0e10cSrcweir if ( !aTotRange.IsInside(nIndex) ) 397*cdf0e10cSrcweir return sal_False; 398*cdf0e10cSrcweir 399*cdf0e10cSrcweir // find the virtual target position 400*cdf0e10cSrcweir sal_uIntPtr nSubSelPos = ImplFindSubSelection( nIndex ); 401*cdf0e10cSrcweir 402*cdf0e10cSrcweir if ( bSelect ) 403*cdf0e10cSrcweir { 404*cdf0e10cSrcweir // is it included in the found sub selection? 405*cdf0e10cSrcweir if ( nSubSelPos < aSels.Count() && 406*cdf0e10cSrcweir aSels.GetObject(nSubSelPos)->IsInside( nIndex ) ) 407*cdf0e10cSrcweir // already selected, nothing to do 408*cdf0e10cSrcweir return sal_False; 409*cdf0e10cSrcweir 410*cdf0e10cSrcweir // it will become selected 411*cdf0e10cSrcweir ++nSelCount; 412*cdf0e10cSrcweir 413*cdf0e10cSrcweir // is it at the end of the previous sub selection 414*cdf0e10cSrcweir if ( nSubSelPos > 0 && 415*cdf0e10cSrcweir aSels.GetObject(nSubSelPos-1)->Max() == (nIndex-1) ) 416*cdf0e10cSrcweir { 417*cdf0e10cSrcweir // expand the previous sub selection 418*cdf0e10cSrcweir aSels.GetObject(nSubSelPos-1)->Max() = nIndex; 419*cdf0e10cSrcweir 420*cdf0e10cSrcweir // try to merge the previous sub selection 421*cdf0e10cSrcweir ImplMergeSubSelections( nSubSelPos-1, nSubSelPos ); 422*cdf0e10cSrcweir } 423*cdf0e10cSrcweir // is is at the beginning of the found sub selection 424*cdf0e10cSrcweir else if ( nSubSelPos < aSels.Count() && 425*cdf0e10cSrcweir aSels.GetObject(nSubSelPos)->Min() == (nIndex+1) ) 426*cdf0e10cSrcweir // expand the found sub selection 427*cdf0e10cSrcweir aSels.GetObject(nSubSelPos)->Min() = nIndex; 428*cdf0e10cSrcweir else 429*cdf0e10cSrcweir { 430*cdf0e10cSrcweir // create a new sub selection 431*cdf0e10cSrcweir aSels.Insert( new Range( nIndex, nIndex ), nSubSelPos ); 432*cdf0e10cSrcweir if ( bCurValid && nCurSubSel >= nSubSelPos ) 433*cdf0e10cSrcweir ++nCurSubSel; 434*cdf0e10cSrcweir } 435*cdf0e10cSrcweir } 436*cdf0e10cSrcweir else 437*cdf0e10cSrcweir { 438*cdf0e10cSrcweir // is it excluded from the found sub selection? 439*cdf0e10cSrcweir if ( nSubSelPos >= aSels.Count() || 440*cdf0e10cSrcweir !aSels.GetObject(nSubSelPos)->IsInside( nIndex ) ) 441*cdf0e10cSrcweir { 442*cdf0e10cSrcweir // not selected, nothing to do 443*cdf0e10cSrcweir DBG(Print( this )); 444*cdf0e10cSrcweir return sal_False; 445*cdf0e10cSrcweir } 446*cdf0e10cSrcweir 447*cdf0e10cSrcweir // it will become deselected 448*cdf0e10cSrcweir --nSelCount; 449*cdf0e10cSrcweir 450*cdf0e10cSrcweir // is it the only index in the found sub selection? 451*cdf0e10cSrcweir if ( aSels.GetObject(nSubSelPos)->Len() == 1 ) 452*cdf0e10cSrcweir { 453*cdf0e10cSrcweir // remove the complete sub selection 454*cdf0e10cSrcweir delete aSels.Remove( nSubSelPos ); 455*cdf0e10cSrcweir DBG(Print( this )); 456*cdf0e10cSrcweir return sal_True; 457*cdf0e10cSrcweir } 458*cdf0e10cSrcweir 459*cdf0e10cSrcweir // is it at the beginning of the found sub selection? 460*cdf0e10cSrcweir if ( aSels.GetObject(nSubSelPos)->Min() == nIndex ) 461*cdf0e10cSrcweir ++aSels.GetObject(nSubSelPos)->Min(); 462*cdf0e10cSrcweir // is it at the end of the found sub selection? 463*cdf0e10cSrcweir else if ( aSels.GetObject(nSubSelPos)->Max() == nIndex ) 464*cdf0e10cSrcweir --aSels.GetObject(nSubSelPos)->Max(); 465*cdf0e10cSrcweir // it is in the middle of the found sub selection? 466*cdf0e10cSrcweir else 467*cdf0e10cSrcweir { 468*cdf0e10cSrcweir // split the sub selection 469*cdf0e10cSrcweir aSels.Insert( 470*cdf0e10cSrcweir new Range( aSels.GetObject(nSubSelPos)->Min(), nIndex-1 ), 471*cdf0e10cSrcweir nSubSelPos ); 472*cdf0e10cSrcweir aSels.GetObject(nSubSelPos+1)->Min() = nIndex + 1; 473*cdf0e10cSrcweir } 474*cdf0e10cSrcweir } 475*cdf0e10cSrcweir 476*cdf0e10cSrcweir DBG(Print( this )); 477*cdf0e10cSrcweir 478*cdf0e10cSrcweir return sal_True; 479*cdf0e10cSrcweir } 480*cdf0e10cSrcweir 481*cdf0e10cSrcweir // ----------------------------------------------------------------------- 482*cdf0e10cSrcweir 483*cdf0e10cSrcweir void MultiSelection::Select( const Range& rIndexRange, sal_Bool bSelect ) 484*cdf0e10cSrcweir { 485*cdf0e10cSrcweir Range* pRange; 486*cdf0e10cSrcweir long nOld; 487*cdf0e10cSrcweir 488*cdf0e10cSrcweir sal_uIntPtr nTmpMin = rIndexRange.Min(); 489*cdf0e10cSrcweir sal_uIntPtr nTmpMax = rIndexRange.Max(); 490*cdf0e10cSrcweir sal_uIntPtr nCurMin = FirstSelected(); 491*cdf0e10cSrcweir sal_uIntPtr nCurMax = LastSelected(); 492*cdf0e10cSrcweir DBG_ASSERT(aTotRange.IsInside(nTmpMax), "selected index out of range" ); 493*cdf0e10cSrcweir DBG_ASSERT(aTotRange.IsInside(nTmpMin), "selected index out of range" ); 494*cdf0e10cSrcweir 495*cdf0e10cSrcweir // gesamte Selektion ersetzen ? 496*cdf0e10cSrcweir if( nTmpMin <= nCurMin && nTmpMax >= nCurMax ) 497*cdf0e10cSrcweir { 498*cdf0e10cSrcweir ImplClear(); 499*cdf0e10cSrcweir if ( bSelect ) 500*cdf0e10cSrcweir { 501*cdf0e10cSrcweir aSels.Insert( new Range(rIndexRange), LIST_APPEND ); 502*cdf0e10cSrcweir nSelCount = rIndexRange.Len(); 503*cdf0e10cSrcweir } 504*cdf0e10cSrcweir return; 505*cdf0e10cSrcweir } 506*cdf0e10cSrcweir // links erweitern ? 507*cdf0e10cSrcweir if( nTmpMax < nCurMin ) 508*cdf0e10cSrcweir { 509*cdf0e10cSrcweir if( bSelect ) 510*cdf0e10cSrcweir { 511*cdf0e10cSrcweir // ersten Range erweitern ? 512*cdf0e10cSrcweir if( nCurMin > (nTmpMax+1) ) 513*cdf0e10cSrcweir { 514*cdf0e10cSrcweir pRange = new Range( rIndexRange ); 515*cdf0e10cSrcweir aSels.Insert( pRange, (sal_uIntPtr)0 ); 516*cdf0e10cSrcweir nSelCount += pRange->Len(); 517*cdf0e10cSrcweir } 518*cdf0e10cSrcweir else 519*cdf0e10cSrcweir { 520*cdf0e10cSrcweir pRange = aSels.First(); 521*cdf0e10cSrcweir nOld = pRange->Min(); 522*cdf0e10cSrcweir pRange->Min() = (long)nTmpMin; 523*cdf0e10cSrcweir nSelCount += ( nOld - nTmpMin ); 524*cdf0e10cSrcweir } 525*cdf0e10cSrcweir bCurValid = sal_False; 526*cdf0e10cSrcweir } 527*cdf0e10cSrcweir return; 528*cdf0e10cSrcweir } 529*cdf0e10cSrcweir // rechts erweitern ? 530*cdf0e10cSrcweir else if( nTmpMin > nCurMax ) 531*cdf0e10cSrcweir { 532*cdf0e10cSrcweir if( bSelect ) 533*cdf0e10cSrcweir { 534*cdf0e10cSrcweir // letzten Range erweitern ? 535*cdf0e10cSrcweir if( nTmpMin > (nCurMax+1) ) 536*cdf0e10cSrcweir { 537*cdf0e10cSrcweir pRange = new Range( rIndexRange ); 538*cdf0e10cSrcweir aSels.Insert( pRange, LIST_APPEND ); 539*cdf0e10cSrcweir nSelCount += pRange->Len(); 540*cdf0e10cSrcweir } 541*cdf0e10cSrcweir else 542*cdf0e10cSrcweir { 543*cdf0e10cSrcweir pRange = aSels.Last(); 544*cdf0e10cSrcweir nOld = pRange->Max(); 545*cdf0e10cSrcweir pRange->Max() = (long)nTmpMax; 546*cdf0e10cSrcweir nSelCount += ( nTmpMax - nOld ); 547*cdf0e10cSrcweir } 548*cdf0e10cSrcweir bCurValid = sal_False; 549*cdf0e10cSrcweir } 550*cdf0e10cSrcweir return; 551*cdf0e10cSrcweir } 552*cdf0e10cSrcweir 553*cdf0e10cSrcweir //HACK(Hier muss noch optimiert werden) 554*cdf0e10cSrcweir while( nTmpMin <= nTmpMax ) 555*cdf0e10cSrcweir { 556*cdf0e10cSrcweir Select( nTmpMin, bSelect ); 557*cdf0e10cSrcweir nTmpMin++; 558*cdf0e10cSrcweir } 559*cdf0e10cSrcweir } 560*cdf0e10cSrcweir 561*cdf0e10cSrcweir // ----------------------------------------------------------------------- 562*cdf0e10cSrcweir 563*cdf0e10cSrcweir sal_Bool MultiSelection::IsSelected( long nIndex ) const 564*cdf0e10cSrcweir { 565*cdf0e10cSrcweir // find the virtual target position 566*cdf0e10cSrcweir sal_uIntPtr nSubSelPos = ImplFindSubSelection( nIndex ); 567*cdf0e10cSrcweir 568*cdf0e10cSrcweir return nSubSelPos < aSels.Count() && 569*cdf0e10cSrcweir aSels.GetObject(nSubSelPos)->IsInside(nIndex); 570*cdf0e10cSrcweir } 571*cdf0e10cSrcweir 572*cdf0e10cSrcweir // ----------------------------------------------------------------------- 573*cdf0e10cSrcweir 574*cdf0e10cSrcweir void MultiSelection::Insert( long nIndex, long nCount ) 575*cdf0e10cSrcweir { 576*cdf0e10cSrcweir DBG(DbgOutf( "::Insert(%ld, %ld)\n", nIndex, nCount )); 577*cdf0e10cSrcweir 578*cdf0e10cSrcweir // find the virtual target position 579*cdf0e10cSrcweir sal_uIntPtr nSubSelPos = ImplFindSubSelection( nIndex ); 580*cdf0e10cSrcweir 581*cdf0e10cSrcweir // did we need to shift the sub selections? 582*cdf0e10cSrcweir if ( nSubSelPos < aSels.Count() ) 583*cdf0e10cSrcweir { 584*cdf0e10cSrcweir // did we insert an unselected into an existing sub selection? 585*cdf0e10cSrcweir if ( !bSelectNew && aSels.GetObject(nSubSelPos)->Min() != nIndex && 586*cdf0e10cSrcweir aSels.GetObject(nSubSelPos)->IsInside(nIndex) ) 587*cdf0e10cSrcweir { 588*cdf0e10cSrcweir // split the sub selection 589*cdf0e10cSrcweir aSels.Insert( 590*cdf0e10cSrcweir new Range( aSels.GetObject(nSubSelPos)->Min(), nIndex-1 ), 591*cdf0e10cSrcweir nSubSelPos ); 592*cdf0e10cSrcweir ++nSubSelPos; 593*cdf0e10cSrcweir aSels.GetObject(nSubSelPos)->Min() = nIndex; 594*cdf0e10cSrcweir } 595*cdf0e10cSrcweir 596*cdf0e10cSrcweir // did we append an selected to an existing sub selection? 597*cdf0e10cSrcweir else if ( bSelectNew && nSubSelPos > 0 && 598*cdf0e10cSrcweir aSels.GetObject(nSubSelPos)->Max() == nIndex-1 ) 599*cdf0e10cSrcweir // expand the previous sub selection 600*cdf0e10cSrcweir aSels.GetObject(nSubSelPos-1)->Max() += nCount; 601*cdf0e10cSrcweir 602*cdf0e10cSrcweir // did we insert an selected into an existing sub selection? 603*cdf0e10cSrcweir else if ( bSelectNew && aSels.GetObject(nSubSelPos)->Min() == nIndex ) 604*cdf0e10cSrcweir { 605*cdf0e10cSrcweir // expand the sub selection 606*cdf0e10cSrcweir aSels.GetObject(nSubSelPos)->Max() += nCount; 607*cdf0e10cSrcweir ++nSubSelPos; 608*cdf0e10cSrcweir } 609*cdf0e10cSrcweir 610*cdf0e10cSrcweir // shift the sub selections behind the inserting position 611*cdf0e10cSrcweir for ( sal_uIntPtr nPos = nSubSelPos; nPos < aSels.Count(); ++nPos ) 612*cdf0e10cSrcweir { 613*cdf0e10cSrcweir aSels.GetObject(nPos)->Min() += nCount; 614*cdf0e10cSrcweir aSels.GetObject(nPos)->Max() += nCount; 615*cdf0e10cSrcweir } 616*cdf0e10cSrcweir } 617*cdf0e10cSrcweir 618*cdf0e10cSrcweir bCurValid = sal_False; 619*cdf0e10cSrcweir aTotRange.Max() += nCount; 620*cdf0e10cSrcweir if ( bSelectNew ) 621*cdf0e10cSrcweir nSelCount += nCount; 622*cdf0e10cSrcweir 623*cdf0e10cSrcweir DBG(Print( this )); 624*cdf0e10cSrcweir } 625*cdf0e10cSrcweir 626*cdf0e10cSrcweir // ----------------------------------------------------------------------- 627*cdf0e10cSrcweir 628*cdf0e10cSrcweir void MultiSelection::Remove( long nIndex ) 629*cdf0e10cSrcweir { 630*cdf0e10cSrcweir DBG(DbgOutf( "::Remove(%ld)\n", nIndex )); 631*cdf0e10cSrcweir 632*cdf0e10cSrcweir // find the virtual target position 633*cdf0e10cSrcweir sal_uIntPtr nSubSelPos = ImplFindSubSelection( nIndex ); 634*cdf0e10cSrcweir 635*cdf0e10cSrcweir // did we remove from an existing sub selection? 636*cdf0e10cSrcweir if ( nSubSelPos < aSels.Count() && 637*cdf0e10cSrcweir aSels.GetObject(nSubSelPos)->IsInside(nIndex) ) 638*cdf0e10cSrcweir { 639*cdf0e10cSrcweir // does this sub selection only contain the index to be deleted 640*cdf0e10cSrcweir if ( aSels.GetObject(nSubSelPos)->Len() == 1 ) 641*cdf0e10cSrcweir // completely remove the sub selection 642*cdf0e10cSrcweir aSels.Remove(nSubSelPos); 643*cdf0e10cSrcweir else 644*cdf0e10cSrcweir // shorten this sub selection 645*cdf0e10cSrcweir --( aSels.GetObject(nSubSelPos++)->Max() ); 646*cdf0e10cSrcweir 647*cdf0e10cSrcweir // adjust the selected counter 648*cdf0e10cSrcweir --nSelCount; 649*cdf0e10cSrcweir } 650*cdf0e10cSrcweir 651*cdf0e10cSrcweir // shift the sub selections behind the removed index 652*cdf0e10cSrcweir for ( sal_uIntPtr nPos = nSubSelPos; nPos < aSels.Count(); ++nPos ) 653*cdf0e10cSrcweir { 654*cdf0e10cSrcweir --( aSels.GetObject(nPos)->Min() ); 655*cdf0e10cSrcweir --( aSels.GetObject(nPos)->Max() ); 656*cdf0e10cSrcweir } 657*cdf0e10cSrcweir 658*cdf0e10cSrcweir bCurValid = sal_False; 659*cdf0e10cSrcweir aTotRange.Max() -= 1; 660*cdf0e10cSrcweir 661*cdf0e10cSrcweir DBG(Print( this )); 662*cdf0e10cSrcweir } 663*cdf0e10cSrcweir 664*cdf0e10cSrcweir // ----------------------------------------------------------------------- 665*cdf0e10cSrcweir 666*cdf0e10cSrcweir void MultiSelection::Append( long nCount ) 667*cdf0e10cSrcweir { 668*cdf0e10cSrcweir long nPrevLast = aTotRange.Max(); 669*cdf0e10cSrcweir aTotRange.Max() += nCount; 670*cdf0e10cSrcweir if ( bSelectNew ) 671*cdf0e10cSrcweir { 672*cdf0e10cSrcweir nSelCount += nCount; 673*cdf0e10cSrcweir aSels.Insert( new Range( nPrevLast+1, nPrevLast + nCount ), 674*cdf0e10cSrcweir LIST_APPEND ); 675*cdf0e10cSrcweir if ( aSels.Count() > 1 ) 676*cdf0e10cSrcweir ImplMergeSubSelections( aSels.Count() - 2, aSels.Count() ); 677*cdf0e10cSrcweir } 678*cdf0e10cSrcweir } 679*cdf0e10cSrcweir 680*cdf0e10cSrcweir // ----------------------------------------------------------------------- 681*cdf0e10cSrcweir 682*cdf0e10cSrcweir long MultiSelection::ImplFwdUnselected() 683*cdf0e10cSrcweir { 684*cdf0e10cSrcweir if ( !bCurValid ) 685*cdf0e10cSrcweir return SFX_ENDOFSELECTION; 686*cdf0e10cSrcweir 687*cdf0e10cSrcweir if ( ( nCurSubSel < aSels.Count() ) && 688*cdf0e10cSrcweir ( aSels.GetObject(nCurSubSel)->Min() <= nCurIndex ) ) 689*cdf0e10cSrcweir nCurIndex = aSels.GetObject(nCurSubSel++)->Max() + 1; 690*cdf0e10cSrcweir 691*cdf0e10cSrcweir if ( nCurIndex <= aTotRange.Max() ) 692*cdf0e10cSrcweir return nCurIndex; 693*cdf0e10cSrcweir else 694*cdf0e10cSrcweir return SFX_ENDOFSELECTION; 695*cdf0e10cSrcweir } 696*cdf0e10cSrcweir 697*cdf0e10cSrcweir // ----------------------------------------------------------------------- 698*cdf0e10cSrcweir 699*cdf0e10cSrcweir long MultiSelection::ImplBwdUnselected() 700*cdf0e10cSrcweir { 701*cdf0e10cSrcweir if ( !bCurValid ) 702*cdf0e10cSrcweir return SFX_ENDOFSELECTION; 703*cdf0e10cSrcweir 704*cdf0e10cSrcweir if ( aSels.GetObject(nCurSubSel)->Max() < nCurIndex ) 705*cdf0e10cSrcweir return nCurIndex; 706*cdf0e10cSrcweir 707*cdf0e10cSrcweir nCurIndex = aSels.GetObject(nCurSubSel--)->Min() - 1; 708*cdf0e10cSrcweir if ( nCurIndex >= 0 ) 709*cdf0e10cSrcweir return nCurIndex; 710*cdf0e10cSrcweir else 711*cdf0e10cSrcweir return SFX_ENDOFSELECTION; 712*cdf0e10cSrcweir } 713*cdf0e10cSrcweir 714*cdf0e10cSrcweir // ----------------------------------------------------------------------- 715*cdf0e10cSrcweir 716*cdf0e10cSrcweir long MultiSelection::FirstSelected( sal_Bool bInverse ) 717*cdf0e10cSrcweir { 718*cdf0e10cSrcweir bInverseCur = bInverse; 719*cdf0e10cSrcweir nCurSubSel = 0; 720*cdf0e10cSrcweir 721*cdf0e10cSrcweir if ( bInverseCur ) 722*cdf0e10cSrcweir { 723*cdf0e10cSrcweir bCurValid = nSelCount < sal_uIntPtr(aTotRange.Len()); 724*cdf0e10cSrcweir if ( bCurValid ) 725*cdf0e10cSrcweir { 726*cdf0e10cSrcweir nCurIndex = 0; 727*cdf0e10cSrcweir return ImplFwdUnselected(); 728*cdf0e10cSrcweir } 729*cdf0e10cSrcweir } 730*cdf0e10cSrcweir else 731*cdf0e10cSrcweir { 732*cdf0e10cSrcweir bCurValid = aSels.Count() > 0; 733*cdf0e10cSrcweir if ( bCurValid ) 734*cdf0e10cSrcweir return nCurIndex = aSels.GetObject(0)->Min(); 735*cdf0e10cSrcweir } 736*cdf0e10cSrcweir 737*cdf0e10cSrcweir return SFX_ENDOFSELECTION; 738*cdf0e10cSrcweir } 739*cdf0e10cSrcweir 740*cdf0e10cSrcweir // ----------------------------------------------------------------------- 741*cdf0e10cSrcweir 742*cdf0e10cSrcweir long MultiSelection::LastSelected() 743*cdf0e10cSrcweir { 744*cdf0e10cSrcweir nCurSubSel = aSels.Count() - 1; 745*cdf0e10cSrcweir bCurValid = aSels.Count() > 0; 746*cdf0e10cSrcweir 747*cdf0e10cSrcweir if ( bCurValid ) 748*cdf0e10cSrcweir return nCurIndex = aSels.GetObject(nCurSubSel)->Max(); 749*cdf0e10cSrcweir 750*cdf0e10cSrcweir return SFX_ENDOFSELECTION; 751*cdf0e10cSrcweir } 752*cdf0e10cSrcweir 753*cdf0e10cSrcweir // ----------------------------------------------------------------------- 754*cdf0e10cSrcweir 755*cdf0e10cSrcweir long MultiSelection::NextSelected() 756*cdf0e10cSrcweir { 757*cdf0e10cSrcweir if ( !bCurValid ) 758*cdf0e10cSrcweir return SFX_ENDOFSELECTION; 759*cdf0e10cSrcweir 760*cdf0e10cSrcweir if ( bInverseCur ) 761*cdf0e10cSrcweir { 762*cdf0e10cSrcweir ++nCurIndex; 763*cdf0e10cSrcweir return ImplFwdUnselected(); 764*cdf0e10cSrcweir } 765*cdf0e10cSrcweir else 766*cdf0e10cSrcweir { 767*cdf0e10cSrcweir // is the next index in the current sub selection too? 768*cdf0e10cSrcweir if ( nCurIndex < aSels.GetObject(nCurSubSel)->Max() ) 769*cdf0e10cSrcweir return ++nCurIndex; 770*cdf0e10cSrcweir 771*cdf0e10cSrcweir // are there further sub selections? 772*cdf0e10cSrcweir if ( ++nCurSubSel < aSels.Count() ) 773*cdf0e10cSrcweir return nCurIndex = aSels.GetObject(nCurSubSel)->Min(); 774*cdf0e10cSrcweir 775*cdf0e10cSrcweir // we are at the end! 776*cdf0e10cSrcweir return SFX_ENDOFSELECTION; 777*cdf0e10cSrcweir } 778*cdf0e10cSrcweir } 779*cdf0e10cSrcweir 780*cdf0e10cSrcweir // ----------------------------------------------------------------------- 781*cdf0e10cSrcweir 782*cdf0e10cSrcweir long MultiSelection::PrevSelected() 783*cdf0e10cSrcweir { 784*cdf0e10cSrcweir if ( !bCurValid ) 785*cdf0e10cSrcweir return SFX_ENDOFSELECTION; 786*cdf0e10cSrcweir 787*cdf0e10cSrcweir if ( bInverseCur ) 788*cdf0e10cSrcweir { 789*cdf0e10cSrcweir --nCurIndex; 790*cdf0e10cSrcweir return ImplBwdUnselected(); 791*cdf0e10cSrcweir } 792*cdf0e10cSrcweir else 793*cdf0e10cSrcweir { 794*cdf0e10cSrcweir // is the previous index in the current sub selection too? 795*cdf0e10cSrcweir if ( nCurIndex > aSels.GetObject(nCurSubSel)->Min() ) 796*cdf0e10cSrcweir return --nCurIndex; 797*cdf0e10cSrcweir 798*cdf0e10cSrcweir // are there previous sub selections? 799*cdf0e10cSrcweir if ( nCurSubSel > 0 ) 800*cdf0e10cSrcweir { 801*cdf0e10cSrcweir --nCurSubSel; 802*cdf0e10cSrcweir return nCurIndex = aSels.GetObject(nCurSubSel)->Max(); 803*cdf0e10cSrcweir } 804*cdf0e10cSrcweir 805*cdf0e10cSrcweir // we are at the beginning! 806*cdf0e10cSrcweir return SFX_ENDOFSELECTION; 807*cdf0e10cSrcweir } 808*cdf0e10cSrcweir } 809*cdf0e10cSrcweir 810*cdf0e10cSrcweir // ----------------------------------------------------------------------- 811*cdf0e10cSrcweir 812*cdf0e10cSrcweir void MultiSelection::SetTotalRange( const Range& rTotRange ) 813*cdf0e10cSrcweir { 814*cdf0e10cSrcweir aTotRange = rTotRange; 815*cdf0e10cSrcweir 816*cdf0e10cSrcweir // die untere Bereichsgrenze anpassen 817*cdf0e10cSrcweir Range* pRange = aSels.GetObject( 0 ); 818*cdf0e10cSrcweir while( pRange ) 819*cdf0e10cSrcweir { 820*cdf0e10cSrcweir if( pRange->Max() < aTotRange.Min() ) 821*cdf0e10cSrcweir { 822*cdf0e10cSrcweir delete pRange; 823*cdf0e10cSrcweir aSels.Remove( (sal_uIntPtr)0 ); 824*cdf0e10cSrcweir } 825*cdf0e10cSrcweir else if( pRange->Min() < aTotRange.Min() ) 826*cdf0e10cSrcweir { 827*cdf0e10cSrcweir pRange->Min() = aTotRange.Min(); 828*cdf0e10cSrcweir break; 829*cdf0e10cSrcweir } 830*cdf0e10cSrcweir else 831*cdf0e10cSrcweir break; 832*cdf0e10cSrcweir 833*cdf0e10cSrcweir pRange = aSels.GetObject( 0 ); 834*cdf0e10cSrcweir } 835*cdf0e10cSrcweir 836*cdf0e10cSrcweir // die obere Bereichsgrenze anpassen 837*cdf0e10cSrcweir sal_uIntPtr nCount = aSels.Count(); 838*cdf0e10cSrcweir while( nCount ) 839*cdf0e10cSrcweir { 840*cdf0e10cSrcweir pRange = aSels.GetObject( nCount - 1 ); 841*cdf0e10cSrcweir if( pRange->Min() > aTotRange.Max() ) 842*cdf0e10cSrcweir { 843*cdf0e10cSrcweir delete pRange; 844*cdf0e10cSrcweir aSels.Remove( (sal_uIntPtr)(nCount - 1) ); 845*cdf0e10cSrcweir } 846*cdf0e10cSrcweir else if( pRange->Max() > aTotRange.Max() ) 847*cdf0e10cSrcweir { 848*cdf0e10cSrcweir pRange->Max() = aTotRange.Max(); 849*cdf0e10cSrcweir break; 850*cdf0e10cSrcweir } 851*cdf0e10cSrcweir else 852*cdf0e10cSrcweir break; 853*cdf0e10cSrcweir 854*cdf0e10cSrcweir nCount = aSels.Count(); 855*cdf0e10cSrcweir } 856*cdf0e10cSrcweir 857*cdf0e10cSrcweir // Selection-Count neu berechnen 858*cdf0e10cSrcweir nSelCount = 0; 859*cdf0e10cSrcweir pRange = aSels.First(); 860*cdf0e10cSrcweir while( pRange ) 861*cdf0e10cSrcweir { 862*cdf0e10cSrcweir nSelCount += pRange->Len(); 863*cdf0e10cSrcweir pRange = aSels.Next(); 864*cdf0e10cSrcweir } 865*cdf0e10cSrcweir 866*cdf0e10cSrcweir bCurValid = sal_False; 867*cdf0e10cSrcweir nCurIndex = 0; 868*cdf0e10cSrcweir } 869*cdf0e10cSrcweir 870*cdf0e10cSrcweir // ----------------------------------------------------------------------- 871*cdf0e10cSrcweir // 872*cdf0e10cSrcweir // StringRangeEnumerator 873*cdf0e10cSrcweir // 874*cdf0e10cSrcweir // ----------------------------------------------------------------------- 875*cdf0e10cSrcweir StringRangeEnumerator::StringRangeEnumerator( const rtl::OUString& i_rInput, 876*cdf0e10cSrcweir sal_Int32 i_nMinNumber, 877*cdf0e10cSrcweir sal_Int32 i_nMaxNumber, 878*cdf0e10cSrcweir sal_Int32 i_nLogicalOffset 879*cdf0e10cSrcweir ) 880*cdf0e10cSrcweir : mnCount( 0 ) 881*cdf0e10cSrcweir , mnMin( i_nMinNumber ) 882*cdf0e10cSrcweir , mnMax( i_nMaxNumber ) 883*cdf0e10cSrcweir , mnOffset( i_nLogicalOffset ) 884*cdf0e10cSrcweir { 885*cdf0e10cSrcweir setRange( i_rInput ); 886*cdf0e10cSrcweir } 887*cdf0e10cSrcweir 888*cdf0e10cSrcweir bool StringRangeEnumerator::checkValue( sal_Int32 i_nValue, const std::set< sal_Int32 >* i_pPossibleValues ) const 889*cdf0e10cSrcweir { 890*cdf0e10cSrcweir if( mnMin >= 0 && i_nValue < mnMin ) 891*cdf0e10cSrcweir return false; 892*cdf0e10cSrcweir if( mnMax >= 0 && i_nValue > mnMax ) 893*cdf0e10cSrcweir return false; 894*cdf0e10cSrcweir if( i_nValue < 0 ) 895*cdf0e10cSrcweir return false; 896*cdf0e10cSrcweir if( i_pPossibleValues && i_pPossibleValues->find( i_nValue ) == i_pPossibleValues->end() ) 897*cdf0e10cSrcweir return false; 898*cdf0e10cSrcweir return true; 899*cdf0e10cSrcweir } 900*cdf0e10cSrcweir 901*cdf0e10cSrcweir bool StringRangeEnumerator::insertRange( sal_Int32 i_nFirst, sal_Int32 i_nLast, bool bSequence, bool bMayAdjust ) 902*cdf0e10cSrcweir { 903*cdf0e10cSrcweir bool bSuccess = true; 904*cdf0e10cSrcweir if( bSequence ) 905*cdf0e10cSrcweir { 906*cdf0e10cSrcweir if( i_nFirst == -1 ) 907*cdf0e10cSrcweir i_nFirst = mnMin; 908*cdf0e10cSrcweir if( i_nLast == -1 ) 909*cdf0e10cSrcweir i_nLast = mnMax; 910*cdf0e10cSrcweir if( bMayAdjust ) 911*cdf0e10cSrcweir { 912*cdf0e10cSrcweir if( i_nFirst < mnMin ) 913*cdf0e10cSrcweir i_nFirst = mnMin; 914*cdf0e10cSrcweir if( i_nFirst > mnMax ) 915*cdf0e10cSrcweir i_nFirst = mnMax; 916*cdf0e10cSrcweir if( i_nLast < mnMin ) 917*cdf0e10cSrcweir i_nLast = mnMin; 918*cdf0e10cSrcweir if( i_nLast > mnMax ) 919*cdf0e10cSrcweir i_nLast = mnMax; 920*cdf0e10cSrcweir } 921*cdf0e10cSrcweir if( checkValue( i_nFirst ) && checkValue( i_nLast ) ) 922*cdf0e10cSrcweir { 923*cdf0e10cSrcweir maSequence.push_back( Range( i_nFirst, i_nLast ) ); 924*cdf0e10cSrcweir sal_Int32 nNumber = i_nLast - i_nFirst; 925*cdf0e10cSrcweir nNumber = nNumber < 0 ? -nNumber : nNumber; 926*cdf0e10cSrcweir mnCount += nNumber + 1; 927*cdf0e10cSrcweir } 928*cdf0e10cSrcweir else 929*cdf0e10cSrcweir bSuccess = false; 930*cdf0e10cSrcweir } 931*cdf0e10cSrcweir else 932*cdf0e10cSrcweir { 933*cdf0e10cSrcweir if( i_nFirst >= 0 ) 934*cdf0e10cSrcweir { 935*cdf0e10cSrcweir if( checkValue( i_nFirst ) ) 936*cdf0e10cSrcweir { 937*cdf0e10cSrcweir maSequence.push_back( Range( i_nFirst, i_nFirst ) ); 938*cdf0e10cSrcweir mnCount++; 939*cdf0e10cSrcweir } 940*cdf0e10cSrcweir else 941*cdf0e10cSrcweir bSuccess = false; 942*cdf0e10cSrcweir } 943*cdf0e10cSrcweir if( i_nLast >= 0 ) 944*cdf0e10cSrcweir { 945*cdf0e10cSrcweir if( checkValue( i_nLast ) ) 946*cdf0e10cSrcweir { 947*cdf0e10cSrcweir maSequence.push_back( Range( i_nLast, i_nLast ) ); 948*cdf0e10cSrcweir mnCount++; 949*cdf0e10cSrcweir } 950*cdf0e10cSrcweir else 951*cdf0e10cSrcweir bSuccess = false; 952*cdf0e10cSrcweir } 953*cdf0e10cSrcweir } 954*cdf0e10cSrcweir 955*cdf0e10cSrcweir return bSuccess; 956*cdf0e10cSrcweir } 957*cdf0e10cSrcweir 958*cdf0e10cSrcweir bool StringRangeEnumerator::setRange( const rtl::OUString& i_rNewRange, bool i_bStrict ) 959*cdf0e10cSrcweir { 960*cdf0e10cSrcweir mnCount = 0; 961*cdf0e10cSrcweir maSequence.clear(); 962*cdf0e10cSrcweir 963*cdf0e10cSrcweir // we love special cases 964*cdf0e10cSrcweir if( i_rNewRange.getLength() == 0 ) 965*cdf0e10cSrcweir { 966*cdf0e10cSrcweir if( mnMin >= 0 && mnMax >= 0 ) 967*cdf0e10cSrcweir { 968*cdf0e10cSrcweir insertRange( mnMin, mnMax, mnMin != mnMax, ! i_bStrict ); 969*cdf0e10cSrcweir } 970*cdf0e10cSrcweir return true; 971*cdf0e10cSrcweir } 972*cdf0e10cSrcweir 973*cdf0e10cSrcweir const sal_Unicode* pInput = i_rNewRange.getStr(); 974*cdf0e10cSrcweir rtl::OUStringBuffer aNumberBuf( 16 ); 975*cdf0e10cSrcweir sal_Int32 nLastNumber = -1, nNumber = -1; 976*cdf0e10cSrcweir bool bSequence = false; 977*cdf0e10cSrcweir bool bSuccess = true; 978*cdf0e10cSrcweir while( *pInput ) 979*cdf0e10cSrcweir { 980*cdf0e10cSrcweir while( *pInput >= sal_Unicode('0') && *pInput <= sal_Unicode('9') ) 981*cdf0e10cSrcweir aNumberBuf.append( *pInput++ ); 982*cdf0e10cSrcweir if( aNumberBuf.getLength() ) 983*cdf0e10cSrcweir { 984*cdf0e10cSrcweir if( nNumber != -1 ) 985*cdf0e10cSrcweir { 986*cdf0e10cSrcweir if( bSequence ) 987*cdf0e10cSrcweir { 988*cdf0e10cSrcweir if( ! insertRange( nLastNumber, nNumber, true, ! i_bStrict ) && i_bStrict ) 989*cdf0e10cSrcweir { 990*cdf0e10cSrcweir bSuccess = false; 991*cdf0e10cSrcweir break; 992*cdf0e10cSrcweir } 993*cdf0e10cSrcweir nLastNumber = -1; 994*cdf0e10cSrcweir } 995*cdf0e10cSrcweir else 996*cdf0e10cSrcweir { 997*cdf0e10cSrcweir if( ! insertRange( nNumber, nNumber, false, ! i_bStrict ) && i_bStrict ) 998*cdf0e10cSrcweir { 999*cdf0e10cSrcweir bSuccess = false; 1000*cdf0e10cSrcweir break; 1001*cdf0e10cSrcweir } 1002*cdf0e10cSrcweir } 1003*cdf0e10cSrcweir } 1004*cdf0e10cSrcweir nNumber = aNumberBuf.makeStringAndClear().toInt32(); 1005*cdf0e10cSrcweir nNumber += mnOffset; 1006*cdf0e10cSrcweir } 1007*cdf0e10cSrcweir bool bInsertRange = false; 1008*cdf0e10cSrcweir if( *pInput == sal_Unicode('-') ) 1009*cdf0e10cSrcweir { 1010*cdf0e10cSrcweir nLastNumber = nNumber; 1011*cdf0e10cSrcweir nNumber = -1; 1012*cdf0e10cSrcweir bSequence = true; 1013*cdf0e10cSrcweir } 1014*cdf0e10cSrcweir else if( *pInput == ' ' ) 1015*cdf0e10cSrcweir { 1016*cdf0e10cSrcweir } 1017*cdf0e10cSrcweir else if( *pInput == sal_Unicode(',') || *pInput == sal_Unicode(';') ) 1018*cdf0e10cSrcweir bInsertRange = true; 1019*cdf0e10cSrcweir else if( *pInput ) 1020*cdf0e10cSrcweir { 1021*cdf0e10cSrcweir 1022*cdf0e10cSrcweir bSuccess = false; 1023*cdf0e10cSrcweir break; // parse error 1024*cdf0e10cSrcweir } 1025*cdf0e10cSrcweir 1026*cdf0e10cSrcweir if( bInsertRange ) 1027*cdf0e10cSrcweir { 1028*cdf0e10cSrcweir if( ! insertRange( nLastNumber, nNumber, bSequence, ! i_bStrict ) && i_bStrict ) 1029*cdf0e10cSrcweir { 1030*cdf0e10cSrcweir bSuccess = false; 1031*cdf0e10cSrcweir break; 1032*cdf0e10cSrcweir } 1033*cdf0e10cSrcweir nNumber = nLastNumber = -1; 1034*cdf0e10cSrcweir bSequence = false; 1035*cdf0e10cSrcweir } 1036*cdf0e10cSrcweir if( *pInput ) 1037*cdf0e10cSrcweir pInput++; 1038*cdf0e10cSrcweir } 1039*cdf0e10cSrcweir // insert last entries 1040*cdf0e10cSrcweir insertRange( nLastNumber, nNumber, bSequence, ! i_bStrict ); 1041*cdf0e10cSrcweir 1042*cdf0e10cSrcweir return bSuccess; 1043*cdf0e10cSrcweir } 1044*cdf0e10cSrcweir 1045*cdf0e10cSrcweir bool StringRangeEnumerator::hasValue( sal_Int32 i_nValue, const std::set< sal_Int32 >* i_pPossibleValues ) const 1046*cdf0e10cSrcweir { 1047*cdf0e10cSrcweir if( i_pPossibleValues && i_pPossibleValues->find( i_nValue ) == i_pPossibleValues->end() ) 1048*cdf0e10cSrcweir return false; 1049*cdf0e10cSrcweir size_t n = maSequence.size(); 1050*cdf0e10cSrcweir for( size_t i= 0; i < n; ++i ) 1051*cdf0e10cSrcweir { 1052*cdf0e10cSrcweir const StringRangeEnumerator::Range rRange( maSequence[i] ); 1053*cdf0e10cSrcweir if( rRange.nFirst < rRange.nLast ) 1054*cdf0e10cSrcweir { 1055*cdf0e10cSrcweir if( i_nValue >= rRange.nFirst && i_nValue <= rRange.nLast ) 1056*cdf0e10cSrcweir return true; 1057*cdf0e10cSrcweir } 1058*cdf0e10cSrcweir else 1059*cdf0e10cSrcweir { 1060*cdf0e10cSrcweir if( i_nValue >= rRange.nLast && i_nValue <= rRange.nFirst ) 1061*cdf0e10cSrcweir return true; 1062*cdf0e10cSrcweir } 1063*cdf0e10cSrcweir } 1064*cdf0e10cSrcweir return false; 1065*cdf0e10cSrcweir } 1066*cdf0e10cSrcweir 1067*cdf0e10cSrcweir StringRangeEnumerator::Iterator& StringRangeEnumerator::Iterator::operator++() 1068*cdf0e10cSrcweir { 1069*cdf0e10cSrcweir if( nRangeIndex >= 0 && nCurrent >= 0 && pEnumerator ) 1070*cdf0e10cSrcweir { 1071*cdf0e10cSrcweir const StringRangeEnumerator::Range& rRange( pEnumerator->maSequence[nRangeIndex] ); 1072*cdf0e10cSrcweir bool bRangeChange = false; 1073*cdf0e10cSrcweir if( rRange.nLast < rRange.nFirst ) 1074*cdf0e10cSrcweir { 1075*cdf0e10cSrcweir // backward range 1076*cdf0e10cSrcweir if( nCurrent > rRange.nLast ) 1077*cdf0e10cSrcweir nCurrent--; 1078*cdf0e10cSrcweir else 1079*cdf0e10cSrcweir bRangeChange = true; 1080*cdf0e10cSrcweir } 1081*cdf0e10cSrcweir else 1082*cdf0e10cSrcweir { 1083*cdf0e10cSrcweir // forward range 1084*cdf0e10cSrcweir if( nCurrent < rRange.nLast ) 1085*cdf0e10cSrcweir nCurrent++; 1086*cdf0e10cSrcweir else 1087*cdf0e10cSrcweir bRangeChange = true; 1088*cdf0e10cSrcweir } 1089*cdf0e10cSrcweir if( bRangeChange ) 1090*cdf0e10cSrcweir { 1091*cdf0e10cSrcweir nRangeIndex++; 1092*cdf0e10cSrcweir if( size_t(nRangeIndex) == pEnumerator->maSequence.size() ) 1093*cdf0e10cSrcweir { 1094*cdf0e10cSrcweir // reached the end 1095*cdf0e10cSrcweir nRangeIndex = nCurrent = -1; 1096*cdf0e10cSrcweir } 1097*cdf0e10cSrcweir else 1098*cdf0e10cSrcweir nCurrent = pEnumerator->maSequence[nRangeIndex].nFirst; 1099*cdf0e10cSrcweir } 1100*cdf0e10cSrcweir if( nRangeIndex != -1 && nCurrent != -1 ) 1101*cdf0e10cSrcweir { 1102*cdf0e10cSrcweir if( ! pEnumerator->checkValue( nCurrent, pPossibleValues ) ) 1103*cdf0e10cSrcweir return ++(*this); 1104*cdf0e10cSrcweir } 1105*cdf0e10cSrcweir } 1106*cdf0e10cSrcweir return *this; 1107*cdf0e10cSrcweir } 1108*cdf0e10cSrcweir 1109*cdf0e10cSrcweir sal_Int32 StringRangeEnumerator::Iterator::operator*() const 1110*cdf0e10cSrcweir { 1111*cdf0e10cSrcweir return nCurrent; 1112*cdf0e10cSrcweir } 1113*cdf0e10cSrcweir 1114*cdf0e10cSrcweir bool StringRangeEnumerator::Iterator::operator==( const Iterator& i_rCompare ) const 1115*cdf0e10cSrcweir { 1116*cdf0e10cSrcweir return i_rCompare.pEnumerator == pEnumerator && i_rCompare.nRangeIndex == nRangeIndex && i_rCompare.nCurrent == nCurrent; 1117*cdf0e10cSrcweir } 1118*cdf0e10cSrcweir 1119*cdf0e10cSrcweir StringRangeEnumerator::Iterator StringRangeEnumerator::begin( const std::set< sal_Int32 >* i_pPossibleValues ) const 1120*cdf0e10cSrcweir { 1121*cdf0e10cSrcweir StringRangeEnumerator::Iterator it( this, 1122*cdf0e10cSrcweir i_pPossibleValues, 1123*cdf0e10cSrcweir maSequence.empty() ? -1 : 0, 1124*cdf0e10cSrcweir maSequence.empty() ? -1 : maSequence[0].nFirst ); 1125*cdf0e10cSrcweir if( ! checkValue(*it, i_pPossibleValues ) ) 1126*cdf0e10cSrcweir ++it; 1127*cdf0e10cSrcweir return it; 1128*cdf0e10cSrcweir } 1129*cdf0e10cSrcweir 1130*cdf0e10cSrcweir StringRangeEnumerator::Iterator StringRangeEnumerator::end( const std::set< sal_Int32 >* i_pPossibleValues ) const 1131*cdf0e10cSrcweir { 1132*cdf0e10cSrcweir return StringRangeEnumerator::Iterator( this, i_pPossibleValues, -1, -1 ); 1133*cdf0e10cSrcweir } 1134*cdf0e10cSrcweir 1135*cdf0e10cSrcweir bool StringRangeEnumerator::getRangesFromString( const OUString& i_rPageRange, 1136*cdf0e10cSrcweir std::vector< sal_Int32 >& o_rPageVector, 1137*cdf0e10cSrcweir sal_Int32 i_nMinNumber, 1138*cdf0e10cSrcweir sal_Int32 i_nMaxNumber, 1139*cdf0e10cSrcweir sal_Int32 i_nLogicalOffset, 1140*cdf0e10cSrcweir std::set< sal_Int32 >* i_pPossibleValues 1141*cdf0e10cSrcweir ) 1142*cdf0e10cSrcweir { 1143*cdf0e10cSrcweir StringRangeEnumerator aEnum; 1144*cdf0e10cSrcweir aEnum.setMin( i_nMinNumber ); 1145*cdf0e10cSrcweir aEnum.setMax( i_nMaxNumber ); 1146*cdf0e10cSrcweir aEnum.setLogicalOffset( i_nLogicalOffset ); 1147*cdf0e10cSrcweir 1148*cdf0e10cSrcweir bool bRes = aEnum.setRange( i_rPageRange ); 1149*cdf0e10cSrcweir if( bRes ) 1150*cdf0e10cSrcweir { 1151*cdf0e10cSrcweir o_rPageVector.clear(); 1152*cdf0e10cSrcweir o_rPageVector.reserve( aEnum.size() ); 1153*cdf0e10cSrcweir for( StringRangeEnumerator::Iterator it = aEnum.begin( i_pPossibleValues ); 1154*cdf0e10cSrcweir it != aEnum.end( i_pPossibleValues ); ++it ) 1155*cdf0e10cSrcweir { 1156*cdf0e10cSrcweir o_rPageVector.push_back( *it ); 1157*cdf0e10cSrcweir } 1158*cdf0e10cSrcweir } 1159*cdf0e10cSrcweir 1160*cdf0e10cSrcweir return bRes; 1161*cdf0e10cSrcweir } 1162*cdf0e10cSrcweir 1163