Limit the search in wxMSW virtual wxListCtrl by time.

Instead of performing the search only up to a certain number of items, do it
for as long as it takes less than the given time threshold (currently fixed at
half a second).

Closes #13038.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@67227 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2011-03-18 09:16:06 +00:00
parent 6935871895
commit fbe7473406

View File

@@ -34,6 +34,7 @@
#include "wx/intl.h" #include "wx/intl.h"
#include "wx/log.h" #include "wx/log.h"
#include "wx/settings.h" #include "wx/settings.h"
#include "wx/stopwatch.h"
#include "wx/dcclient.h" #include "wx/dcclient.h"
#include "wx/textctrl.h" #include "wx/textctrl.h"
#endif #endif
@@ -2366,12 +2367,8 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
#ifdef HAVE_NMLVFINDITEM #ifdef HAVE_NMLVFINDITEM
case LVN_ODFINDITEM: case LVN_ODFINDITEM:
// this message is only used with the virtual list control but // Find an item in a (necessarily virtual) list control.
// even there we don't want to always use it: in a control with if ( IsVirtual() )
// sufficiently big number of items (defined as > 1000 here),
// accidentally pressing a key could result in hanging an
// application waiting while it performs linear search
if ( IsVirtual() && GetItemCount() <= 1000 )
{ {
NMLVFINDITEM* pFindInfo = (NMLVFINDITEM*)lParam; NMLVFINDITEM* pFindInfo = (NMLVFINDITEM*)lParam;
@@ -2411,6 +2408,12 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
startPos = 0; startPos = 0;
} }
// Linear search in a control with a lot of items can take
// a long time so we limit the total time of the search to
// ensure that the program doesn't appear to hang.
#if wxUSE_STOPWATCH
wxStopWatch sw;
#endif // wxUSE_STOPWATCH
for ( int currentPos = startPos; ; ) for ( int currentPos = startPos; ; )
{ {
// does this item begin with searchstr? // does this item begin with searchstr?
@@ -2440,6 +2443,26 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
// item by default in this case. // item by default in this case.
return true; return true;
} }
#if wxUSE_STOPWATCH
// Check the time elapsed only every thousand
// iterations for performance reasons: if we did it
// more often calling wxStopWatch::Time() could take
// noticeable time on its own.
if ( !((currentPos - startPos)%1000) )
{
// We use half a second to limit the search time
// which is about as long as we can take without
// annoying the user.
if ( sw.Time() > 500 )
{
// As above, return true to prevent the control
// from selecting the first item by default.
return true;
}
}
#endif // wxUSE_STOPWATCH
} }
SetItemState(*result, SetItemState(*result,