This keyword is not expanded by Git which means it's not replaced with the correct revision value in the releases made using git-based scripts and it's confusing to have lines with unexpanded "$Id$" in the released files. As expanding them with Git is not that simple (it could be done with git archive and export-subst attribute) and there are not many benefits in having them in the first place, just remove all these lines. If nothing else, this will make an eventual transition to Git simpler. Closes #14487. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74602 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
232 lines
7.2 KiB
C++
232 lines
7.2 KiB
C++
///////////////////////////////////////////////////////////////////////////////
|
|
// Name: src/generic/selstore.cpp
|
|
// Purpose: wxSelectionStore implementation
|
|
// Author: Vadim Zeitlin
|
|
// Modified by:
|
|
// Created: 08.06.03 (extracted from src/generic/listctrl.cpp)
|
|
// Copyright: (c) 2000-2003 Vadim Zeitlin <vadim@wxwindows.org>
|
|
// Licence: wxWindows licence
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// ============================================================================
|
|
// declarations
|
|
// ============================================================================
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// headers
|
|
// ----------------------------------------------------------------------------
|
|
|
|
#include "wx/wxprec.h"
|
|
|
|
#ifdef __BORLANDC__
|
|
#pragma hdrstop
|
|
#endif
|
|
|
|
#include "wx/selstore.h"
|
|
|
|
// ============================================================================
|
|
// wxSelectionStore
|
|
// ============================================================================
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// tests
|
|
// ----------------------------------------------------------------------------
|
|
|
|
bool wxSelectionStore::IsSelected(unsigned item) const
|
|
{
|
|
bool isSel = m_itemsSel.Index(item) != wxNOT_FOUND;
|
|
|
|
// if the default state is to be selected, being in m_itemsSel means that
|
|
// the item is not selected, so we have to inverse the logic
|
|
return m_defaultState ? !isSel : isSel;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Select*()
|
|
// ----------------------------------------------------------------------------
|
|
|
|
bool wxSelectionStore::SelectItem(unsigned item, bool select)
|
|
{
|
|
// search for the item ourselves as like this we get the index where to
|
|
// insert it later if needed, so we do only one search in the array instead
|
|
// of two (adding item to a sorted array requires a search)
|
|
size_t index = m_itemsSel.IndexForInsert(item);
|
|
bool isSel = index < m_itemsSel.GetCount() && m_itemsSel[index] == item;
|
|
|
|
if ( select != m_defaultState )
|
|
{
|
|
if ( !isSel )
|
|
{
|
|
m_itemsSel.AddAt(item, index);
|
|
|
|
return true;
|
|
}
|
|
}
|
|
else // reset to default state
|
|
{
|
|
if ( isSel )
|
|
{
|
|
m_itemsSel.RemoveAt(index);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool wxSelectionStore::SelectRange(unsigned itemFrom, unsigned itemTo,
|
|
bool select,
|
|
wxArrayInt *itemsChanged)
|
|
{
|
|
// 100 is hardcoded but it shouldn't matter much: the important thing is
|
|
// that we don't refresh everything when really few (e.g. 1 or 2) items
|
|
// change state
|
|
static const unsigned MANY_ITEMS = 100;
|
|
|
|
wxASSERT_MSG( itemFrom <= itemTo, wxT("should be in order") );
|
|
|
|
// are we going to have more [un]selected items than the other ones?
|
|
if ( itemTo - itemFrom > m_count/2 )
|
|
{
|
|
if ( select != m_defaultState )
|
|
{
|
|
// the default state now becomes the same as 'select'
|
|
m_defaultState = select;
|
|
|
|
// so all the old selections (which had state select) shouldn't be
|
|
// selected any more, but all the other ones should
|
|
wxSelectedIndices selOld = m_itemsSel;
|
|
m_itemsSel.Empty();
|
|
|
|
// TODO: it should be possible to optimize the searches a bit
|
|
// knowing the possible range
|
|
|
|
unsigned item;
|
|
for ( item = 0; item < itemFrom; item++ )
|
|
{
|
|
if ( selOld.Index(item) == wxNOT_FOUND )
|
|
m_itemsSel.Add(item);
|
|
}
|
|
|
|
for ( item = itemTo + 1; item < m_count; item++ )
|
|
{
|
|
if ( selOld.Index(item) == wxNOT_FOUND )
|
|
m_itemsSel.Add(item);
|
|
}
|
|
|
|
// many items (> half) changed state
|
|
itemsChanged = NULL;
|
|
}
|
|
else // select == m_defaultState
|
|
{
|
|
// get the inclusive range of items between itemFrom and itemTo
|
|
size_t count = m_itemsSel.GetCount(),
|
|
start = m_itemsSel.IndexForInsert(itemFrom),
|
|
end = m_itemsSel.IndexForInsert(itemTo);
|
|
|
|
if ( start == count || m_itemsSel[start] < itemFrom )
|
|
{
|
|
start++;
|
|
}
|
|
|
|
if ( end == count || m_itemsSel[end] > itemTo )
|
|
{
|
|
end--;
|
|
}
|
|
|
|
if ( start <= end )
|
|
{
|
|
// delete all of them (from end to avoid changing indices)
|
|
for ( int i = end; i >= (int)start; i-- )
|
|
{
|
|
if ( itemsChanged )
|
|
{
|
|
if ( itemsChanged->GetCount() > MANY_ITEMS )
|
|
{
|
|
// stop counting (see comment below)
|
|
itemsChanged = NULL;
|
|
}
|
|
else
|
|
{
|
|
itemsChanged->Add(m_itemsSel[i]);
|
|
}
|
|
}
|
|
|
|
m_itemsSel.RemoveAt(i);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else // "few" items change state
|
|
{
|
|
if ( itemsChanged )
|
|
{
|
|
itemsChanged->Empty();
|
|
}
|
|
|
|
// just add the items to the selection
|
|
for ( unsigned item = itemFrom; item <= itemTo; item++ )
|
|
{
|
|
if ( SelectItem(item, select) && itemsChanged )
|
|
{
|
|
itemsChanged->Add(item);
|
|
|
|
if ( itemsChanged->GetCount() > MANY_ITEMS )
|
|
{
|
|
// stop counting them, we'll just eat gobs of memory
|
|
// for nothing at all - faster to refresh everything in
|
|
// this case
|
|
itemsChanged = NULL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// we set it to NULL if there are many items changing state
|
|
return itemsChanged != NULL;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// callbacks
|
|
// ----------------------------------------------------------------------------
|
|
|
|
void wxSelectionStore::OnItemDelete(unsigned item)
|
|
{
|
|
size_t count = m_itemsSel.GetCount(),
|
|
i = m_itemsSel.IndexForInsert(item);
|
|
|
|
if ( i < count && m_itemsSel[i] == item )
|
|
{
|
|
// this item itself was in m_itemsSel, remove it from there
|
|
m_itemsSel.RemoveAt(i);
|
|
|
|
count--;
|
|
}
|
|
|
|
// and adjust the index of all which follow it
|
|
while ( i < count )
|
|
{
|
|
// all following elements must be greater than the one we deleted
|
|
wxASSERT_MSG( m_itemsSel[i] > item, wxT("logic error") );
|
|
|
|
m_itemsSel[i++]--;
|
|
}
|
|
}
|
|
|
|
void wxSelectionStore::SetItemCount(unsigned count)
|
|
{
|
|
// forget about all items whose indices are now invalid if the size
|
|
// decreased
|
|
if ( count < m_count )
|
|
{
|
|
for ( size_t i = m_itemsSel.GetCount(); i > 0; i-- )
|
|
{
|
|
if ( m_itemsSel[i - 1] >= count )
|
|
m_itemsSel.RemoveAt(i - 1);
|
|
}
|
|
}
|
|
|
|
// remember the new number of items
|
|
m_count = count;
|
|
}
|