Improve wxDataViewCtrl performance with wxDV_VARIABLE_LINE_HEIGHT

Store the line heights in a cache to make the (generic) wxDataViewCtrl
usable with this style.
This commit is contained in:
jensgoe
2018-11-18 22:48:28 +01:00
committed by Vadim Zeitlin
parent 3d75541662
commit d6a137b730
25 changed files with 1068 additions and 69 deletions

View File

@@ -4579,7 +4579,8 @@ COND_USE_GUI_1_WXUNIV_0___CORE_SRC_OBJECTS = \
monodll_datavgen.o \
monodll_editlbox.o \
monodll_laywin.o \
monodll_calctrlg.o
monodll_calctrlg.o \
monodll_rowheightcache.o
@COND_USE_GUI_1_WXUNIV_0@__CORE_SRC_OBJECTS = $(COND_USE_GUI_1_WXUNIV_0___CORE_SRC_OBJECTS)
COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS = \
$(__LOWLEVEL_SRC_OBJECTS_1) \
@@ -4839,7 +4840,8 @@ COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS = \
monodll_datavgen.o \
monodll_editlbox.o \
monodll_laywin.o \
monodll_calctrlg.o
monodll_calctrlg.o \
monodll_rowheightcache.o
@COND_USE_GUI_1_WXUNIV_1@__CORE_SRC_OBJECTS = $(COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS)
COND_TOOLKIT_DFB___LOWLEVEL_SRC_OBJECTS = \
monodll_fontmgrcmn.o \
@@ -6555,7 +6557,8 @@ COND_USE_GUI_1_WXUNIV_0___CORE_SRC_OBJECTS_1 = \
monolib_datavgen.o \
monolib_editlbox.o \
monolib_laywin.o \
monolib_calctrlg.o
monolib_calctrlg.o \
monolib_rowheightcache.o
@COND_USE_GUI_1_WXUNIV_0@__CORE_SRC_OBJECTS_1 = $(COND_USE_GUI_1_WXUNIV_0___CORE_SRC_OBJECTS_1)
COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS_1 = \
$(__LOWLEVEL_SRC_OBJECTS_3) \
@@ -6815,7 +6818,8 @@ COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS_1 = \
monolib_datavgen.o \
monolib_editlbox.o \
monolib_laywin.o \
monolib_calctrlg.o
monolib_calctrlg.o \
monolib_rowheightcache.o
@COND_USE_GUI_1_WXUNIV_1@__CORE_SRC_OBJECTS_1 = $(COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS_1)
COND_TOOLKIT_DFB___LOWLEVEL_SRC_OBJECTS_2 = \
monolib_fontmgrcmn.o \
@@ -8678,7 +8682,8 @@ COND_USE_GUI_1_WXUNIV_0___CORE_SRC_OBJECTS_2 = \
coredll_datavgen.o \
coredll_editlbox.o \
coredll_laywin.o \
coredll_calctrlg.o
coredll_calctrlg.o \
coredll_rowheightcache.o
@COND_USE_GUI_1_WXUNIV_0@__CORE_SRC_OBJECTS_2 = $(COND_USE_GUI_1_WXUNIV_0___CORE_SRC_OBJECTS_2)
COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS_2 = \
$(__LOWLEVEL_SRC_OBJECTS_5) \
@@ -8938,7 +8943,8 @@ COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS_2 = \
coredll_datavgen.o \
coredll_editlbox.o \
coredll_laywin.o \
coredll_calctrlg.o
coredll_calctrlg.o \
coredll_rowheightcache.o
@COND_USE_GUI_1_WXUNIV_1@__CORE_SRC_OBJECTS_2 = $(COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS_2)
COND_TOOLKIT_DFB___LOWLEVEL_SRC_OBJECTS_4 = \
coredll_fontmgrcmn.o \
@@ -10396,7 +10402,8 @@ COND_USE_GUI_1_WXUNIV_0___CORE_SRC_OBJECTS_3 = \
corelib_datavgen.o \
corelib_editlbox.o \
corelib_laywin.o \
corelib_calctrlg.o
corelib_calctrlg.o \
corelib_rowheightcache.o
@COND_USE_GUI_1_WXUNIV_0@__CORE_SRC_OBJECTS_3 = $(COND_USE_GUI_1_WXUNIV_0___CORE_SRC_OBJECTS_3)
COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS_3 = \
$(__LOWLEVEL_SRC_OBJECTS_7) \
@@ -10656,7 +10663,8 @@ COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS_3 = \
corelib_datavgen.o \
corelib_editlbox.o \
corelib_laywin.o \
corelib_calctrlg.o
corelib_calctrlg.o \
corelib_rowheightcache.o
@COND_USE_GUI_1_WXUNIV_1@__CORE_SRC_OBJECTS_3 = $(COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS_3)
COND_TOOLKIT_DFB___LOWLEVEL_SRC_OBJECTS_6 = \
corelib_fontmgrcmn.o \
@@ -20698,6 +20706,9 @@ monodll_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(MONODLL_ODEP)
@COND_USE_GUI_1@monodll_calctrlg.o: $(srcdir)/src/generic/calctrlg.cpp $(MONODLL_ODEP)
@COND_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/generic/calctrlg.cpp
@COND_USE_GUI_1@monodll_rowheightcache.o: $(srcdir)/src/generic/rowheightcache.cpp $(MONODLL_ODEP)
@COND_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/generic/rowheightcache.cpp
@COND_TOOLKIT_OSX_COCOA_USE_GUI_1@monodll_osx_cocoa_mediactrl.o: $(srcdir)/src/osx/cocoa/mediactrl.mm $(MONODLL_ODEP)
@COND_TOOLKIT_OSX_COCOA_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_OBJCXXFLAGS) $(srcdir)/src/osx/cocoa/mediactrl.mm
@@ -25951,6 +25962,9 @@ monolib_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(MONOLIB_ODEP)
@COND_USE_GUI_1@monolib_calctrlg.o: $(srcdir)/src/generic/calctrlg.cpp $(MONOLIB_ODEP)
@COND_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/generic/calctrlg.cpp
@COND_USE_GUI_1@monolib_rowheightcache.o: $(srcdir)/src/generic/rowheightcache.cpp $(MONOLIB_ODEP)
@COND_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/generic/rowheightcache.cpp
@COND_TOOLKIT_OSX_COCOA_USE_GUI_1@monolib_osx_cocoa_mediactrl.o: $(srcdir)/src/osx/cocoa/mediactrl.mm $(MONOLIB_ODEP)
@COND_TOOLKIT_OSX_COCOA_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_OBJCXXFLAGS) $(srcdir)/src/osx/cocoa/mediactrl.mm
@@ -31297,6 +31311,9 @@ coredll_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(COREDLL_ODEP)
@COND_USE_GUI_1@coredll_calctrlg.o: $(srcdir)/src/generic/calctrlg.cpp $(COREDLL_ODEP)
@COND_USE_GUI_1@ $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/generic/calctrlg.cpp
@COND_USE_GUI_1@coredll_rowheightcache.o: $(srcdir)/src/generic/rowheightcache.cpp $(COREDLL_ODEP)
@COND_USE_GUI_1@ $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/generic/rowheightcache.cpp
corelib_event.o: $(srcdir)/src/common/event.cpp $(CORELIB_ODEP)
$(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/common/event.cpp
@@ -35545,6 +35562,9 @@ corelib_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(CORELIB_ODEP)
@COND_USE_GUI_1@corelib_calctrlg.o: $(srcdir)/src/generic/calctrlg.cpp $(CORELIB_ODEP)
@COND_USE_GUI_1@ $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/generic/calctrlg.cpp
@COND_USE_GUI_1@corelib_rowheightcache.o: $(srcdir)/src/generic/rowheightcache.cpp $(CORELIB_ODEP)
@COND_USE_GUI_1@ $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/generic/rowheightcache.cpp
advdll_version_rc.o: $(srcdir)/src/msw/version.rc $(ADVDLL_ODEP)
$(WINDRES) -i$< -o$@ --define __WX$(TOOLKIT)__ $(__WXUNIV_DEFINE_p_67) $(__DEBUG_DEFINE_p_66) $(__EXCEPTIONS_DEFINE_p_65) $(__RTTI_DEFINE_p_65) $(__THREAD_DEFINE_p_65) --define WXBUILDING --define WXDLLNAME=$(WXDLLNAMEPREFIXGUI)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_adv$(WXCOMPILER)$(VENDORTAG)$(WXDLLVERSIONTAG) $(__RCDEFDIR_p) --include-dir $(top_srcdir)/include $(__INC_TIFF_BUILD_p_66) $(__INC_TIFF_p_66) $(__INC_JPEG_p_66) $(__INC_PNG_p_65) $(__INC_ZLIB_p_67) $(__INC_REGEX_p_65) $(__INC_EXPAT_p_65) --define WXUSINGDLL --define WXMAKINGDLL_ADV

View File

@@ -1005,6 +1005,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file!
src/generic/editlbox.cpp
src/generic/laywin.cpp
src/generic/calctrlg.cpp
src/generic/rowheightcache.cpp
</set>
<set var="GUI_CMN_HDR" hints="files">
wx/affinematrix2dbase.h

View File

@@ -908,6 +908,7 @@ set(GUI_CMN_SRC
src/generic/wizard.cpp
src/generic/editlbox.cpp
src/generic/datavgen.cpp
src/generic/rowheightcache.cpp
)
set(GUI_CMN_HDR

View File

@@ -899,6 +899,7 @@ GUI_CMN_SRC =
src/generic/renderg.cpp
src/generic/richmsgdlgg.cpp
src/generic/richtooltipg.cpp
src/generic/rowheightcache.cpp
src/generic/sashwin.cpp
src/generic/scrlwing.cpp
src/generic/selstore.cpp

View File

@@ -2126,7 +2126,8 @@ ____CORE_SRC_FILENAMES_OBJECTS = \
$(OBJS)\monodll_datavgen.obj \
$(OBJS)\monodll_editlbox.obj \
$(OBJS)\monodll_laywin.obj \
$(OBJS)\monodll_calctrlg.obj
$(OBJS)\monodll_calctrlg.obj \
$(OBJS)\monodll_rowheightcache.obj
!endif
!if "$(USE_GUI)" == "1" && "$(WXUNIV)" == "1"
____CORE_SRC_FILENAMES_OBJECTS = \
@@ -2451,7 +2452,8 @@ ____CORE_SRC_FILENAMES_OBJECTS = \
$(OBJS)\monodll_datavgen.obj \
$(OBJS)\monodll_editlbox.obj \
$(OBJS)\monodll_laywin.obj \
$(OBJS)\monodll_calctrlg.obj
$(OBJS)\monodll_calctrlg.obj \
$(OBJS)\monodll_rowheightcache.obj
!endif
!if "$(USE_STC)" == "1"
____MONOLIB_STC_SRC_FILENAMES_OBJECTS = \
@@ -2955,7 +2957,8 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \
$(OBJS)\monolib_datavgen.obj \
$(OBJS)\monolib_editlbox.obj \
$(OBJS)\monolib_laywin.obj \
$(OBJS)\monolib_calctrlg.obj
$(OBJS)\monolib_calctrlg.obj \
$(OBJS)\monolib_rowheightcache.obj
!endif
!if "$(USE_GUI)" == "1" && "$(WXUNIV)" == "1"
____CORE_SRC_FILENAMES_1_OBJECTS = \
@@ -3280,7 +3283,8 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \
$(OBJS)\monolib_datavgen.obj \
$(OBJS)\monolib_editlbox.obj \
$(OBJS)\monolib_laywin.obj \
$(OBJS)\monolib_calctrlg.obj
$(OBJS)\monolib_calctrlg.obj \
$(OBJS)\monolib_rowheightcache.obj
!endif
!if "$(USE_STC)" == "1"
____MONOLIB_STC_SRC_FILENAMES_1_OBJECTS = \
@@ -3659,7 +3663,8 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \
$(OBJS)\coredll_datavgen.obj \
$(OBJS)\coredll_editlbox.obj \
$(OBJS)\coredll_laywin.obj \
$(OBJS)\coredll_calctrlg.obj
$(OBJS)\coredll_calctrlg.obj \
$(OBJS)\coredll_rowheightcache.obj
!endif
!if "$(USE_GUI)" == "1" && "$(WXUNIV)" == "1"
____CORE_SRC_FILENAMES_2_OBJECTS = \
@@ -3984,7 +3989,8 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \
$(OBJS)\coredll_datavgen.obj \
$(OBJS)\coredll_editlbox.obj \
$(OBJS)\coredll_laywin.obj \
$(OBJS)\coredll_calctrlg.obj
$(OBJS)\coredll_calctrlg.obj \
$(OBJS)\coredll_rowheightcache.obj
!endif
!if "$(MONOLITHIC)" == "0" && "$(SHARED)" == "0" && "$(USE_GUI)" == "1"
__corelib___depname = \
@@ -4329,7 +4335,8 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \
$(OBJS)\corelib_datavgen.obj \
$(OBJS)\corelib_editlbox.obj \
$(OBJS)\corelib_laywin.obj \
$(OBJS)\corelib_calctrlg.obj
$(OBJS)\corelib_calctrlg.obj \
$(OBJS)\corelib_rowheightcache.obj
!endif
!if "$(USE_GUI)" == "1" && "$(WXUNIV)" == "1"
____CORE_SRC_FILENAMES_3_OBJECTS = \
@@ -4654,7 +4661,8 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \
$(OBJS)\corelib_datavgen.obj \
$(OBJS)\corelib_editlbox.obj \
$(OBJS)\corelib_laywin.obj \
$(OBJS)\corelib_calctrlg.obj
$(OBJS)\corelib_calctrlg.obj \
$(OBJS)\corelib_rowheightcache.obj
!endif
!if "$(SHARED)" == "1"
____wxcore_namedll_DEP = $(__coredll___depname)
@@ -8937,6 +8945,11 @@ $(OBJS)\monodll_calctrlg.obj: ..\..\src\generic\calctrlg.cpp
$(CXX) -q -c -P -o$@ $(MONODLL_CXXFLAGS) ..\..\src\generic\calctrlg.cpp
!endif
!if "$(USE_GUI)" == "1"
$(OBJS)\monodll_rowheightcache.obj: ..\..\src\generic\rowheightcache.cpp
$(CXX) -q -c -P -o$@ $(MONODLL_CXXFLAGS) ..\..\src\generic\rowheightcache.cpp
!endif
$(OBJS)\monodll_version.res: ..\..\src\msw\version.rc
brcc32 -32 -r -fo$@ -i$(BCCDIR)\include -d__WXMSW__ $(__WXUNIV_DEFINE_p_67) $(__DEBUG_DEFINE_p_66) $(__NDEBUG_DEFINE_p_65) $(__EXCEPTIONS_DEFINE_p_65) $(__RTTI_DEFINE_p_65) $(__THREAD_DEFINE_p_65) $(__UNICODE_DEFINE_p_67) -i$(SETUPHDIR) -i..\..\include $(____CAIRO_INCLUDEDIR_FILENAMES_4) -dWXBUILDING -dWXDLLNAME=wx$(PORTNAME)$(WXUNIVNAME)$(WX_VERSION_NODOT)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)$(WXCOMPILER)$(VENDORTAG) -i$(BCCDIR)\include\windows\sdk -i..\..\src\tiff\libtiff -i..\..\src\jpeg -i..\..\src\png -i..\..\src\zlib -i..\..\src\regex -i..\..\src\expat\expat\lib -i..\..\src\stc\scintilla\include -i..\..\src\stc\scintilla\lexlib -i..\..\src\stc\scintilla\src -d__WX__ -dSCI_LEXER -dNO_CXX11_REGEX -dLINK_LEXERS -dwxUSE_BASE=1 -dWXMAKINGDLL ..\..\src\msw\version.rc
@@ -11478,6 +11491,11 @@ $(OBJS)\monolib_calctrlg.obj: ..\..\src\generic\calctrlg.cpp
$(CXX) -q -c -P -o$@ $(MONOLIB_CXXFLAGS) ..\..\src\generic\calctrlg.cpp
!endif
!if "$(USE_GUI)" == "1"
$(OBJS)\monolib_rowheightcache.obj: ..\..\src\generic\rowheightcache.cpp
$(CXX) -q -c -P -o$@ $(MONOLIB_CXXFLAGS) ..\..\src\generic\rowheightcache.cpp
!endif
$(OBJS)\basedll_dummy.obj: ..\..\src\common\dummy.cpp
$(CXX) -q -c -P -o$@ $(BASEDLL_CXXFLAGS) -H ..\..\src\common\dummy.cpp
@@ -13983,6 +14001,11 @@ $(OBJS)\coredll_calctrlg.obj: ..\..\src\generic\calctrlg.cpp
$(CXX) -q -c -P -o$@ $(COREDLL_CXXFLAGS) ..\..\src\generic\calctrlg.cpp
!endif
!if "$(USE_GUI)" == "1"
$(OBJS)\coredll_rowheightcache.obj: ..\..\src\generic\rowheightcache.cpp
$(CXX) -q -c -P -o$@ $(COREDLL_CXXFLAGS) ..\..\src\generic\rowheightcache.cpp
!endif
$(OBJS)\corelib_dummy.obj: ..\..\src\common\dummy.cpp
$(CXX) -q -c -P -o$@ $(CORELIB_CXXFLAGS) -H ..\..\src\common\dummy.cpp
@@ -15711,6 +15734,11 @@ $(OBJS)\corelib_calctrlg.obj: ..\..\src\generic\calctrlg.cpp
$(CXX) -q -c -P -o$@ $(CORELIB_CXXFLAGS) ..\..\src\generic\calctrlg.cpp
!endif
!if "$(USE_GUI)" == "1"
$(OBJS)\corelib_rowheightcache.obj: ..\..\src\generic\rowheightcache.cpp
$(CXX) -q -c -P -o$@ $(CORELIB_CXXFLAGS) ..\..\src\generic\rowheightcache.cpp
!endif
$(OBJS)\advdll_dummy.obj: ..\..\src\common\dummy.cpp
$(CXX) -q -c -P -o$@ $(ADVDLL_CXXFLAGS) -H ..\..\src\common\dummy.cpp

View File

@@ -2152,7 +2152,8 @@ ____CORE_SRC_FILENAMES_OBJECTS = \
$(OBJS)\monodll_datavgen.o \
$(OBJS)\monodll_editlbox.o \
$(OBJS)\monodll_laywin.o \
$(OBJS)\monodll_calctrlg.o
$(OBJS)\monodll_calctrlg.o \
$(OBJS)\monodll_rowheightcache.o
endif
endif
ifeq ($(USE_GUI),1)
@@ -2479,7 +2480,8 @@ ____CORE_SRC_FILENAMES_OBJECTS = \
$(OBJS)\monodll_datavgen.o \
$(OBJS)\monodll_editlbox.o \
$(OBJS)\monodll_laywin.o \
$(OBJS)\monodll_calctrlg.o
$(OBJS)\monodll_calctrlg.o \
$(OBJS)\monodll_rowheightcache.o
endif
endif
ifeq ($(USE_STC),1)
@@ -2987,7 +2989,8 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \
$(OBJS)\monolib_datavgen.o \
$(OBJS)\monolib_editlbox.o \
$(OBJS)\monolib_laywin.o \
$(OBJS)\monolib_calctrlg.o
$(OBJS)\monolib_calctrlg.o \
$(OBJS)\monolib_rowheightcache.o
endif
endif
ifeq ($(USE_GUI),1)
@@ -3314,7 +3317,8 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \
$(OBJS)\monolib_datavgen.o \
$(OBJS)\monolib_editlbox.o \
$(OBJS)\monolib_laywin.o \
$(OBJS)\monolib_calctrlg.o
$(OBJS)\monolib_calctrlg.o \
$(OBJS)\monolib_rowheightcache.o
endif
endif
ifeq ($(USE_STC),1)
@@ -3707,7 +3711,8 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \
$(OBJS)\coredll_datavgen.o \
$(OBJS)\coredll_editlbox.o \
$(OBJS)\coredll_laywin.o \
$(OBJS)\coredll_calctrlg.o
$(OBJS)\coredll_calctrlg.o \
$(OBJS)\coredll_rowheightcache.o
endif
endif
ifeq ($(USE_GUI),1)
@@ -4034,7 +4039,8 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \
$(OBJS)\coredll_datavgen.o \
$(OBJS)\coredll_editlbox.o \
$(OBJS)\coredll_laywin.o \
$(OBJS)\coredll_calctrlg.o
$(OBJS)\coredll_calctrlg.o \
$(OBJS)\coredll_rowheightcache.o
endif
endif
ifeq ($(MONOLITHIC),0)
@@ -4385,7 +4391,8 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \
$(OBJS)\corelib_datavgen.o \
$(OBJS)\corelib_editlbox.o \
$(OBJS)\corelib_laywin.o \
$(OBJS)\corelib_calctrlg.o
$(OBJS)\corelib_calctrlg.o \
$(OBJS)\corelib_rowheightcache.o
endif
endif
ifeq ($(USE_GUI),1)
@@ -4712,7 +4719,8 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \
$(OBJS)\corelib_datavgen.o \
$(OBJS)\corelib_editlbox.o \
$(OBJS)\corelib_laywin.o \
$(OBJS)\corelib_calctrlg.o
$(OBJS)\corelib_calctrlg.o \
$(OBJS)\corelib_rowheightcache.o
endif
endif
ifeq ($(SHARED),1)
@@ -9119,6 +9127,11 @@ $(OBJS)\monodll_calctrlg.o: ../../src/generic/calctrlg.cpp
$(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $<
endif
ifeq ($(USE_GUI),1)
$(OBJS)\monodll_rowheightcache.o: ../../src/generic/rowheightcache.cpp
$(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $<
endif
$(OBJS)\monodll_version_rc.o: ../../src/msw/version.rc
$(WINDRES) -i$< -o$@ --define __WXMSW__ $(__WXUNIV_DEFINE_p_67) $(__DEBUG_DEFINE_p_66) $(__NDEBUG_DEFINE_p_65) $(__EXCEPTIONS_DEFINE_p_65) $(__RTTI_DEFINE_p_65) $(__THREAD_DEFINE_p_65) $(__UNICODE_DEFINE_p_67) --include-dir $(SETUPHDIR) --include-dir ../../include $(__CAIRO_INCLUDEDIR_p) --define WXBUILDING --define WXDLLNAME=wx$(PORTNAME)$(WXUNIVNAME)$(WX_VERSION_NODOT)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)$(WXCOMPILER)$(VENDORTAG) --include-dir ../../src/tiff/libtiff --include-dir ../../src/jpeg --include-dir ../../src/png --include-dir ../../src/zlib --include-dir ../../src/regex --include-dir ../../src/expat/expat/lib --include-dir ../../src/stc/scintilla/include --include-dir ../../src/stc/scintilla/lexlib --include-dir ../../src/stc/scintilla/src --define __WX__ --define SCI_LEXER --define NO_CXX11_REGEX --define LINK_LEXERS --define wxUSE_BASE=1 --define WXMAKINGDLL
@@ -11660,6 +11673,11 @@ $(OBJS)\monolib_calctrlg.o: ../../src/generic/calctrlg.cpp
$(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $<
endif
ifeq ($(USE_GUI),1)
$(OBJS)\monolib_rowheightcache.o: ../../src/generic/rowheightcache.cpp
$(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $<
endif
$(OBJS)\basedll_dummy.o: ../../src/common/dummy.cpp
$(CXX) -c -o $@ $(BASEDLL_CXXFLAGS) $(CPPDEPS) $<
@@ -14165,6 +14183,11 @@ $(OBJS)\coredll_calctrlg.o: ../../src/generic/calctrlg.cpp
$(CXX) -c -o $@ $(COREDLL_CXXFLAGS) $(CPPDEPS) $<
endif
ifeq ($(USE_GUI),1)
$(OBJS)\coredll_rowheightcache.o: ../../src/generic/rowheightcache.cpp
$(CXX) -c -o $@ $(COREDLL_CXXFLAGS) $(CPPDEPS) $<
endif
$(OBJS)\corelib_dummy.o: ../../src/common/dummy.cpp
$(CXX) -c -o $@ $(CORELIB_CXXFLAGS) $(CPPDEPS) $<
@@ -15893,6 +15916,11 @@ $(OBJS)\corelib_calctrlg.o: ../../src/generic/calctrlg.cpp
$(CXX) -c -o $@ $(CORELIB_CXXFLAGS) $(CPPDEPS) $<
endif
ifeq ($(USE_GUI),1)
$(OBJS)\corelib_rowheightcache.o: ../../src/generic/rowheightcache.cpp
$(CXX) -c -o $@ $(CORELIB_CXXFLAGS) $(CPPDEPS) $<
endif
$(OBJS)\advdll_dummy.o: ../../src/common/dummy.cpp
$(CXX) -c -o $@ $(ADVDLL_CXXFLAGS) $(CPPDEPS) $<

View File

@@ -2443,7 +2443,8 @@ ____CORE_SRC_FILENAMES_OBJECTS = \
$(OBJS)\monodll_datavgen.obj \
$(OBJS)\monodll_editlbox.obj \
$(OBJS)\monodll_laywin.obj \
$(OBJS)\monodll_calctrlg.obj
$(OBJS)\monodll_calctrlg.obj \
$(OBJS)\monodll_rowheightcache.obj
!endif
!if "$(USE_GUI)" == "1" && "$(WXUNIV)" == "1"
____CORE_SRC_FILENAMES_OBJECTS = \
@@ -2768,7 +2769,8 @@ ____CORE_SRC_FILENAMES_OBJECTS = \
$(OBJS)\monodll_datavgen.obj \
$(OBJS)\monodll_editlbox.obj \
$(OBJS)\monodll_laywin.obj \
$(OBJS)\monodll_calctrlg.obj
$(OBJS)\monodll_calctrlg.obj \
$(OBJS)\monodll_rowheightcache.obj
!endif
!if "$(USE_STC)" == "1"
____MONOLIB_STC_SRC_FILENAMES_OBJECTS = \
@@ -3278,7 +3280,8 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \
$(OBJS)\monolib_datavgen.obj \
$(OBJS)\monolib_editlbox.obj \
$(OBJS)\monolib_laywin.obj \
$(OBJS)\monolib_calctrlg.obj
$(OBJS)\monolib_calctrlg.obj \
$(OBJS)\monolib_rowheightcache.obj
!endif
!if "$(USE_GUI)" == "1" && "$(WXUNIV)" == "1"
____CORE_SRC_FILENAMES_1_OBJECTS = \
@@ -3603,7 +3606,8 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \
$(OBJS)\monolib_datavgen.obj \
$(OBJS)\monolib_editlbox.obj \
$(OBJS)\monolib_laywin.obj \
$(OBJS)\monolib_calctrlg.obj
$(OBJS)\monolib_calctrlg.obj \
$(OBJS)\monolib_rowheightcache.obj
!endif
!if "$(USE_STC)" == "1"
____MONOLIB_STC_SRC_FILENAMES_1_OBJECTS = \
@@ -4048,7 +4052,8 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \
$(OBJS)\coredll_datavgen.obj \
$(OBJS)\coredll_editlbox.obj \
$(OBJS)\coredll_laywin.obj \
$(OBJS)\coredll_calctrlg.obj
$(OBJS)\coredll_calctrlg.obj \
$(OBJS)\coredll_rowheightcache.obj
!endif
!if "$(USE_GUI)" == "1" && "$(WXUNIV)" == "1"
____CORE_SRC_FILENAMES_2_OBJECTS = \
@@ -4373,7 +4378,8 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \
$(OBJS)\coredll_datavgen.obj \
$(OBJS)\coredll_editlbox.obj \
$(OBJS)\coredll_laywin.obj \
$(OBJS)\coredll_calctrlg.obj
$(OBJS)\coredll_calctrlg.obj \
$(OBJS)\coredll_rowheightcache.obj
!endif
!if "$(MONOLITHIC)" == "0" && "$(SHARED)" == "0" && "$(USE_GUI)" == "1"
__corelib___depname = \
@@ -4724,7 +4730,8 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \
$(OBJS)\corelib_datavgen.obj \
$(OBJS)\corelib_editlbox.obj \
$(OBJS)\corelib_laywin.obj \
$(OBJS)\corelib_calctrlg.obj
$(OBJS)\corelib_calctrlg.obj \
$(OBJS)\corelib_rowheightcache.obj
!endif
!if "$(USE_GUI)" == "1" && "$(WXUNIV)" == "1"
____CORE_SRC_FILENAMES_3_OBJECTS = \
@@ -5049,7 +5056,8 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \
$(OBJS)\corelib_datavgen.obj \
$(OBJS)\corelib_editlbox.obj \
$(OBJS)\corelib_laywin.obj \
$(OBJS)\corelib_calctrlg.obj
$(OBJS)\corelib_calctrlg.obj \
$(OBJS)\corelib_rowheightcache.obj
!endif
!if "$(SHARED)" == "1"
____wxcore_namedll_DEP = $(__coredll___depname)
@@ -9646,6 +9654,11 @@ $(OBJS)\monodll_calctrlg.obj: ..\..\src\generic\calctrlg.cpp
$(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\generic\calctrlg.cpp
!endif
!if "$(USE_GUI)" == "1"
$(OBJS)\monodll_rowheightcache.obj: ..\..\src\generic\rowheightcache.cpp
$(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\generic\rowheightcache.cpp
!endif
$(OBJS)\monodll_version.res: ..\..\src\msw\version.rc
rc /fo$@ /d WIN32 $(____DEBUGRUNTIME_6) /d _CRT_SECURE_NO_DEPRECATE=1 /d _CRT_NON_CONFORMING_SWPRINTFS=1 /d _SCL_SECURE_NO_WARNINGS=1 $(__NO_VC_CRTDBG_p_72) /d __WXMSW__ $(__WXUNIV_DEFINE_p_67) $(__DEBUG_DEFINE_p_66) $(__NDEBUG_DEFINE_p_65) $(__EXCEPTIONS_DEFINE_p_65) $(__RTTI_DEFINE_p_65) $(__THREAD_DEFINE_p_65) $(__UNICODE_DEFINE_p_67) /i $(SETUPHDIR) /i ..\..\include $(____CAIRO_INCLUDEDIR_FILENAMES_4) /d WXBUILDING /d WXDLLNAME=wx$(PORTNAME)$(WXUNIVNAME)$(WX_VERSION_NODOT)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)$(WXCOMPILER)$(VENDORTAG) /i ..\..\src\tiff\libtiff /i ..\..\src\jpeg /i ..\..\src\png /i ..\..\src\zlib /i ..\..\src\regex /i ..\..\src\expat\expat\lib /i ..\..\src\stc\scintilla\include /i ..\..\src\stc\scintilla\lexlib /i ..\..\src\stc\scintilla\src /d __WX__ /d SCI_LEXER /d NO_CXX11_REGEX /d LINK_LEXERS /d wxUSE_BASE=1 /d WXMAKINGDLL ..\..\src\msw\version.rc
@@ -12187,6 +12200,11 @@ $(OBJS)\monolib_calctrlg.obj: ..\..\src\generic\calctrlg.cpp
$(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\generic\calctrlg.cpp
!endif
!if "$(USE_GUI)" == "1"
$(OBJS)\monolib_rowheightcache.obj: ..\..\src\generic\rowheightcache.cpp
$(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\generic\rowheightcache.cpp
!endif
$(OBJS)\basedll_dummy.obj: ..\..\src\common\dummy.cpp
$(CXX) /c /nologo /TP /Fo$@ $(BASEDLL_CXXFLAGS) /Ycwx/wxprec.h ..\..\src\common\dummy.cpp
@@ -14692,6 +14710,11 @@ $(OBJS)\coredll_calctrlg.obj: ..\..\src\generic\calctrlg.cpp
$(CXX) /c /nologo /TP /Fo$@ $(COREDLL_CXXFLAGS) ..\..\src\generic\calctrlg.cpp
!endif
!if "$(USE_GUI)" == "1"
$(OBJS)\coredll_rowheightcache.obj: ..\..\src\generic\rowheightcache.cpp
$(CXX) /c /nologo /TP /Fo$@ $(COREDLL_CXXFLAGS) ..\..\src\generic\rowheightcache.cpp
!endif
$(OBJS)\corelib_dummy.obj: ..\..\src\common\dummy.cpp
$(CXX) /c /nologo /TP /Fo$@ $(CORELIB_CXXFLAGS) /Ycwx/wxprec.h ..\..\src\common\dummy.cpp
@@ -16420,6 +16443,11 @@ $(OBJS)\corelib_calctrlg.obj: ..\..\src\generic\calctrlg.cpp
$(CXX) /c /nologo /TP /Fo$@ $(CORELIB_CXXFLAGS) ..\..\src\generic\calctrlg.cpp
!endif
!if "$(USE_GUI)" == "1"
$(OBJS)\corelib_rowheightcache.obj: ..\..\src\generic\rowheightcache.cpp
$(CXX) /c /nologo /TP /Fo$@ $(CORELIB_CXXFLAGS) ..\..\src\generic\rowheightcache.cpp
!endif
$(OBJS)\advdll_dummy.obj: ..\..\src\common\dummy.cpp
$(CXX) /c /nologo /TP /Fo$@ $(ADVDLL_CXXFLAGS) /Ycwx/wxprec.h ..\..\src\common\dummy.cpp

View File

@@ -1061,6 +1061,7 @@
<ClCompile Include="..\..\src\generic\hyperlinkg.cpp" />
<ClCompile Include="..\..\src\generic\notifmsgg.cpp" />
<ClCompile Include="..\..\src\common\bmpcboxcmn.cpp" />
<ClCompile Include="..\..\src\generic\rowheightcache.cpp" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\..\src\msw\version.rc">

View File

@@ -603,6 +603,9 @@
<ClCompile Include="..\..\src\generic\richtooltipg.cpp">
<Filter>Generic Sources</Filter>
</ClCompile>
<ClCompile Include="..\..\src\generic\rowheightcache.cpp">
<Filter>Generic Sources</Filter>
</ClCompile>
<ClCompile Include="..\..\src\generic\sashwin.cpp">
<Filter>Generic Sources</Filter>
</ClCompile>

View File

@@ -1286,6 +1286,9 @@
<File
RelativePath="..\..\src\generic\richtooltipg.cpp">
</File>
<File
RelativePath="..\..\src\generic\rowheightcache.cpp">
</File>
<File
RelativePath="..\..\src\generic\sashwin.cpp">
</File>

View File

@@ -2127,6 +2127,10 @@
RelativePath="..\..\src\generic\richtooltipg.cpp"
>
</File>
<File
RelativePath="..\..\src\generic\rowheightcache.cpp"
>
</File>
<File
RelativePath="..\..\src\generic\sashwin.cpp"
>

View File

@@ -2123,6 +2123,10 @@
RelativePath="..\..\src\generic\richtooltipg.cpp"
>
</File>
<File
RelativePath="..\..\src\generic\rowheightcache.cpp"
>
</File>
<File
RelativePath="..\..\src\generic\sashwin.cpp"
>

View File

@@ -144,6 +144,7 @@ All (GUI):
- Adapt AUI colours to system colour changes (Daniel Kulp).
- Fix removing and inserting pages in wxToolbook (Stefan Ziegler).
- Fix bug in template selection in docview framework (jwiesemann).
- Improve wxDataViewCtrl performance with variable line heights (Jens Goepfert).
wxGTK:

View File

@@ -0,0 +1,142 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/private/rowheightcache.h
// Purpose: height cache of rows in a dataview
// Author: Jens Goepfert (mail@jensgoepfert.de)
// Created: 2018-03-06
// Copyright: (c) wxWidgets team
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_PRIVATE_ROWHEIGHTCACHE_H_
#define _WX_PRIVATE_ROWHEIGHTCACHE_H_
#include "wx/hashmap.h"
#include "wx/vector.h"
// struct describing a range of rows which contains rows <from> .. <to-1>
struct RowRange
{
unsigned int from;
unsigned int to;
};
/**
@class RowRanges
A helper class that manages a set of RowRange objects.
It stores the indices that are members of a group in a memory
efficiant way.
*/
class WXDLLIMPEXP_CORE RowRanges
//class RowRanges
{
public:
/**
Adds a row index to this group by adding it to an existing RowRange
or by creating a new one.
*/
void Add(unsigned int row);
/**
Removes a row index and all indices after idx from this group.
*/
void Remove(unsigned int row);
/**
Checks whether a row index is contained in this group.
*/
bool Has(unsigned int row) const;
/**
Returns the number of row indices that are contained in this group.
*/
unsigned int CountAll() const;
/**
Returns the number of rows that are in this group before the given row index.
not including given row.
*/
unsigned int CountTo(unsigned int row) const;
unsigned int GetSize() const; // for debugging statistics
private:
wxVector<RowRange> m_ranges;
/**
If a new row index was inserted Cleanup checks if the neighbour ranges
of idx can includes the same row indices and discards
unnecessary RowRange objects.
*/
void CleanUp(unsigned int idx);
};
WX_DECLARE_HASH_MAP(unsigned int, RowRanges*, wxIntegerHash, wxIntegerEqual,
HeightToRowRangesMap);
/**
@class HeightCache
HeightCache implements a cache mechanism for the DataViewCtrl to give
fast access to:
* the height of one line (GetLineHeight)
* the y-coordinate where a row starts (GetLineStart)
* and vice versa (GetLineAt)
The layout of the cache is a hashmap where the keys are all exisiting
row heights in pixels. The values are RowRange objects that represents
all having the specified height.
{
22: RowRange([0..10], [15..17], [20..2000]),
42: RowRange([11..12], [18..18]),
62: RowRange([13..14], [19..19])
}
Examples
========
GetLineStart
------------
To retrieve the y-coordinate of item 1000 it is neccessary to look into
each key of the hashmap *m_heightToRowRange*. Get the row count of
indices lower than 1000 (RowRange::CountTo) and multiplies it wich the
according height.
RowRange([0..10], [15..17], [20..2000]).CountTo(1000)
--> 0..10 are 11 items, 15..17 are 3 items and 20..1000 are 980 items (1000-20)
= 11 + 3 + 980 = 994 items
GetLineStart(1000) --> (22 * 994) + (42 * 3) + (62 * 3) = 22180
GetLineHeight
-------------
To retrieve the line height look into each key and check if row is
contained in RowRange (RowRange::Has)
GetLineAt
---------
To retrieve the row that starts at a specific y-coordinate.
Look into each key and count all rows.
Use bisect algorithm in combination with GetLineStart() to
find the appropriate item
*/
class WXDLLIMPEXP_ADV HeightCache
{
public:
bool GetLineStart(unsigned int row, int &start);
bool GetLineHeight(unsigned int row, int &height);
bool GetLineAt(int y, unsigned int &row);
void Put(const unsigned int row, const int height);
/**
removes the stored height of the given row from the cache
and invalidates all cached rows (including row)
*/
void Remove(const unsigned int row);
void Clear();
private:
bool GetLineInfo(unsigned int row, int &start, int &height);
HeightToRowRangesMap m_heightToRowRange;
};
#endif // _WX_PRIVATE_ROWHEIGHTCACHE_H_

View File

@@ -53,6 +53,7 @@
#include "wx/stopwatch.h"
#include "wx/weakref.h"
#include "wx/generic/private/markuptext.h"
#include "wx/generic/private/rowheightcache.h"
#include "wx/generic/private/widthcalc.h"
#if wxUSE_ACCESSIBILITY
#include "wx/private/markupparser.h"
@@ -910,6 +911,7 @@ private:
bool m_hasFocus;
bool m_useCellFocus;
bool m_currentColSetByKeyboard;
HeightCache *m_rowHeightCache;
#if wxUSE_DRAG_AND_DROP
int m_dragCount;
@@ -1946,6 +1948,14 @@ wxDataViewMainWindow::wxDataViewMainWindow( wxDataViewCtrl *parent, wxWindowID i
m_useCellFocus = false;
m_currentRow = (unsigned)-1;
m_lineHeight = GetDefaultRowHeight();
if (GetOwner()->HasFlag(wxDV_VARIABLE_LINE_HEIGHT))
{
m_rowHeightCache = new HeightCache();
}
else
{
m_rowHeightCache = NULL;
}
#if wxUSE_DRAG_AND_DROP
m_dragCount = 0;
@@ -1982,6 +1992,11 @@ wxDataViewMainWindow::~wxDataViewMainWindow()
{
DestroyTree();
delete m_renameTimer;
if (m_rowHeightCache != NULL)
{
m_rowHeightCache->Clear();
delete m_rowHeightCache;
}
}
@@ -2739,6 +2754,12 @@ bool wxDataViewMainWindow::ItemAdded(const wxDataViewItem & parent, const wxData
}
else
{
if (GetOwner()->HasFlag(wxDV_VARIABLE_LINE_HEIGHT))
{
// specific position (row) is unclear, so clear whole height cache
m_rowHeightCache->Clear();
}
wxDataViewTreeNode *parentNode = FindNode(parent);
if ( !parentNode )
@@ -2880,6 +2901,9 @@ bool wxDataViewMainWindow::ItemDeleted(const wxDataViewItem& parent,
return true;
}
if (GetOwner()->HasFlag(wxDV_VARIABLE_LINE_HEIGHT))
m_rowHeightCache->Remove(GetRowByItem(parent) + itemPosInNode);
// Delete the item from wxDataViewTreeNode representation:
const int itemsDeleted = 1 + itemNode->GetSubTreeCount();
@@ -2944,6 +2968,9 @@ bool wxDataViewMainWindow::DoItemChanged(const wxDataViewItem & item, int view_c
{
if ( !IsVirtualList() )
{
if (GetOwner()->HasFlag(wxDV_VARIABLE_LINE_HEIGHT))
m_rowHeightCache->Remove(GetRowByItem(item));
// Move this node to its new correct place after it was updated.
//
// In principle, we could skip the call to PutInSortOrder() if the modified
@@ -3277,6 +3304,9 @@ void wxDataViewMainWindow::SendSelectionChangedEvent( const wxDataViewItem& item
void wxDataViewMainWindow::RefreshRows( unsigned int from, unsigned int to )
{
if (from == to && from == ((unsigned)-1))
return;
wxRect rect = GetLinesRect(from, to);
m_owner->CalcScrolledPosition(rect.x, rect.y, &rect.x, &rect.y);
@@ -3325,21 +3355,35 @@ int wxDataViewMainWindow::GetLineStart( unsigned int row ) const
if (GetOwner()->GetWindowStyle() & wxDV_VARIABLE_LINE_HEIGHT)
{
// TODO make more efficient
int start = 0;
if (m_rowHeightCache->GetLineStart(row, start))
return start;
unsigned int r;
for (r = 0; r < row; r++)
{
const wxDataViewTreeNode* node = GetTreeNodeByRow(r);
if (!node) return start;
int height = 0;
if (m_rowHeightCache->GetLineHeight(r, height))
{
start += height;
continue;
}
wxDataViewItem item = node->GetItem();
wxDataViewItem item;
if (IsList())
{
item = GetItemByRow(r);
}
else
{
const wxDataViewTreeNode* node = GetTreeNodeByRow(r);
if (!node) return start;
item = node->GetItem();
}
unsigned int cols = GetOwner()->GetColumnCount();
unsigned int col;
int height = m_lineHeight;
height = m_lineHeight;
for (col = 0; col < cols; col++)
{
const wxDataViewColumn *column = GetOwner()->GetColumn(col);
@@ -3359,6 +3403,8 @@ int wxDataViewMainWindow::GetLineStart( unsigned int row ) const
}
start += height;
m_rowHeightCache->Put(r, height);
}
return start;
@@ -3377,39 +3423,58 @@ int wxDataViewMainWindow::GetLineAt( unsigned int y ) const
if ( !GetOwner()->HasFlag(wxDV_VARIABLE_LINE_HEIGHT) )
return y / m_lineHeight;
// TODO make more efficient
unsigned int row = 0;
unsigned int yy = 0;
if (m_rowHeightCache->GetLineAt(y, row))
return row;
for (;;)
{
const wxDataViewTreeNode* node = GetTreeNodeByRow(row);
if (!node)
int height = 0;
if (!m_rowHeightCache->GetLineHeight(row, height))
{
// not really correct...
return row + ((y-yy) / m_lineHeight);
}
// row height not in cache -> get it from the renderer...
wxDataViewItem item = node->GetItem();
wxDataViewItem item;
if (IsList())
{
item = GetItemByRow(row);
}
else
{
const wxDataViewTreeNode* node = GetTreeNodeByRow(row);
if (!node)
{
// not really correct...
return row + ((y - yy) / m_lineHeight);
}
item = node->GetItem();
}
unsigned int cols = GetOwner()->GetColumnCount();
unsigned int col;
int height = m_lineHeight;
for (col = 0; col < cols; col++)
{
const wxDataViewColumn *column = GetOwner()->GetColumn(col);
if (column->IsHidden())
continue; // skip it!
unsigned int cols = GetOwner()->GetColumnCount();
unsigned int col;
height = m_lineHeight;
for (col = 0; col < cols; col++)
{
const wxDataViewColumn *column = GetOwner()->GetColumn(col);
if (column->IsHidden())
continue; // skip it!
if ((col != 0) &&
model->IsContainer(item) &&
!model->HasContainerColumns(item))
continue; // skip it!
if ((col != 0) &&
model->IsContainer(item) &&
!model->HasContainerColumns(item))
continue; // skip it!
wxDataViewRenderer *renderer =
const_cast<wxDataViewRenderer*>(column->GetRenderer());
renderer->PrepareForItem(model, item, column->GetModelColumn());
wxDataViewRenderer *renderer =
const_cast<wxDataViewRenderer*>(column->GetRenderer());
renderer->PrepareForItem(model, item, column->GetModelColumn());
height = wxMax( height, renderer->GetSize().y );
height = wxMax( height, renderer->GetSize().y );
}
// ... and store the height in the cache
m_rowHeightCache->Put(row, height);
}
yy += height;
@@ -3426,16 +3491,24 @@ int wxDataViewMainWindow::GetLineHeight( unsigned int row ) const
if (GetOwner()->GetWindowStyle() & wxDV_VARIABLE_LINE_HEIGHT)
{
wxASSERT( !IsVirtualList() );
int height = 0;
if (m_rowHeightCache->GetLineHeight(row, height))
return height;
const wxDataViewTreeNode* node = GetTreeNodeByRow(row);
// wxASSERT( node );
if (!node) return m_lineHeight;
wxDataViewItem item = node->GetItem();
int height = m_lineHeight;
wxDataViewItem item;
if (IsList())
{
item = GetItemByRow(row);
}
else
{
const wxDataViewTreeNode* node = GetTreeNodeByRow(row);
// wxASSERT( node );
if (!node) return m_lineHeight;
item = node->GetItem();
}
height = m_lineHeight;
unsigned int cols = GetOwner()->GetColumnCount();
unsigned int col;
for (col = 0; col < cols; col++)
@@ -3456,6 +3529,8 @@ int wxDataViewMainWindow::GetLineHeight( unsigned int row ) const
height = wxMax( height, renderer->GetSize().y );
}
m_rowHeightCache->Put(row, height);
return height;
}
else
@@ -3602,6 +3677,13 @@ void wxDataViewMainWindow::Expand( unsigned int row )
if (!node->HasChildren())
return;
if (GetOwner()->HasFlag(wxDV_VARIABLE_LINE_HEIGHT))
{
// Expand makes new rows visible thus we invalidates all following
// rows in the height cache
m_rowHeightCache->Remove(row);
}
if (!node->IsOpen())
{
if ( !SendExpanderEvent(wxEVT_DATAVIEW_ITEM_EXPANDING, node->GetItem()) )
@@ -3651,6 +3733,13 @@ void wxDataViewMainWindow::Collapse(unsigned int row)
if (!node->HasChildren())
return;
if (GetOwner()->HasFlag(wxDV_VARIABLE_LINE_HEIGHT))
{
// Collapse hides rows thus we invalidates all following
// rows in the height cache
m_rowHeightCache->Remove(row);
}
if (node->IsOpen())
{
if ( !SendExpanderEvent(wxEVT_DATAVIEW_ITEM_COLLAPSING,node->GetItem()) )

View File

@@ -0,0 +1,337 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/private/rowheightcache.h
// Purpose: height cache of rows in a dataview
// Author: Jens Goepfert (mail@jensgoepfert.de)
// Created: 2018-03-06
// Copyright: (c) wxWidgets team
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
// ============================================================================
// declarations
// ============================================================================
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
// for compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/log.h"
#endif // WX_PRECOMP
#include "wx/generic/private/rowheightcache.h"
// ----------------------------------------------------------------------------
// private structs
// ----------------------------------------------------------------------------
// ============================================================================
// implementation
// ============================================================================
// ----------------------------------------------------------------------------
// RowRanges
// ----------------------------------------------------------------------------
void RowRanges::Add(const unsigned int row)
{
size_t count = m_ranges.size();
size_t rngIdx = 0;
for (rngIdx = 0; rngIdx < count; ++rngIdx)
{
RowRange &rng = m_ranges[rngIdx];
if (row >= rng.from && rng.to > row)
{
// index already in range
return;
}
if (row == rng.from - 1)
{
// extend range at the beginning (to the left)
rng.from = row;
// no cleanup necessary
return;
}
if (row == rng.to)
{
// extend range at the end (set to row+1 because 'to' is not including)
rng.to = row + 1;
CleanUp(rngIdx);
return;
}
if (rng.from > row + 1)
{
// this range is already behind row index, so break here and insert a new range before
break;
}
}
// wxLogMessage("New Range: %d" , count);
RowRange newRange;
newRange.from = row;
newRange.to = row + 1;
m_ranges.insert(m_ranges.begin() + rngIdx, newRange);
}
void RowRanges::Remove(const unsigned int row)
{
size_t count = m_ranges.size();
size_t rngIdx = 0;
while (rngIdx < count)
{
RowRange &rng = m_ranges[rngIdx];
if (rng.from >= row)
{
// this range starts behind row index, so remove it
m_ranges.erase(m_ranges.begin() + rngIdx);
count--;
continue;
}
if (rng.to > row)
{
// this ranges includes row, so cut off at row index to exclude row
rng.to = row;
}
rngIdx += 1;
}
}
void RowRanges::CleanUp(unsigned int idx)
{
size_t count = m_ranges.size();
size_t rngIdx = 0;
if (idx > 0)
{
// start one RowRange before
rngIdx = idx - 1;
}
if (idx >= count)
{
// should never reached, due CleanUp is private and internal called correctly
return;
}
RowRange *prevRng = &m_ranges[rngIdx];
rngIdx++;
while (rngIdx <= idx + 1 && rngIdx < count)
{
RowRange &rng = m_ranges[rngIdx];
if (prevRng->to == rng.from)
{
// this range starts where the previous range began, so remove this
// and set the to-value of the previous range to the to-value of this range
prevRng->to = rng.to;
m_ranges.erase(m_ranges.begin() + rngIdx);
count--;
continue;
}
prevRng = &rng;
rngIdx += 1;
}
}
bool RowRanges::Has(unsigned int row) const
{
size_t count = m_ranges.size();
for (size_t rngIdx = 0; rngIdx < count; rngIdx++)
{
const RowRange &rng = m_ranges[rngIdx];
if (rng.from <= row && row < rng.to)
{
return true;
}
}
return false;
}
unsigned int RowRanges::CountAll() const
{
unsigned int ctr = 0;
size_t count = m_ranges.size();
for (size_t rngIdx = 0; rngIdx < count; rngIdx++)
{
const RowRange &rng = m_ranges[rngIdx];
ctr += rng.to - rng.from;
}
return ctr;
}
unsigned int RowRanges::CountTo(unsigned int row) const
{
unsigned int ctr = 0;
size_t count = m_ranges.size();
for (size_t rngIdx = 0; rngIdx < count; rngIdx++)
{
const RowRange &rng = m_ranges[rngIdx];
if (rng.from > row)
{
break;
}
else if (rng.to < row)
{
ctr += rng.to - rng.from;
}
else
{
ctr += row - rng.from;
break;
}
}
return ctr;
}
unsigned int RowRanges::GetSize() const // for debugging statistics
{
return m_ranges.size();
}
// ----------------------------------------------------------------------------
// HeightCache
// ----------------------------------------------------------------------------
bool HeightCache::GetLineInfo(unsigned int row, int &start, int &height)
{
int y = 0;
bool found = false;
HeightToRowRangesMap::iterator it;
for (it = m_heightToRowRange.begin(); it != m_heightToRowRange.end(); ++it)
{
int rowHeight = it->first;
RowRanges* rowRanges = it->second;
if (rowRanges->Has(row))
{
height = rowHeight;
found = true;
}
y += rowHeight * (rowRanges->CountTo(row));
}
if (found)
{
start = y;
}
return found;
}
bool HeightCache::GetLineStart(unsigned int row, int &start)
{
int height = 0;
return GetLineInfo(row, start, height);
}
bool HeightCache::GetLineHeight(unsigned int row, int &height)
{
HeightToRowRangesMap::iterator it;
for (it = m_heightToRowRange.begin(); it != m_heightToRowRange.end(); ++it)
{
int rowHeight = it->first;
RowRanges* rowRanges = it->second;
if (rowRanges->Has(row))
{
height = rowHeight;
return true;
}
}
return false;
}
bool HeightCache::GetLineAt(int y, unsigned int &row)
{
unsigned int total = 0;
HeightToRowRangesMap::iterator it;
for (it = m_heightToRowRange.begin(); it != m_heightToRowRange.end(); ++it)
{
RowRanges* rowRanges = it->second;
total += rowRanges->CountAll();
}
if (total == 0)
{
return false;
}
int lo = 0;
int hi = total;
int start, height;
while (lo < hi)
{
int mid = (lo + hi) / 2;
if (GetLineInfo(mid, start, height))
{
if (start + height <= y)
{
lo = mid + 1;
}
else
{
hi = mid;
}
}
else
{
// should never happen, except the HeightCache has gaps which is an invalid state
return false;
}
}
if (GetLineInfo(lo, start, height))
{
if (y < start)
{
// given y point is before the first row
return false;
}
row = lo;
return true;
}
else
{
// given y point is after the last row
return false;
}
}
void HeightCache::Put(const unsigned int row, const int height)
{
RowRanges *rowRanges = m_heightToRowRange[height];
if (rowRanges == NULL)
{
rowRanges = new RowRanges();
m_heightToRowRange[height] = rowRanges;
}
rowRanges->Add(row);
}
void HeightCache::Remove(const unsigned int row)
{
HeightToRowRangesMap::iterator it;
for (it = m_heightToRowRange.begin(); it != m_heightToRowRange.end(); ++it)
{
RowRanges* rowRanges = it->second;
rowRanges->Remove(row);
}
}
void HeightCache::Clear()
{
HeightToRowRangesMap::iterator it;
for (it = m_heightToRowRange.begin(); it != m_heightToRowRange.end(); ++it)
{
RowRanges* rowRanges = it->second;
delete rowRanges;
}
m_heightToRowRange.clear();
}

View File

@@ -254,6 +254,7 @@ TEST_GUI_OBJECTS = \
test_gui_socket.o \
test_gui_tlw.o \
test_gui_dataview.o \
test_gui_rowheightcachetest.o \
test_gui_boxsizer.o \
test_gui_gridsizer.o \
test_gui_wrapsizer.o \
@@ -1030,6 +1031,9 @@ test_gui_tlw.o: $(srcdir)/persistence/tlw.cpp $(TEST_GUI_ODEP)
test_gui_dataview.o: $(srcdir)/persistence/dataview.cpp $(TEST_GUI_ODEP)
$(CXXC) -c -o $@ $(TEST_GUI_CXXFLAGS) $(srcdir)/persistence/dataview.cpp
test_gui_rowheightcachetest.o: $(srcdir)/rowheightcache/rowheightcachetest.cpp $(TEST_GUI_ODEP)
$(CXXC) -c -o $@ $(TEST_GUI_CXXFLAGS) $(srcdir)/rowheightcache/rowheightcachetest.cpp
test_gui_boxsizer.o: $(srcdir)/sizers/boxsizer.cpp $(TEST_GUI_ODEP)
$(CXXC) -c -o $@ $(TEST_GUI_CXXFLAGS) $(srcdir)/sizers/boxsizer.cpp

View File

@@ -241,6 +241,7 @@ TEST_GUI_OBJECTS = \
$(OBJS)\test_gui_socket.obj \
$(OBJS)\test_gui_tlw.obj \
$(OBJS)\test_gui_dataview.obj \
$(OBJS)\test_gui_rowheightcachetest.obj \
$(OBJS)\test_gui_boxsizer.obj \
$(OBJS)\test_gui_gridsizer.obj \
$(OBJS)\test_gui_wrapsizer.obj \
@@ -1084,6 +1085,9 @@ $(OBJS)\test_gui_tlw.obj: .\persistence\tlw.cpp
$(OBJS)\test_gui_dataview.obj: .\persistence\dataview.cpp
$(CXX) -q -c -P -o$@ $(TEST_GUI_CXXFLAGS) .\persistence\dataview.cpp
$(OBJS)\test_gui_rowheightcachetest.obj: .\rowheightcache\rowheightcachetest.cpp
$(CXX) -q -c -P -o$@ $(TEST_GUI_CXXFLAGS) .\rowheightcache\rowheightcachetest.cpp
$(OBJS)\test_gui_boxsizer.obj: .\sizers\boxsizer.cpp
$(CXX) -q -c -P -o$@ $(TEST_GUI_CXXFLAGS) .\sizers\boxsizer.cpp

View File

@@ -236,6 +236,7 @@ TEST_GUI_OBJECTS = \
$(OBJS)\test_gui_socket.o \
$(OBJS)\test_gui_tlw.o \
$(OBJS)\test_gui_dataview.o \
$(OBJS)\test_gui_rowheightcachetest.o \
$(OBJS)\test_gui_boxsizer.o \
$(OBJS)\test_gui_gridsizer.o \
$(OBJS)\test_gui_wrapsizer.o \
@@ -1061,6 +1062,9 @@ $(OBJS)\test_gui_tlw.o: ./persistence/tlw.cpp
$(OBJS)\test_gui_dataview.o: ./persistence/dataview.cpp
$(CXX) -c -o $@ $(TEST_GUI_CXXFLAGS) $(CPPDEPS) $<
$(OBJS)\test_gui_rowheightcachetest.o: ./rowheightcache/rowheightcachetest.cpp
$(CXX) -c -o $@ $(TEST_GUI_CXXFLAGS) $(CPPDEPS) $<
$(OBJS)\test_gui_boxsizer.o: ./sizers/boxsizer.cpp
$(CXX) -c -o $@ $(TEST_GUI_CXXFLAGS) $(CPPDEPS) $<

View File

@@ -247,6 +247,7 @@ TEST_GUI_OBJECTS = \
$(OBJS)\test_gui_socket.obj \
$(OBJS)\test_gui_tlw.obj \
$(OBJS)\test_gui_dataview.obj \
$(OBJS)\test_gui_rowheightcachetest.obj \
$(OBJS)\test_gui_boxsizer.obj \
$(OBJS)\test_gui_gridsizer.obj \
$(OBJS)\test_gui_wrapsizer.obj \
@@ -1275,6 +1276,9 @@ $(OBJS)\test_gui_tlw.obj: .\persistence\tlw.cpp
$(OBJS)\test_gui_dataview.obj: .\persistence\dataview.cpp
$(CXX) /c /nologo /TP /Fo$@ $(TEST_GUI_CXXFLAGS) .\persistence\dataview.cpp
$(OBJS)\test_gui_rowheightcachetest.obj: .\rowheightcache\rowheightcachetest.cpp
$(CXX) /c /nologo /TP /Fo$@ $(TEST_GUI_CXXFLAGS) .\rowheightcache\rowheightcachetest.cpp
$(OBJS)\test_gui_boxsizer.obj: .\sizers\boxsizer.cpp
$(CXX) /c /nologo /TP /Fo$@ $(TEST_GUI_CXXFLAGS) .\sizers\boxsizer.cpp

View File

@@ -0,0 +1,280 @@
///////////////////////////////////////////////////////////////////////////////
// Name: tests/rowheightcache/rowheightcachetest.cpp
// Purpose: unit tests for the row height cache of a dataview
// Author: Jens Goepfert (mail@jensgoepfert.de)
// Created: 2018-03-06
// Copyright: (c) wxWidgets team
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
#include "testprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#endif
#include "wx/generic/private/rowheightcache.h"
// ----------------------------------------------------------------------------
// local functions
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// TestRowRangesAdd
// ----------------------------------------------------------------------------
TEST_CASE("RowHeightCacheTestCase::TestRowRangesSimple", "[dataview][heightcache]")
{
RowRanges *rr = new RowRanges();
CHECK(rr->CountAll() == 0);
for (unsigned int i = 0; i <= 10; i++)
{
CHECK(rr->Has(i) == false);
rr->Add(i);
CHECK(rr->CountAll() == i+1);
CHECK(rr->CountTo(i) == i);
CHECK(rr->Has(i) == true);
}
CHECK(rr->GetSize() == 1); // every row is sorted in the same range, so count == 1
CHECK(rr->CountAll() == 11); // 11 rows collected
CHECK(rr->CountTo(10) == 10);
rr->Add(5); // row 5 already contained -> does nothing
CHECK(rr->GetSize() == 1); // every row is sorted in the same range, so count == 1
CHECK(rr->CountAll() == 11); // 11 rows collected
CHECK(rr->CountTo(10) == 10);
for (int i = 10; i >= 0; i--)
{
CHECK(rr->CountAll() == (unsigned)i+1);
CHECK(rr->CountTo((unsigned)i) == (unsigned)i);
rr->Remove(i);
CHECK(rr->CountAll() == (unsigned)i);
CHECK(rr->CountTo((unsigned)i) == (unsigned)i);
}
CHECK(rr->CountAll() == 0); // everything removed, no row range is left behind
for (int i = 10; i > 0; i--)
{
CHECK(rr->CountTo(i) == 0);
}
CHECK(rr->GetSize() == 0);
}
// ----------------------------------------------------------------------------
// TestRowRangesRemove
// ----------------------------------------------------------------------------
TEST_CASE("RowHeightCacheTestCase::TestRowRangesGapsMod2", "[dataview][heightcache]")
{
RowRanges *rr = new RowRanges();
for (int i = 0; i < 100; i++)
{
CHECK(rr->Has(i) == false);
if (i % 2 == 0)
{
rr->Add(i);
}
}
CHECK(rr->CountAll() == 50);
CHECK(rr->CountTo(100) == 50);
for (unsigned int i = 99; i > 0; i--)
{
if (i % 2 == 0)
{
CHECK(rr->Has(i) == true);
rr->Remove(i);
CHECK(rr->Has(i) == false);
}
else
{
CHECK(rr->Has(i) == false);
}
}
// only row 0 is in the RowRanges, so remove 1 does nothing
rr->Remove(1);
CHECK(rr->CountAll() == 1);
CHECK(rr->CountTo(0) == 0);
CHECK(rr->CountTo(1) == 1);
CHECK(rr->CountTo(100) == 1);
CHECK(rr->GetSize() == 1);
rr->Remove(0); // last row is beeing removed
CHECK(rr->CountAll() == 0);
CHECK(rr->CountTo(0) == 0);
CHECK(rr->CountTo(1) == 0);
CHECK(rr->CountTo(100) == 0);
CHECK(rr->GetSize() == 0);
rr->Add(10);
CHECK(rr->GetSize() == 1);
CHECK(rr->CountTo(1) == 0); // tests CountTo first break
rr->Add(5); // inserts a range at the beginning
CHECK(rr->GetSize() == 2);
rr->Remove(10);
rr->Remove(5);
CHECK(rr->GetSize() == 0);
}
// ----------------------------------------------------------------------------
// TestRowRangesCleanUp1
// ----------------------------------------------------------------------------
TEST_CASE("RowHeightCacheTestCase::TestRowRangesCleanUp1", "[dataview][heightcache]")
{
RowRanges *rr = new RowRanges();
for (unsigned int i = 0; i < 100; i++)
{
CHECK(rr->Has(i) == false);
if (i % 2 == 0)
{
rr->Add(i);
}
}
CHECK(rr->GetSize() == 50); // adding 50 rows (only even) results in 50 range objects
CHECK(rr->CountAll() == 50);
CHECK(rr->CountTo(100) == 50);
for (unsigned int i = 0; i < 100; i++)
{
if (i % 2 == 1)
{
rr->Add(i);
}
}
CHECK(rr->GetSize() == 1); // adding 50 rows (only odd) should combined to 1 range object
CHECK(rr->CountAll() == 100);
CHECK(rr->CountTo(100) == 100);
}
// ----------------------------------------------------------------------------
// TestRowRangesCleanUp2
// ----------------------------------------------------------------------------
TEST_CASE("RowHeightCacheTestCase::TestRowRangesCleanUp2", "[dataview][heightcache]")
{
RowRanges *rr = new RowRanges();
for (unsigned int i = 0; i < 10; i++)
{
rr->Add(i);
}
CHECK(rr->GetSize() == 1); // adding 10 sequent rows results in 1 range objects
CHECK(rr->CountAll() == 10);
CHECK(rr->CountTo(100) == 10);
for (unsigned int i = 12; i < 20; i++)
{
rr->Add(i);
}
CHECK(rr->GetSize() == 2);
rr->Add(11); // tests extending a range at the beginning (to the left)
CHECK(rr->GetSize() == 2);
rr->Add(10); // extends a range and reduces them
CHECK(rr->GetSize() == 1);
}
// ----------------------------------------------------------------------------
// TestHeightCache
// ----------------------------------------------------------------------------
TEST_CASE("RowHeightCacheTestCase::TestHeightCache", "[dataview][heightcache]")
{
HeightCache *hc = new HeightCache();
for (unsigned int i = 0; i <= 10; i++)
{
hc->Put(i, 22);
}
for (unsigned int i = 15; i <= 17; i++)
{
hc->Put(i, 22);
}
for (unsigned int i = 20; i <= 2000; i++)
{
hc->Put(i, 22);
}
hc->Put(11, 42);
hc->Put(12, 42);
hc->Put(18, 42);
hc->Put(13, 62);
hc->Put(14, 62);
hc->Put(19, 62);
int start = 0;
int height = 0;
unsigned int row = 666;
CHECK(hc->GetLineStart(1000, start) == true);
CHECK(start == 22180);
CHECK(hc->GetLineHeight(1000, height) == true);
CHECK(height == 22);
CHECK(hc->GetLineHeight(5000, start) == false);
// test invalid y
CHECK(hc->GetLineAt(-1, row) == false);
CHECK(row == 666);
// test start of first row
CHECK(hc->GetLineAt(0, row) == true);
CHECK(row == 0);
// test end of first row
CHECK(hc->GetLineAt(21, row) == true);
CHECK(row == 0);
// test start of second row
CHECK(hc->GetLineAt(22, row) == true);
CHECK(row == 1);
hc->Remove(1000); // Delete row 1000 and everything behind
CHECK(hc->GetLineAt(22179, row) == true);
CHECK(row == 999);
CHECK(hc->GetLineHeight(999, height) == true);
CHECK(height == 22);
row = 666;
height = 666;
CHECK(hc->GetLineAt(22180, row) == false);
CHECK(row == 666);
CHECK(hc->GetLineHeight(1000, height) == false);
CHECK(height == 666);
hc->Clear(); // Clear all items
for (int i = 20; i <= 2000; i++)
{
height = 666;
CHECK(hc->GetLineHeight(i, height) == false);
CHECK(height == 666);
}
hc->Clear(); // Clear twice should not crash
row = 666;
height = 666;
CHECK(hc->GetLineAt(22180, row) == false);
CHECK(row == 666);
}

View File

@@ -266,6 +266,7 @@
net/socket.cpp
persistence/tlw.cpp
persistence/dataview.cpp
rowheightcache/rowheightcachetest.cpp
sizers/boxsizer.cpp
sizers/gridsizer.cpp
sizers/wrapsizer.cpp

View File

@@ -523,6 +523,9 @@
<File
RelativePath=".\controls\richtextctrltest.cpp">
</File>
<File
RelativePath=".\rowheightcache\rowheightcachetest.cpp">
</File>
<File
RelativePath=".\misc\safearrayconverttest.cpp">
</File>

View File

@@ -1166,6 +1166,10 @@
RelativePath=".\controls\richtextctrltest.cpp"
>
</File>
<File
RelativePath=".\rowheightcache\rowheightcachetest.cpp"
>
</File>
<File
RelativePath=".\misc\safearrayconverttest.cpp"
>

View File

@@ -1138,6 +1138,10 @@
RelativePath=".\controls\richtextctrltest.cpp"
>
</File>
<File
RelativePath=".\rowheightcache\rowheightcachetest.cpp"
>
</File>
<File
RelativePath=".\misc\safearrayconverttest.cpp"
>