]>
git.saurik.com Git - wxWidgets.git/blob - src/generic/selstore.cpp
   1 /////////////////////////////////////////////////////////////////////////////// 
   2 // Name:        generic/selstore.cpp 
   3 // Purpose:     wxSelectionStore implementation 
   4 // Author:      Vadim Zeitlin 
   6 // Created:     08.06.03 (extracted from src/generic/listctrl.cpp) 
   8 // Copyright:   (c) 2000-2003 Vadim Zeitlin <vadim@wxwindows.org> 
   9 // Licence:     wxWindows licence 
  10 /////////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  20 #include "wx/wxprec.h" 
  26 #include "wx/selstore.h" 
  28 // ============================================================================ 
  30 // ============================================================================ 
  32 // ---------------------------------------------------------------------------- 
  34 // ---------------------------------------------------------------------------- 
  36 bool wxSelectionStore::IsSelected(unsigned item
) const 
  38     bool isSel 
= m_itemsSel
.Index(item
) != wxNOT_FOUND
; 
  40     // if the default state is to be selected, being in m_itemsSel means that 
  41     // the item is not selected, so we have to inverse the logic 
  42     return m_defaultState 
? !isSel 
: isSel
; 
  45 // ---------------------------------------------------------------------------- 
  47 // ---------------------------------------------------------------------------- 
  49 bool wxSelectionStore::SelectItem(unsigned item
, bool select
) 
  51     // search for the item ourselves as like this we get the index where to 
  52     // insert it later if needed, so we do only one search in the array instead 
  53     // of two (adding item to a sorted array requires a search) 
  54     size_t index 
= m_itemsSel
.IndexForInsert(item
); 
  55     bool isSel 
= index 
< m_itemsSel
.GetCount() && m_itemsSel
[index
] == item
; 
  57     if ( select 
!= m_defaultState 
) 
  61             m_itemsSel
.AddAt(item
, index
); 
  66     else // reset to default state 
  70             m_itemsSel
.RemoveAt(index
); 
  78 bool wxSelectionStore::SelectRange(unsigned itemFrom
, unsigned itemTo
, 
  80                                    wxArrayInt 
*itemsChanged
) 
  82     // 100 is hardcoded but it shouldn't matter much: the important thing is 
  83     // that we don't refresh everything when really few (e.g. 1 or 2) items 
  85     static const unsigned MANY_ITEMS 
= 100; 
  87     wxASSERT_MSG( itemFrom 
<= itemTo
, wxT("should be in order") ); 
  89     // are we going to have more [un]selected items than the other ones? 
  90     if ( itemTo 
- itemFrom 
> m_count
/2 ) 
  92         if ( select 
!= m_defaultState 
) 
  94             // the default state now becomes the same as 'select' 
  95             m_defaultState 
= select
; 
  97             // so all the old selections (which had state select) shouldn't be 
  98             // selected any more, but all the other ones should 
  99             wxSelectedIndices selOld 
= m_itemsSel
; 
 102             // TODO: it should be possible to optimize the searches a bit 
 103             //       knowing the possible range 
 106             for ( item 
= 0; item 
< itemFrom
; item
++ ) 
 108                 if ( selOld
.Index(item
) == wxNOT_FOUND 
) 
 109                     m_itemsSel
.Add(item
); 
 112             for ( item 
= itemTo 
+ 1; item 
< m_count
; item
++ ) 
 114                 if ( selOld
.Index(item
) == wxNOT_FOUND 
) 
 115                     m_itemsSel
.Add(item
); 
 118             // many items (> half) changed state 
 121         else // select == m_defaultState 
 123             // get the inclusive range of items between itemFrom and itemTo 
 124             size_t count 
= m_itemsSel
.GetCount(), 
 125                    start 
= m_itemsSel
.IndexForInsert(itemFrom
), 
 126                    end 
= m_itemsSel
.IndexForInsert(itemTo
); 
 128             if ( start 
== count 
|| m_itemsSel
[start
] < itemFrom 
) 
 133             if ( end 
== count 
|| m_itemsSel
[end
] > itemTo 
) 
 140                 // delete all of them (from end to avoid changing indices) 
 141                 for ( int i 
= end
; i 
>= (int)start
; i
-- ) 
 145                         if ( itemsChanged
->GetCount() > MANY_ITEMS 
) 
 147                             // stop counting (see comment below) 
 152                             itemsChanged
->Add(m_itemsSel
[i
]); 
 156                     m_itemsSel
.RemoveAt(i
); 
 161     else // "few" items change state 
 165             itemsChanged
->Empty(); 
 168         // just add the items to the selection 
 169         for ( unsigned item 
= itemFrom
; item 
<= itemTo
; item
++ ) 
 171             if ( SelectItem(item
, select
) && itemsChanged 
) 
 173                 itemsChanged
->Add(item
); 
 175                 if ( itemsChanged
->GetCount() > MANY_ITEMS 
) 
 177                     // stop counting them, we'll just eat gobs of memory 
 178                     // for nothing at all - faster to refresh everything in 
 186     // we set it to NULL if there are many items changing state 
 187     return itemsChanged 
!= NULL
; 
 190 // ---------------------------------------------------------------------------- 
 192 // ---------------------------------------------------------------------------- 
 194 void wxSelectionStore::OnItemDelete(unsigned item
) 
 196     size_t count 
= m_itemsSel
.GetCount(), 
 197            i 
= m_itemsSel
.IndexForInsert(item
); 
 199     if ( i 
< count 
&& m_itemsSel
[i
] == item 
) 
 201         // this item itself was in m_itemsSel, remove it from there 
 202         m_itemsSel
.RemoveAt(i
); 
 207     // and adjust the index of all which follow it 
 210         // all following elements must be greater than the one we deleted 
 211         wxASSERT_MSG( m_itemsSel
[i
] > item
, wxT("logic error") ); 
 217 void wxSelectionStore::SetItemCount(unsigned count
) 
 219     // forget about all items whose indices are now invalid if the size 
 221     if ( count 
< m_count 
) 
 223         for ( size_t i 
= m_itemsSel
.GetCount(); i 
> 0; i
-- ) 
 225             if ( m_itemsSel
[i 
- 1] >= count 
) 
 226                 m_itemsSel
.RemoveAt(i 
- 1); 
 230     // remember the new number of items