From 29efc6e4a478652d6f59fb3f5ca7990d78a8ead4 Mon Sep 17 00:00:00 2001 From: Francesco Montorsi Date: Sun, 11 Jan 2009 15:49:37 +0000 Subject: [PATCH] split wxGrid implementation in grideditors.cpp (for wxGridCellEditor-derived classes), gridctrl.cpp (for wxGridCellRenderer-derived classes) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@58024 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- Makefile.in | 87 +- build/bakefiles/files.bkl | 2 + build/msw/makefile.bcc | 24 + build/msw/makefile.gcc | 24 + build/msw/makefile.vc | 24 + build/msw/makefile.wat | 24 + build/msw/wx_adv.dsp | 8 + build/msw/wx_core.dsp | 4 + build/msw/wx_vc7_adv.vcproj | 6 + build/msw/wx_vc7_core.vcproj | 3 + build/msw/wx_vc8_adv.vcproj | 8 + build/msw/wx_vc8_core.vcproj | 4 + build/msw/wx_vc9_adv.vcproj | 8 + build/msw/wx_vc9_core.vcproj | 4 + include/wx/generic/grid.h | 365 +--- include/wx/generic/gridctrl.h | 161 +- include/wx/generic/grideditors.h | 328 +++ include/wx/generic/private/grid.h | 826 ++++++++ src/generic/grid.cpp | 3246 +++-------------------------- src/generic/gridctrl.cpp | 593 +++++- src/generic/grideditors.cpp | 1524 ++++++++++++++ 21 files changed, 3781 insertions(+), 3492 deletions(-) create mode 100644 include/wx/generic/grideditors.h create mode 100644 include/wx/generic/private/grid.h create mode 100644 src/generic/grideditors.cpp diff --git a/Makefile.in b/Makefile.in index 78b0864850..d76fea5668 100644 --- a/Makefile.in +++ b/Makefile.in @@ -27,6 +27,7 @@ STRIP = @STRIP@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_DIR = @INSTALL_DIR@ +ICC_PCH_USE_SWITCH = @ICC_PCH_USE_SWITCH@ BK_DEPS = @BK_DEPS@ BK_MAKE_PCH = @BK_MAKE_PCH@ srcdir = @srcdir@ @@ -3453,6 +3454,7 @@ COND_WXUNIV_0_ADVANCED_HDR = \ wx/generic/dataview.h \ wx/generic/grid.h \ wx/generic/gridctrl.h \ + wx/generic/grideditors.h \ wx/generic/gridsel.h \ wx/generic/helpext.h \ wx/generic/hyperlink.h \ @@ -3495,6 +3497,7 @@ COND_WXUNIV_1_ADVANCED_HDR = \ wx/generic/dataview.h \ wx/generic/grid.h \ wx/generic/gridctrl.h \ + wx/generic/grideditors.h \ wx/generic/gridsel.h \ wx/generic/helpext.h \ wx/generic/hyperlink.h \ @@ -3910,7 +3913,7 @@ COND_WINDOWS_IMPLIB_1___monodll___importlib = \ -Wl,--out-implib=$(LIBDIRNAME)/$(LIBPREFIX)wx_$(PORTNAME)$(WXUNIVNAME)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)-$(WX_RELEASE)$(HOST_SUFFIX).$(DLLIMP_SUFFIX) @COND_WINDOWS_IMPLIB_1@__monodll___importlib = $(COND_WINDOWS_IMPLIB_1___monodll___importlib) @COND_GCC_PCH_1@__monodll_PCH_INC = -I./.pch/wxprec_monodll -@COND_ICC_PCH_1@__monodll_PCH_INC = -use_pch \ +@COND_ICC_PCH_1@__monodll_PCH_INC = $(ICC_PCH_USE_SWITCH) \ @COND_ICC_PCH_1@ ./.pch/wxprec_monodll/wx/wxprec.h.gch @COND_USE_PCH_1@_____pch_wxprec_monodll_wx_wxprec_h_gch___depname \ @COND_USE_PCH_1@ = ./.pch/wxprec_monodll/wx/wxprec.h.gch @@ -5650,6 +5653,7 @@ COND_WXUNIV_0___ADVANCED_SRC_OBJECTS = \ monodll_editlbox.o \ monodll_grid.o \ monodll_gridctrl.o \ + monodll_grideditors.o \ monodll_gridsel.o \ monodll_helpext.o \ monodll_hyperlinkg.o \ @@ -5678,6 +5682,7 @@ COND_WXUNIV_1___ADVANCED_SRC_OBJECTS = \ monodll_editlbox.o \ monodll_grid.o \ monodll_gridctrl.o \ + monodll_grideditors.o \ monodll_gridsel.o \ monodll_helpext.o \ monodll_hyperlinkg.o \ @@ -5750,7 +5755,7 @@ COND_MONOLITHIC_1_SHARED_0___monolib___depname = \ @COND_MONOLITHIC_1_SHARED_0@__uninstall_monolib___depname \ @COND_MONOLITHIC_1_SHARED_0@ = uninstall_monolib @COND_GCC_PCH_1@__monolib_PCH_INC = -I./.pch/wxprec_monolib -@COND_ICC_PCH_1@__monolib_PCH_INC = -use_pch \ +@COND_ICC_PCH_1@__monolib_PCH_INC = $(ICC_PCH_USE_SWITCH) \ @COND_ICC_PCH_1@ ./.pch/wxprec_monolib/wx/wxprec.h.gch @COND_USE_PCH_1@_____pch_wxprec_monolib_wx_wxprec_h_gch___depname \ @COND_USE_PCH_1@ = ./.pch/wxprec_monolib/wx/wxprec.h.gch @@ -7460,6 +7465,7 @@ COND_WXUNIV_0___ADVANCED_SRC_OBJECTS_1 = \ monolib_editlbox.o \ monolib_grid.o \ monolib_gridctrl.o \ + monolib_grideditors.o \ monolib_gridsel.o \ monolib_helpext.o \ monolib_hyperlinkg.o \ @@ -7488,6 +7494,7 @@ COND_WXUNIV_1___ADVANCED_SRC_OBJECTS_1 = \ monolib_editlbox.o \ monolib_grid.o \ monolib_gridctrl.o \ + monolib_grideditors.o \ monolib_gridsel.o \ monolib_helpext.o \ monolib_hyperlinkg.o \ @@ -7566,7 +7573,7 @@ COND_WINDOWS_IMPLIB_1___basedll___importlib = \ -Wl,--out-implib=$(LIBDIRNAME)/$(LIBPREFIX)wx_base$(WXBASEPORT)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)-$(WX_RELEASE)$(HOST_SUFFIX).$(DLLIMP_SUFFIX) @COND_WINDOWS_IMPLIB_1@__basedll___importlib = $(COND_WINDOWS_IMPLIB_1___basedll___importlib) @COND_GCC_PCH_1@__basedll_PCH_INC = -I./.pch/wxprec_basedll -@COND_ICC_PCH_1@__basedll_PCH_INC = -use_pch \ +@COND_ICC_PCH_1@__basedll_PCH_INC = $(ICC_PCH_USE_SWITCH) \ @COND_ICC_PCH_1@ ./.pch/wxprec_basedll/wx/wxprec.h.gch @COND_USE_PCH_1@_____pch_wxprec_basedll_wx_wxprec_h_gch___depname \ @COND_USE_PCH_1@ = ./.pch/wxprec_basedll/wx/wxprec.h.gch @@ -7689,7 +7696,7 @@ COND_MONOLITHIC_0_SHARED_0___baselib___depname = \ @COND_MONOLITHIC_0_SHARED_0@__uninstall_baselib___depname \ @COND_MONOLITHIC_0_SHARED_0@ = uninstall_baselib @COND_GCC_PCH_1@__baselib_PCH_INC = -I./.pch/wxprec_baselib -@COND_ICC_PCH_1@__baselib_PCH_INC = -use_pch \ +@COND_ICC_PCH_1@__baselib_PCH_INC = $(ICC_PCH_USE_SWITCH) \ @COND_ICC_PCH_1@ ./.pch/wxprec_baselib/wx/wxprec.h.gch @COND_USE_PCH_1@_____pch_wxprec_baselib_wx_wxprec_h_gch___depname \ @COND_USE_PCH_1@ = ./.pch/wxprec_baselib/wx/wxprec.h.gch @@ -7791,7 +7798,7 @@ COND_WINDOWS_IMPLIB_1___netdll___importlib = \ -Wl,--out-implib=$(LIBDIRNAME)/$(LIBPREFIX)wx_base$(WXBASEPORT)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_net-$(WX_RELEASE)$(HOST_SUFFIX).$(DLLIMP_SUFFIX) @COND_WINDOWS_IMPLIB_1@__netdll___importlib = $(COND_WINDOWS_IMPLIB_1___netdll___importlib) @COND_GCC_PCH_1@__netdll_PCH_INC = -I./.pch/wxprec_netdll -@COND_ICC_PCH_1@__netdll_PCH_INC = -use_pch \ +@COND_ICC_PCH_1@__netdll_PCH_INC = $(ICC_PCH_USE_SWITCH) \ @COND_ICC_PCH_1@ ./.pch/wxprec_netdll/wx/wxprec.h.gch @COND_USE_PCH_1@_____pch_wxprec_netdll_wx_wxprec_h_gch___depname \ @COND_USE_PCH_1@ = ./.pch/wxprec_netdll/wx/wxprec.h.gch @@ -7842,7 +7849,7 @@ COND_MONOLITHIC_0_SHARED_0___netlib___depname = \ @COND_MONOLITHIC_0_SHARED_0@__install_netlib___depname = install_netlib @COND_MONOLITHIC_0_SHARED_0@__uninstall_netlib___depname = uninstall_netlib @COND_GCC_PCH_1@__netlib_PCH_INC = -I./.pch/wxprec_netlib -@COND_ICC_PCH_1@__netlib_PCH_INC = -use_pch \ +@COND_ICC_PCH_1@__netlib_PCH_INC = $(ICC_PCH_USE_SWITCH) \ @COND_ICC_PCH_1@ ./.pch/wxprec_netlib/wx/wxprec.h.gch @COND_USE_PCH_1@_____pch_wxprec_netlib_wx_wxprec_h_gch___depname \ @COND_USE_PCH_1@ = ./.pch/wxprec_netlib/wx/wxprec.h.gch @@ -7875,7 +7882,7 @@ COND_WINDOWS_IMPLIB_1___coredll___importlib = \ -Wl,--out-implib=$(LIBDIRNAME)/$(LIBPREFIX)wx_$(PORTNAME)$(WXUNIVNAME)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_core-$(WX_RELEASE)$(HOST_SUFFIX).$(DLLIMP_SUFFIX) @COND_WINDOWS_IMPLIB_1@__coredll___importlib = $(COND_WINDOWS_IMPLIB_1___coredll___importlib) @COND_GCC_PCH_1@__coredll_PCH_INC = -I./.pch/wxprec_coredll -@COND_ICC_PCH_1@__coredll_PCH_INC = -use_pch \ +@COND_ICC_PCH_1@__coredll_PCH_INC = $(ICC_PCH_USE_SWITCH) \ @COND_ICC_PCH_1@ ./.pch/wxprec_coredll/wx/wxprec.h.gch @COND_USE_PCH_1@_____pch_wxprec_coredll_wx_wxprec_h_gch___depname \ @COND_USE_PCH_1@ = ./.pch/wxprec_coredll/wx/wxprec.h.gch @@ -9411,7 +9418,7 @@ COND_MONOLITHIC_0_SHARED_0_USE_GUI_1___corelib___depname = \ @COND_MONOLITHIC_0_SHARED_0_USE_GUI_1@__uninstall_corelib___depname \ @COND_MONOLITHIC_0_SHARED_0_USE_GUI_1@ = uninstall_corelib @COND_GCC_PCH_1@__corelib_PCH_INC = -I./.pch/wxprec_corelib -@COND_ICC_PCH_1@__corelib_PCH_INC = -use_pch \ +@COND_ICC_PCH_1@__corelib_PCH_INC = $(ICC_PCH_USE_SWITCH) \ @COND_ICC_PCH_1@ ./.pch/wxprec_corelib/wx/wxprec.h.gch @COND_USE_PCH_1@_____pch_wxprec_corelib_wx_wxprec_h_gch___depname \ @COND_USE_PCH_1@ = ./.pch/wxprec_corelib/wx/wxprec.h.gch @@ -10927,7 +10934,7 @@ COND_WINDOWS_IMPLIB_1___advdll___importlib = \ -Wl,--out-implib=$(LIBDIRNAME)/$(LIBPREFIX)wx_$(PORTNAME)$(WXUNIVNAME)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_adv-$(WX_RELEASE)$(HOST_SUFFIX).$(DLLIMP_SUFFIX) @COND_WINDOWS_IMPLIB_1@__advdll___importlib = $(COND_WINDOWS_IMPLIB_1___advdll___importlib) @COND_GCC_PCH_1@__advdll_PCH_INC = -I./.pch/wxprec_advdll -@COND_ICC_PCH_1@__advdll_PCH_INC = -use_pch \ +@COND_ICC_PCH_1@__advdll_PCH_INC = $(ICC_PCH_USE_SWITCH) \ @COND_ICC_PCH_1@ ./.pch/wxprec_advdll/wx/wxprec.h.gch @COND_USE_PCH_1@_____pch_wxprec_advdll_wx_wxprec_h_gch___depname \ @COND_USE_PCH_1@ = ./.pch/wxprec_advdll/wx/wxprec.h.gch @@ -10976,6 +10983,7 @@ COND_WXUNIV_0___ADVANCED_SRC_OBJECTS_2 = \ advdll_editlbox.o \ advdll_grid.o \ advdll_gridctrl.o \ + advdll_grideditors.o \ advdll_gridsel.o \ advdll_helpext.o \ advdll_hyperlinkg.o \ @@ -11004,6 +11012,7 @@ COND_WXUNIV_1___ADVANCED_SRC_OBJECTS_2 = \ advdll_editlbox.o \ advdll_grid.o \ advdll_gridctrl.o \ + advdll_grideditors.o \ advdll_gridsel.o \ advdll_helpext.o \ advdll_hyperlinkg.o \ @@ -11048,7 +11057,7 @@ COND_MONOLITHIC_0_SHARED_0_USE_GUI_1___advlib___depname = \ @COND_MONOLITHIC_0_SHARED_0_USE_GUI_1@__uninstall_advlib___depname \ @COND_MONOLITHIC_0_SHARED_0_USE_GUI_1@ = uninstall_advlib @COND_GCC_PCH_1@__advlib_PCH_INC = -I./.pch/wxprec_advlib -@COND_ICC_PCH_1@__advlib_PCH_INC = -use_pch \ +@COND_ICC_PCH_1@__advlib_PCH_INC = $(ICC_PCH_USE_SWITCH) \ @COND_ICC_PCH_1@ ./.pch/wxprec_advlib/wx/wxprec.h.gch @COND_USE_PCH_1@_____pch_wxprec_advlib_wx_wxprec_h_gch___depname \ @COND_USE_PCH_1@ = ./.pch/wxprec_advlib/wx/wxprec.h.gch @@ -11066,6 +11075,7 @@ COND_WXUNIV_0___ADVANCED_SRC_OBJECTS_3 = \ advlib_editlbox.o \ advlib_grid.o \ advlib_gridctrl.o \ + advlib_grideditors.o \ advlib_gridsel.o \ advlib_helpext.o \ advlib_hyperlinkg.o \ @@ -11094,6 +11104,7 @@ COND_WXUNIV_1___ADVANCED_SRC_OBJECTS_3 = \ advlib_editlbox.o \ advlib_grid.o \ advlib_gridctrl.o \ + advlib_grideditors.o \ advlib_gridsel.o \ advlib_helpext.o \ advlib_hyperlinkg.o \ @@ -11149,7 +11160,7 @@ COND_WINDOWS_IMPLIB_1___mediadll___importlib = \ -Wl,--out-implib=$(LIBDIRNAME)/$(LIBPREFIX)wx_$(PORTNAME)$(WXUNIVNAME)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_media-$(WX_RELEASE)$(HOST_SUFFIX).$(DLLIMP_SUFFIX) @COND_WINDOWS_IMPLIB_1@__mediadll___importlib = $(COND_WINDOWS_IMPLIB_1___mediadll___importlib) @COND_GCC_PCH_1@__mediadll_PCH_INC = -I./.pch/wxprec_mediadll -@COND_ICC_PCH_1@__mediadll_PCH_INC = -use_pch \ +@COND_ICC_PCH_1@__mediadll_PCH_INC = $(ICC_PCH_USE_SWITCH) \ @COND_ICC_PCH_1@ ./.pch/wxprec_mediadll/wx/wxprec.h.gch @COND_USE_PCH_1@_____pch_wxprec_mediadll_wx_wxprec_h_gch___depname \ @COND_USE_PCH_1@ = ./.pch/wxprec_mediadll/wx/wxprec.h.gch @@ -11216,7 +11227,7 @@ COND_MONOLITHIC_0_SHARED_0_USE_GUI_1_USE_MEDIA_1___medialib___depname = \ @COND_MONOLITHIC_0_SHARED_0_USE_GUI_1_USE_MEDIA_1@__uninstall_medialib___depname \ @COND_MONOLITHIC_0_SHARED_0_USE_GUI_1_USE_MEDIA_1@ = uninstall_medialib @COND_GCC_PCH_1@__medialib_PCH_INC = -I./.pch/wxprec_medialib -@COND_ICC_PCH_1@__medialib_PCH_INC = -use_pch \ +@COND_ICC_PCH_1@__medialib_PCH_INC = $(ICC_PCH_USE_SWITCH) \ @COND_ICC_PCH_1@ ./.pch/wxprec_medialib/wx/wxprec.h.gch @COND_USE_PCH_1@_____pch_wxprec_medialib_wx_wxprec_h_gch___depname \ @COND_USE_PCH_1@ = ./.pch/wxprec_medialib/wx/wxprec.h.gch @@ -11263,7 +11274,7 @@ COND_WINDOWS_IMPLIB_1___htmldll___importlib = \ -Wl,--out-implib=$(LIBDIRNAME)/$(LIBPREFIX)wx_$(PORTNAME)$(WXUNIVNAME)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_html-$(WX_RELEASE)$(HOST_SUFFIX).$(DLLIMP_SUFFIX) @COND_WINDOWS_IMPLIB_1@__htmldll___importlib = $(COND_WINDOWS_IMPLIB_1___htmldll___importlib) @COND_GCC_PCH_1@__htmldll_PCH_INC = -I./.pch/wxprec_htmldll -@COND_ICC_PCH_1@__htmldll_PCH_INC = -use_pch \ +@COND_ICC_PCH_1@__htmldll_PCH_INC = $(ICC_PCH_USE_SWITCH) \ @COND_ICC_PCH_1@ ./.pch/wxprec_htmldll/wx/wxprec.h.gch @COND_USE_PCH_1@_____pch_wxprec_htmldll_wx_wxprec_h_gch___depname \ @COND_USE_PCH_1@ = ./.pch/wxprec_htmldll/wx/wxprec.h.gch @@ -11309,7 +11320,7 @@ COND_MONOLITHIC_0_SHARED_0_USE_GUI_1_USE_HTML_1___htmllib___depname = \ @COND_MONOLITHIC_0_SHARED_0_USE_GUI_1_USE_HTML_1@__uninstall_htmllib___depname \ @COND_MONOLITHIC_0_SHARED_0_USE_GUI_1_USE_HTML_1@ = uninstall_htmllib @COND_GCC_PCH_1@__htmllib_PCH_INC = -I./.pch/wxprec_htmllib -@COND_ICC_PCH_1@__htmllib_PCH_INC = -use_pch \ +@COND_ICC_PCH_1@__htmllib_PCH_INC = $(ICC_PCH_USE_SWITCH) \ @COND_ICC_PCH_1@ ./.pch/wxprec_htmllib/wx/wxprec.h.gch @COND_USE_PCH_1@_____pch_wxprec_htmllib_wx_wxprec_h_gch___depname \ @COND_USE_PCH_1@ = ./.pch/wxprec_htmllib/wx/wxprec.h.gch @@ -11335,7 +11346,7 @@ COND_WINDOWS_IMPLIB_1___qadll___importlib = \ -Wl,--out-implib=$(LIBDIRNAME)/$(LIBPREFIX)wx_$(PORTNAME)$(WXUNIVNAME)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_qa-$(WX_RELEASE)$(HOST_SUFFIX).$(DLLIMP_SUFFIX) @COND_WINDOWS_IMPLIB_1@__qadll___importlib = $(COND_WINDOWS_IMPLIB_1___qadll___importlib) @COND_GCC_PCH_1@__qadll_PCH_INC = -I./.pch/wxprec_qadll -@COND_ICC_PCH_1@__qadll_PCH_INC = -use_pch \ +@COND_ICC_PCH_1@__qadll_PCH_INC = $(ICC_PCH_USE_SWITCH) \ @COND_ICC_PCH_1@ ./.pch/wxprec_qadll/wx/wxprec.h.gch @COND_USE_PCH_1@_____pch_wxprec_qadll_wx_wxprec_h_gch___depname \ @COND_USE_PCH_1@ = ./.pch/wxprec_qadll/wx/wxprec.h.gch @@ -11378,7 +11389,7 @@ COND_MONOLITHIC_0_SHARED_0_USE_GUI_1_USE_QA_1___qalib___depname = \ @COND_MONOLITHIC_0_SHARED_0_USE_GUI_1_USE_QA_1@__uninstall_qalib___depname \ @COND_MONOLITHIC_0_SHARED_0_USE_GUI_1_USE_QA_1@ = uninstall_qalib @COND_GCC_PCH_1@__qalib_PCH_INC = -I./.pch/wxprec_qalib -@COND_ICC_PCH_1@__qalib_PCH_INC = -use_pch \ +@COND_ICC_PCH_1@__qalib_PCH_INC = $(ICC_PCH_USE_SWITCH) \ @COND_ICC_PCH_1@ ./.pch/wxprec_qalib/wx/wxprec.h.gch @COND_USE_PCH_1@_____pch_wxprec_qalib_wx_wxprec_h_gch___depname \ @COND_USE_PCH_1@ = ./.pch/wxprec_qalib/wx/wxprec.h.gch @@ -11399,7 +11410,7 @@ COND_WINDOWS_IMPLIB_1___xmldll___importlib = \ -Wl,--out-implib=$(LIBDIRNAME)/$(LIBPREFIX)wx_base$(WXBASEPORT)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_xml-$(WX_RELEASE)$(HOST_SUFFIX).$(DLLIMP_SUFFIX) @COND_WINDOWS_IMPLIB_1@__xmldll___importlib = $(COND_WINDOWS_IMPLIB_1___xmldll___importlib) @COND_GCC_PCH_1@__xmldll_PCH_INC = -I./.pch/wxprec_xmldll -@COND_ICC_PCH_1@__xmldll_PCH_INC = -use_pch \ +@COND_ICC_PCH_1@__xmldll_PCH_INC = $(ICC_PCH_USE_SWITCH) \ @COND_ICC_PCH_1@ ./.pch/wxprec_xmldll/wx/wxprec.h.gch @COND_USE_PCH_1@_____pch_wxprec_xmldll_wx_wxprec_h_gch___depname \ @COND_USE_PCH_1@ = ./.pch/wxprec_xmldll/wx/wxprec.h.gch @@ -11440,7 +11451,7 @@ COND_MONOLITHIC_0_SHARED_0___xmllib___depname = \ @COND_MONOLITHIC_0_SHARED_0@__install_xmllib___depname = install_xmllib @COND_MONOLITHIC_0_SHARED_0@__uninstall_xmllib___depname = uninstall_xmllib @COND_GCC_PCH_1@__xmllib_PCH_INC = -I./.pch/wxprec_xmllib -@COND_ICC_PCH_1@__xmllib_PCH_INC = -use_pch \ +@COND_ICC_PCH_1@__xmllib_PCH_INC = $(ICC_PCH_USE_SWITCH) \ @COND_ICC_PCH_1@ ./.pch/wxprec_xmllib/wx/wxprec.h.gch @COND_USE_PCH_1@_____pch_wxprec_xmllib_wx_wxprec_h_gch___depname \ @COND_USE_PCH_1@ = ./.pch/wxprec_xmllib/wx/wxprec.h.gch @@ -11463,7 +11474,7 @@ COND_WINDOWS_IMPLIB_1___xrcdll___importlib = \ -Wl,--out-implib=$(LIBDIRNAME)/$(LIBPREFIX)wx_$(PORTNAME)$(WXUNIVNAME)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_xrc-$(WX_RELEASE)$(HOST_SUFFIX).$(DLLIMP_SUFFIX) @COND_WINDOWS_IMPLIB_1@__xrcdll___importlib = $(COND_WINDOWS_IMPLIB_1___xrcdll___importlib) @COND_GCC_PCH_1@__xrcdll_PCH_INC = -I./.pch/wxprec_xrcdll -@COND_ICC_PCH_1@__xrcdll_PCH_INC = -use_pch \ +@COND_ICC_PCH_1@__xrcdll_PCH_INC = $(ICC_PCH_USE_SWITCH) \ @COND_ICC_PCH_1@ ./.pch/wxprec_xrcdll/wx/wxprec.h.gch @COND_USE_PCH_1@_____pch_wxprec_xrcdll_wx_wxprec_h_gch___depname \ @COND_USE_PCH_1@ = ./.pch/wxprec_xrcdll/wx/wxprec.h.gch @@ -11506,7 +11517,7 @@ COND_MONOLITHIC_0_SHARED_0_USE_XRC_1___xrclib___depname = \ @COND_MONOLITHIC_0_SHARED_0_USE_XRC_1@__uninstall_xrclib___depname \ @COND_MONOLITHIC_0_SHARED_0_USE_XRC_1@ = uninstall_xrclib @COND_GCC_PCH_1@__xrclib_PCH_INC = -I./.pch/wxprec_xrclib -@COND_ICC_PCH_1@__xrclib_PCH_INC = -use_pch \ +@COND_ICC_PCH_1@__xrclib_PCH_INC = $(ICC_PCH_USE_SWITCH) \ @COND_ICC_PCH_1@ ./.pch/wxprec_xrclib/wx/wxprec.h.gch @COND_USE_PCH_1@_____pch_wxprec_xrclib_wx_wxprec_h_gch___depname \ @COND_USE_PCH_1@ = ./.pch/wxprec_xrclib/wx/wxprec.h.gch @@ -11529,7 +11540,7 @@ COND_WINDOWS_IMPLIB_1___auidll___importlib = \ -Wl,--out-implib=$(LIBDIRNAME)/$(LIBPREFIX)wx_$(PORTNAME)$(WXUNIVNAME)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_aui-$(WX_RELEASE)$(HOST_SUFFIX).$(DLLIMP_SUFFIX) @COND_WINDOWS_IMPLIB_1@__auidll___importlib = $(COND_WINDOWS_IMPLIB_1___auidll___importlib) @COND_GCC_PCH_1@__auidll_PCH_INC = -I./.pch/wxprec_auidll -@COND_ICC_PCH_1@__auidll_PCH_INC = -use_pch \ +@COND_ICC_PCH_1@__auidll_PCH_INC = $(ICC_PCH_USE_SWITCH) \ @COND_ICC_PCH_1@ ./.pch/wxprec_auidll/wx/wxprec.h.gch @COND_USE_PCH_1@_____pch_wxprec_auidll_wx_wxprec_h_gch___depname \ @COND_USE_PCH_1@ = ./.pch/wxprec_auidll/wx/wxprec.h.gch @@ -11572,7 +11583,7 @@ COND_MONOLITHIC_0_SHARED_0_USE_AUI_1___auilib___depname = \ @COND_MONOLITHIC_0_SHARED_0_USE_AUI_1@__uninstall_auilib___depname \ @COND_MONOLITHIC_0_SHARED_0_USE_AUI_1@ = uninstall_auilib @COND_GCC_PCH_1@__auilib_PCH_INC = -I./.pch/wxprec_auilib -@COND_ICC_PCH_1@__auilib_PCH_INC = -use_pch \ +@COND_ICC_PCH_1@__auilib_PCH_INC = $(ICC_PCH_USE_SWITCH) \ @COND_ICC_PCH_1@ ./.pch/wxprec_auilib/wx/wxprec.h.gch @COND_USE_PCH_1@_____pch_wxprec_auilib_wx_wxprec_h_gch___depname \ @COND_USE_PCH_1@ = ./.pch/wxprec_auilib/wx/wxprec.h.gch @@ -11595,7 +11606,8 @@ COND_WINDOWS_IMPLIB_1___propgriddll___importlib = \ -Wl,--out-implib=$(LIBDIRNAME)/$(LIBPREFIX)wx_$(PORTNAME)$(WXUNIVNAME)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_propgrid-$(WX_RELEASE)$(HOST_SUFFIX).$(DLLIMP_SUFFIX) @COND_WINDOWS_IMPLIB_1@__propgriddll___importlib = $(COND_WINDOWS_IMPLIB_1___propgriddll___importlib) @COND_GCC_PCH_1@__propgriddll_PCH_INC = -I./.pch/wxprec_propgriddll -@COND_ICC_PCH_1@__propgriddll_PCH_INC = -use_pch \ +@COND_ICC_PCH_1@__propgriddll_PCH_INC = \ +@COND_ICC_PCH_1@ $(ICC_PCH_USE_SWITCH) \ @COND_ICC_PCH_1@ ./.pch/wxprec_propgriddll/wx/wxprec.h.gch @COND_USE_PCH_1@_____pch_wxprec_propgriddll_wx_wxprec_h_gch___depname \ @COND_USE_PCH_1@ = ./.pch/wxprec_propgriddll/wx/wxprec.h.gch @@ -11639,7 +11651,8 @@ COND_MONOLITHIC_0_SHARED_0_USE_PROPGRID_1___propgridlib___depname = \ @COND_MONOLITHIC_0_SHARED_0_USE_PROPGRID_1@__uninstall_propgridlib___depname \ @COND_MONOLITHIC_0_SHARED_0_USE_PROPGRID_1@ = uninstall_propgridlib @COND_GCC_PCH_1@__propgridlib_PCH_INC = -I./.pch/wxprec_propgridlib -@COND_ICC_PCH_1@__propgridlib_PCH_INC = -use_pch \ +@COND_ICC_PCH_1@__propgridlib_PCH_INC = \ +@COND_ICC_PCH_1@ $(ICC_PCH_USE_SWITCH) \ @COND_ICC_PCH_1@ ./.pch/wxprec_propgridlib/wx/wxprec.h.gch @COND_USE_PCH_1@_____pch_wxprec_propgridlib_wx_wxprec_h_gch___depname \ @COND_USE_PCH_1@ = ./.pch/wxprec_propgridlib/wx/wxprec.h.gch @@ -11662,7 +11675,8 @@ COND_WINDOWS_IMPLIB_1___richtextdll___importlib = \ -Wl,--out-implib=$(LIBDIRNAME)/$(LIBPREFIX)wx_$(PORTNAME)$(WXUNIVNAME)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_richtext-$(WX_RELEASE)$(HOST_SUFFIX).$(DLLIMP_SUFFIX) @COND_WINDOWS_IMPLIB_1@__richtextdll___importlib = $(COND_WINDOWS_IMPLIB_1___richtextdll___importlib) @COND_GCC_PCH_1@__richtextdll_PCH_INC = -I./.pch/wxprec_richtextdll -@COND_ICC_PCH_1@__richtextdll_PCH_INC = -use_pch \ +@COND_ICC_PCH_1@__richtextdll_PCH_INC = \ +@COND_ICC_PCH_1@ $(ICC_PCH_USE_SWITCH) \ @COND_ICC_PCH_1@ ./.pch/wxprec_richtextdll/wx/wxprec.h.gch @COND_USE_PCH_1@_____pch_wxprec_richtextdll_wx_wxprec_h_gch___depname \ @COND_USE_PCH_1@ = ./.pch/wxprec_richtextdll/wx/wxprec.h.gch @@ -11706,7 +11720,8 @@ COND_MONOLITHIC_0_SHARED_0_USE_RICHTEXT_1___richtextlib___depname = \ @COND_MONOLITHIC_0_SHARED_0_USE_RICHTEXT_1@__uninstall_richtextlib___depname \ @COND_MONOLITHIC_0_SHARED_0_USE_RICHTEXT_1@ = uninstall_richtextlib @COND_GCC_PCH_1@__richtextlib_PCH_INC = -I./.pch/wxprec_richtextlib -@COND_ICC_PCH_1@__richtextlib_PCH_INC = -use_pch \ +@COND_ICC_PCH_1@__richtextlib_PCH_INC = \ +@COND_ICC_PCH_1@ $(ICC_PCH_USE_SWITCH) \ @COND_ICC_PCH_1@ ./.pch/wxprec_richtextlib/wx/wxprec.h.gch @COND_USE_PCH_1@_____pch_wxprec_richtextlib_wx_wxprec_h_gch___depname \ @COND_USE_PCH_1@ = ./.pch/wxprec_richtextlib/wx/wxprec.h.gch @@ -11729,7 +11744,7 @@ COND_WINDOWS_IMPLIB_1___stcdll___importlib = \ -Wl,--out-implib=$(LIBDIRNAME)/$(LIBPREFIX)wx_$(PORTNAME)$(WXUNIVNAME)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_stc-$(WX_RELEASE)$(HOST_SUFFIX).$(DLLIMP_SUFFIX) @COND_WINDOWS_IMPLIB_1@__stcdll___importlib = $(COND_WINDOWS_IMPLIB_1___stcdll___importlib) @COND_GCC_PCH_1@__stcdll_PCH_INC = -I./.pch/wxprec_stcdll -@COND_ICC_PCH_1@__stcdll_PCH_INC = -use_pch \ +@COND_ICC_PCH_1@__stcdll_PCH_INC = $(ICC_PCH_USE_SWITCH) \ @COND_ICC_PCH_1@ ./.pch/wxprec_stcdll/wx/wxprec.h.gch @COND_USE_PCH_1@_____pch_wxprec_stcdll_wx_wxprec_h_gch___depname \ @COND_USE_PCH_1@ = ./.pch/wxprec_stcdll/wx/wxprec.h.gch @@ -11772,7 +11787,7 @@ COND_MONOLITHIC_0_SHARED_0_USE_STC_1___stclib___depname = \ @COND_MONOLITHIC_0_SHARED_0_USE_STC_1@__uninstall_stclib___depname \ @COND_MONOLITHIC_0_SHARED_0_USE_STC_1@ = uninstall_stclib @COND_GCC_PCH_1@__stclib_PCH_INC = -I./.pch/wxprec_stclib -@COND_ICC_PCH_1@__stclib_PCH_INC = -use_pch \ +@COND_ICC_PCH_1@__stclib_PCH_INC = $(ICC_PCH_USE_SWITCH) \ @COND_ICC_PCH_1@ ./.pch/wxprec_stclib/wx/wxprec.h.gch @COND_USE_PCH_1@_____pch_wxprec_stclib_wx_wxprec_h_gch___depname \ @COND_USE_PCH_1@ = ./.pch/wxprec_stclib/wx/wxprec.h.gch @@ -11795,7 +11810,7 @@ COND_WINDOWS_IMPLIB_1___gldll___importlib = \ -Wl,--out-implib=$(LIBDIRNAME)/$(LIBPREFIX)wx_$(PORTNAME)$(WXUNIVNAME)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_gl-$(WX_RELEASE)$(HOST_SUFFIX).$(DLLIMP_SUFFIX) @COND_WINDOWS_IMPLIB_1@__gldll___importlib = $(COND_WINDOWS_IMPLIB_1___gldll___importlib) @COND_GCC_PCH_1@__gldll_PCH_INC = -I./.pch/wxprec_gldll -@COND_ICC_PCH_1@__gldll_PCH_INC = -use_pch \ +@COND_ICC_PCH_1@__gldll_PCH_INC = $(ICC_PCH_USE_SWITCH) \ @COND_ICC_PCH_1@ ./.pch/wxprec_gldll/wx/wxprec.h.gch @COND_USE_PCH_1@_____pch_wxprec_gldll_wx_wxprec_h_gch___depname \ @COND_USE_PCH_1@ = ./.pch/wxprec_gldll/wx/wxprec.h.gch @@ -11864,7 +11879,7 @@ COND_SHARED_0_USE_GUI_1_USE_OPENGL_1___gllib___depname = \ @COND_SHARED_0_USE_GUI_1_USE_OPENGL_1@__uninstall_gllib___depname \ @COND_SHARED_0_USE_GUI_1_USE_OPENGL_1@ = uninstall_gllib @COND_GCC_PCH_1@__gllib_PCH_INC = -I./.pch/wxprec_gllib -@COND_ICC_PCH_1@__gllib_PCH_INC = -use_pch \ +@COND_ICC_PCH_1@__gllib_PCH_INC = $(ICC_PCH_USE_SWITCH) \ @COND_ICC_PCH_1@ ./.pch/wxprec_gllib/wx/wxprec.h.gch @COND_USE_PCH_1@_____pch_wxprec_gllib_wx_wxprec_h_gch___depname \ @COND_USE_PCH_1@ = ./.pch/wxprec_gllib/wx/wxprec.h.gch @@ -18458,6 +18473,9 @@ monodll_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(MONODLL_ODEP) @COND_USE_GUI_1@monodll_gridctrl.o: $(srcdir)/src/generic/gridctrl.cpp $(MONODLL_ODEP) @COND_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/generic/gridctrl.cpp +@COND_USE_GUI_1@monodll_grideditors.o: $(srcdir)/src/generic/grideditors.cpp $(MONODLL_ODEP) +@COND_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/generic/grideditors.cpp + @COND_USE_GUI_1@monodll_gridsel.o: $(srcdir)/src/generic/gridsel.cpp $(MONODLL_ODEP) @COND_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/generic/gridsel.cpp @@ -23114,6 +23132,9 @@ monolib_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(MONOLIB_ODEP) @COND_USE_GUI_1@monolib_gridctrl.o: $(srcdir)/src/generic/gridctrl.cpp $(MONOLIB_ODEP) @COND_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/generic/gridctrl.cpp +@COND_USE_GUI_1@monolib_grideditors.o: $(srcdir)/src/generic/grideditors.cpp $(MONOLIB_ODEP) +@COND_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/generic/grideditors.cpp + @COND_USE_GUI_1@monolib_gridsel.o: $(srcdir)/src/generic/gridsel.cpp $(MONOLIB_ODEP) @COND_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/generic/gridsel.cpp @@ -31466,6 +31487,9 @@ advdll_grid.o: $(srcdir)/src/generic/grid.cpp $(ADVDLL_ODEP) advdll_gridctrl.o: $(srcdir)/src/generic/gridctrl.cpp $(ADVDLL_ODEP) $(CXXC) -c -o $@ $(ADVDLL_CXXFLAGS) $(srcdir)/src/generic/gridctrl.cpp +advdll_grideditors.o: $(srcdir)/src/generic/grideditors.cpp $(ADVDLL_ODEP) + $(CXXC) -c -o $@ $(ADVDLL_CXXFLAGS) $(srcdir)/src/generic/grideditors.cpp + advdll_gridsel.o: $(srcdir)/src/generic/gridsel.cpp $(ADVDLL_ODEP) $(CXXC) -c -o $@ $(ADVDLL_CXXFLAGS) $(srcdir)/src/generic/gridsel.cpp @@ -31769,6 +31793,9 @@ advlib_grid.o: $(srcdir)/src/generic/grid.cpp $(ADVLIB_ODEP) advlib_gridctrl.o: $(srcdir)/src/generic/gridctrl.cpp $(ADVLIB_ODEP) $(CXXC) -c -o $@ $(ADVLIB_CXXFLAGS) $(srcdir)/src/generic/gridctrl.cpp +advlib_grideditors.o: $(srcdir)/src/generic/grideditors.cpp $(ADVLIB_ODEP) + $(CXXC) -c -o $@ $(ADVLIB_CXXFLAGS) $(srcdir)/src/generic/grideditors.cpp + advlib_gridsel.o: $(srcdir)/src/generic/gridsel.cpp $(ADVLIB_ODEP) $(CXXC) -c -o $@ $(ADVLIB_CXXFLAGS) $(srcdir)/src/generic/gridsel.cpp diff --git a/build/bakefiles/files.bkl b/build/bakefiles/files.bkl index d2ea2993c9..16d818d852 100644 --- a/build/bakefiles/files.bkl +++ b/build/bakefiles/files.bkl @@ -2872,6 +2872,7 @@ src/osx/iphone/window.mm src/generic/editlbox.cpp src/generic/grid.cpp src/generic/gridctrl.cpp + src/generic/grideditors.cpp src/generic/gridsel.cpp src/generic/helpext.cpp src/generic/hyperlinkg.cpp @@ -2902,6 +2903,7 @@ src/osx/iphone/window.mm wx/generic/dataview.h wx/generic/grid.h wx/generic/gridctrl.h + wx/generic/grideditors.h wx/generic/gridsel.h wx/generic/helpext.h wx/generic/hyperlink.h diff --git a/build/msw/makefile.bcc b/build/msw/makefile.bcc index f7e9a8596e..ec5ee4426e 100644 --- a/build/msw/makefile.bcc +++ b/build/msw/makefile.bcc @@ -2013,6 +2013,7 @@ ____ADVANCED_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_editlbox.obj \ $(OBJS)\monodll_grid.obj \ $(OBJS)\monodll_gridctrl.obj \ + $(OBJS)\monodll_grideditors.obj \ $(OBJS)\monodll_gridsel.obj \ $(OBJS)\monodll_helpext.obj \ $(OBJS)\monodll_hyperlinkg.obj \ @@ -2051,6 +2052,7 @@ ____ADVANCED_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_editlbox.obj \ $(OBJS)\monodll_grid.obj \ $(OBJS)\monodll_gridctrl.obj \ + $(OBJS)\monodll_grideditors.obj \ $(OBJS)\monodll_gridsel.obj \ $(OBJS)\monodll_helpext.obj \ $(OBJS)\monodll_hyperlinkg.obj \ @@ -2688,6 +2690,7 @@ ____ADVANCED_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_editlbox.obj \ $(OBJS)\monolib_grid.obj \ $(OBJS)\monolib_gridctrl.obj \ + $(OBJS)\monolib_grideditors.obj \ $(OBJS)\monolib_gridsel.obj \ $(OBJS)\monolib_helpext.obj \ $(OBJS)\monolib_hyperlinkg.obj \ @@ -2726,6 +2729,7 @@ ____ADVANCED_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_editlbox.obj \ $(OBJS)\monolib_grid.obj \ $(OBJS)\monolib_gridctrl.obj \ + $(OBJS)\monolib_grideditors.obj \ $(OBJS)\monolib_gridsel.obj \ $(OBJS)\monolib_helpext.obj \ $(OBJS)\monolib_hyperlinkg.obj \ @@ -3757,6 +3761,7 @@ ____ADVANCED_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\advdll_editlbox.obj \ $(OBJS)\advdll_grid.obj \ $(OBJS)\advdll_gridctrl.obj \ + $(OBJS)\advdll_grideditors.obj \ $(OBJS)\advdll_gridsel.obj \ $(OBJS)\advdll_helpext.obj \ $(OBJS)\advdll_hyperlinkg.obj \ @@ -3795,6 +3800,7 @@ ____ADVANCED_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\advdll_editlbox.obj \ $(OBJS)\advdll_grid.obj \ $(OBJS)\advdll_gridctrl.obj \ + $(OBJS)\advdll_grideditors.obj \ $(OBJS)\advdll_gridsel.obj \ $(OBJS)\advdll_helpext.obj \ $(OBJS)\advdll_hyperlinkg.obj \ @@ -3834,6 +3840,7 @@ ____ADVANCED_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\advlib_editlbox.obj \ $(OBJS)\advlib_grid.obj \ $(OBJS)\advlib_gridctrl.obj \ + $(OBJS)\advlib_grideditors.obj \ $(OBJS)\advlib_gridsel.obj \ $(OBJS)\advlib_helpext.obj \ $(OBJS)\advlib_hyperlinkg.obj \ @@ -3872,6 +3879,7 @@ ____ADVANCED_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\advlib_editlbox.obj \ $(OBJS)\advlib_grid.obj \ $(OBJS)\advlib_gridctrl.obj \ + $(OBJS)\advlib_grideditors.obj \ $(OBJS)\advlib_gridsel.obj \ $(OBJS)\advlib_helpext.obj \ $(OBJS)\advlib_hyperlinkg.obj \ @@ -7473,6 +7481,11 @@ $(OBJS)\monodll_gridctrl.obj: ..\..\src\generic\gridctrl.cpp $(CXX) -q -c -P -o$@ $(MONODLL_CXXFLAGS) ..\..\src\generic\gridctrl.cpp !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\monodll_grideditors.obj: ..\..\src\generic\grideditors.cpp + $(CXX) -q -c -P -o$@ $(MONODLL_CXXFLAGS) ..\..\src\generic\grideditors.cpp +!endif + !if "$(USE_GUI)" == "1" $(OBJS)\monodll_gridsel.obj: ..\..\src\generic\gridsel.cpp $(CXX) -q -c -P -o$@ $(MONODLL_CXXFLAGS) ..\..\src\generic\gridsel.cpp @@ -9678,6 +9691,11 @@ $(OBJS)\monolib_gridctrl.obj: ..\..\src\generic\gridctrl.cpp $(CXX) -q -c -P -o$@ $(MONOLIB_CXXFLAGS) ..\..\src\generic\gridctrl.cpp !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\monolib_grideditors.obj: ..\..\src\generic\grideditors.cpp + $(CXX) -q -c -P -o$@ $(MONOLIB_CXXFLAGS) ..\..\src\generic\grideditors.cpp +!endif + !if "$(USE_GUI)" == "1" $(OBJS)\monolib_gridsel.obj: ..\..\src\generic\gridsel.cpp $(CXX) -q -c -P -o$@ $(MONOLIB_CXXFLAGS) ..\..\src\generic\gridsel.cpp @@ -13257,6 +13275,9 @@ $(OBJS)\advdll_grid.obj: ..\..\src\generic\grid.cpp $(OBJS)\advdll_gridctrl.obj: ..\..\src\generic\gridctrl.cpp $(CXX) -q -c -P -o$@ $(ADVDLL_CXXFLAGS) ..\..\src\generic\gridctrl.cpp +$(OBJS)\advdll_grideditors.obj: ..\..\src\generic\grideditors.cpp + $(CXX) -q -c -P -o$@ $(ADVDLL_CXXFLAGS) ..\..\src\generic\grideditors.cpp + $(OBJS)\advdll_gridsel.obj: ..\..\src\generic\gridsel.cpp $(CXX) -q -c -P -o$@ $(ADVDLL_CXXFLAGS) ..\..\src\generic\gridsel.cpp @@ -13370,6 +13391,9 @@ $(OBJS)\advlib_grid.obj: ..\..\src\generic\grid.cpp $(OBJS)\advlib_gridctrl.obj: ..\..\src\generic\gridctrl.cpp $(CXX) -q -c -P -o$@ $(ADVLIB_CXXFLAGS) ..\..\src\generic\gridctrl.cpp +$(OBJS)\advlib_grideditors.obj: ..\..\src\generic\grideditors.cpp + $(CXX) -q -c -P -o$@ $(ADVLIB_CXXFLAGS) ..\..\src\generic\grideditors.cpp + $(OBJS)\advlib_gridsel.obj: ..\..\src\generic\gridsel.cpp $(CXX) -q -c -P -o$@ $(ADVLIB_CXXFLAGS) ..\..\src\generic\gridsel.cpp diff --git a/build/msw/makefile.gcc b/build/msw/makefile.gcc index 90dd3786e9..bae6ceddd0 100644 --- a/build/msw/makefile.gcc +++ b/build/msw/makefile.gcc @@ -2034,6 +2034,7 @@ ____ADVANCED_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_editlbox.o \ $(OBJS)\monodll_grid.o \ $(OBJS)\monodll_gridctrl.o \ + $(OBJS)\monodll_grideditors.o \ $(OBJS)\monodll_gridsel.o \ $(OBJS)\monodll_helpext.o \ $(OBJS)\monodll_hyperlinkg.o \ @@ -2072,6 +2073,7 @@ ____ADVANCED_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_editlbox.o \ $(OBJS)\monodll_grid.o \ $(OBJS)\monodll_gridctrl.o \ + $(OBJS)\monodll_grideditors.o \ $(OBJS)\monodll_gridsel.o \ $(OBJS)\monodll_helpext.o \ $(OBJS)\monodll_hyperlinkg.o \ @@ -2715,6 +2717,7 @@ ____ADVANCED_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_editlbox.o \ $(OBJS)\monolib_grid.o \ $(OBJS)\monolib_gridctrl.o \ + $(OBJS)\monolib_grideditors.o \ $(OBJS)\monolib_gridsel.o \ $(OBJS)\monolib_helpext.o \ $(OBJS)\monolib_hyperlinkg.o \ @@ -2753,6 +2756,7 @@ ____ADVANCED_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_editlbox.o \ $(OBJS)\monolib_grid.o \ $(OBJS)\monolib_gridctrl.o \ + $(OBJS)\monolib_grideditors.o \ $(OBJS)\monolib_gridsel.o \ $(OBJS)\monolib_helpext.o \ $(OBJS)\monolib_hyperlinkg.o \ @@ -3812,6 +3816,7 @@ ____ADVANCED_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\advdll_editlbox.o \ $(OBJS)\advdll_grid.o \ $(OBJS)\advdll_gridctrl.o \ + $(OBJS)\advdll_grideditors.o \ $(OBJS)\advdll_gridsel.o \ $(OBJS)\advdll_helpext.o \ $(OBJS)\advdll_hyperlinkg.o \ @@ -3850,6 +3855,7 @@ ____ADVANCED_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\advdll_editlbox.o \ $(OBJS)\advdll_grid.o \ $(OBJS)\advdll_gridctrl.o \ + $(OBJS)\advdll_grideditors.o \ $(OBJS)\advdll_gridsel.o \ $(OBJS)\advdll_helpext.o \ $(OBJS)\advdll_hyperlinkg.o \ @@ -3893,6 +3899,7 @@ ____ADVANCED_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\advlib_editlbox.o \ $(OBJS)\advlib_grid.o \ $(OBJS)\advlib_gridctrl.o \ + $(OBJS)\advlib_grideditors.o \ $(OBJS)\advlib_gridsel.o \ $(OBJS)\advlib_helpext.o \ $(OBJS)\advlib_hyperlinkg.o \ @@ -3931,6 +3938,7 @@ ____ADVANCED_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\advlib_editlbox.o \ $(OBJS)\advlib_grid.o \ $(OBJS)\advlib_gridctrl.o \ + $(OBJS)\advlib_grideditors.o \ $(OBJS)\advlib_gridsel.o \ $(OBJS)\advlib_helpext.o \ $(OBJS)\advlib_hyperlinkg.o \ @@ -7737,6 +7745,11 @@ $(OBJS)\monodll_gridctrl.o: ../../src/generic/gridctrl.cpp $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $< endif +ifeq ($(USE_GUI),1) +$(OBJS)\monodll_grideditors.o: ../../src/generic/grideditors.cpp + $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $< +endif + ifeq ($(USE_GUI),1) $(OBJS)\monodll_gridsel.o: ../../src/generic/gridsel.cpp $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $< @@ -10056,6 +10069,11 @@ $(OBJS)\monolib_gridctrl.o: ../../src/generic/gridctrl.cpp $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< endif +ifeq ($(USE_GUI),1) +$(OBJS)\monolib_grideditors.o: ../../src/generic/grideditors.cpp + $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< +endif + ifeq ($(USE_GUI),1) $(OBJS)\monolib_gridsel.o: ../../src/generic/gridsel.cpp $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< @@ -13861,6 +13879,9 @@ $(OBJS)\advdll_grid.o: ../../src/generic/grid.cpp $(OBJS)\advdll_gridctrl.o: ../../src/generic/gridctrl.cpp $(CXX) -c -o $@ $(ADVDLL_CXXFLAGS) $(CPPDEPS) $< +$(OBJS)\advdll_grideditors.o: ../../src/generic/grideditors.cpp + $(CXX) -c -o $@ $(ADVDLL_CXXFLAGS) $(CPPDEPS) $< + $(OBJS)\advdll_gridsel.o: ../../src/generic/gridsel.cpp $(CXX) -c -o $@ $(ADVDLL_CXXFLAGS) $(CPPDEPS) $< @@ -13974,6 +13995,9 @@ $(OBJS)\advlib_grid.o: ../../src/generic/grid.cpp $(OBJS)\advlib_gridctrl.o: ../../src/generic/gridctrl.cpp $(CXX) -c -o $@ $(ADVLIB_CXXFLAGS) $(CPPDEPS) $< +$(OBJS)\advlib_grideditors.o: ../../src/generic/grideditors.cpp + $(CXX) -c -o $@ $(ADVLIB_CXXFLAGS) $(CPPDEPS) $< + $(OBJS)\advlib_gridsel.o: ../../src/generic/gridsel.cpp $(CXX) -c -o $@ $(ADVLIB_CXXFLAGS) $(CPPDEPS) $< diff --git a/build/msw/makefile.vc b/build/msw/makefile.vc index bad53b34fc..b418aa0ea3 100644 --- a/build/msw/makefile.vc +++ b/build/msw/makefile.vc @@ -2193,6 +2193,7 @@ ____ADVANCED_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_editlbox.obj \ $(OBJS)\monodll_grid.obj \ $(OBJS)\monodll_gridctrl.obj \ + $(OBJS)\monodll_grideditors.obj \ $(OBJS)\monodll_gridsel.obj \ $(OBJS)\monodll_helpext.obj \ $(OBJS)\monodll_hyperlinkg.obj \ @@ -2231,6 +2232,7 @@ ____ADVANCED_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_editlbox.obj \ $(OBJS)\monodll_grid.obj \ $(OBJS)\monodll_gridctrl.obj \ + $(OBJS)\monodll_grideditors.obj \ $(OBJS)\monodll_gridsel.obj \ $(OBJS)\monodll_helpext.obj \ $(OBJS)\monodll_hyperlinkg.obj \ @@ -2874,6 +2876,7 @@ ____ADVANCED_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_editlbox.obj \ $(OBJS)\monolib_grid.obj \ $(OBJS)\monolib_gridctrl.obj \ + $(OBJS)\monolib_grideditors.obj \ $(OBJS)\monolib_gridsel.obj \ $(OBJS)\monolib_helpext.obj \ $(OBJS)\monolib_hyperlinkg.obj \ @@ -2912,6 +2915,7 @@ ____ADVANCED_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_editlbox.obj \ $(OBJS)\monolib_grid.obj \ $(OBJS)\monolib_gridctrl.obj \ + $(OBJS)\monolib_grideditors.obj \ $(OBJS)\monolib_gridsel.obj \ $(OBJS)\monolib_helpext.obj \ $(OBJS)\monolib_hyperlinkg.obj \ @@ -3985,6 +3989,7 @@ ____ADVANCED_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\advdll_editlbox.obj \ $(OBJS)\advdll_grid.obj \ $(OBJS)\advdll_gridctrl.obj \ + $(OBJS)\advdll_grideditors.obj \ $(OBJS)\advdll_gridsel.obj \ $(OBJS)\advdll_helpext.obj \ $(OBJS)\advdll_hyperlinkg.obj \ @@ -4023,6 +4028,7 @@ ____ADVANCED_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\advdll_editlbox.obj \ $(OBJS)\advdll_grid.obj \ $(OBJS)\advdll_gridctrl.obj \ + $(OBJS)\advdll_grideditors.obj \ $(OBJS)\advdll_gridsel.obj \ $(OBJS)\advdll_helpext.obj \ $(OBJS)\advdll_hyperlinkg.obj \ @@ -4068,6 +4074,7 @@ ____ADVANCED_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\advlib_editlbox.obj \ $(OBJS)\advlib_grid.obj \ $(OBJS)\advlib_gridctrl.obj \ + $(OBJS)\advlib_grideditors.obj \ $(OBJS)\advlib_gridsel.obj \ $(OBJS)\advlib_helpext.obj \ $(OBJS)\advlib_hyperlinkg.obj \ @@ -4106,6 +4113,7 @@ ____ADVANCED_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\advlib_editlbox.obj \ $(OBJS)\advlib_grid.obj \ $(OBJS)\advlib_gridctrl.obj \ + $(OBJS)\advlib_grideditors.obj \ $(OBJS)\advlib_gridsel.obj \ $(OBJS)\advlib_helpext.obj \ $(OBJS)\advlib_hyperlinkg.obj \ @@ -7819,6 +7827,11 @@ $(OBJS)\monodll_gridctrl.obj: ..\..\src\generic\gridctrl.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\generic\gridctrl.cpp !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\monodll_grideditors.obj: ..\..\src\generic\grideditors.cpp + $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\generic\grideditors.cpp +!endif + !if "$(USE_GUI)" == "1" $(OBJS)\monodll_gridsel.obj: ..\..\src\generic\gridsel.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\generic\gridsel.cpp @@ -10024,6 +10037,11 @@ $(OBJS)\monolib_gridctrl.obj: ..\..\src\generic\gridctrl.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\generic\gridctrl.cpp !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\monolib_grideditors.obj: ..\..\src\generic\grideditors.cpp + $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\generic\grideditors.cpp +!endif + !if "$(USE_GUI)" == "1" $(OBJS)\monolib_gridsel.obj: ..\..\src\generic\gridsel.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\generic\gridsel.cpp @@ -13603,6 +13621,9 @@ $(OBJS)\advdll_grid.obj: ..\..\src\generic\grid.cpp $(OBJS)\advdll_gridctrl.obj: ..\..\src\generic\gridctrl.cpp $(CXX) /c /nologo /TP /Fo$@ $(ADVDLL_CXXFLAGS) ..\..\src\generic\gridctrl.cpp +$(OBJS)\advdll_grideditors.obj: ..\..\src\generic\grideditors.cpp + $(CXX) /c /nologo /TP /Fo$@ $(ADVDLL_CXXFLAGS) ..\..\src\generic\grideditors.cpp + $(OBJS)\advdll_gridsel.obj: ..\..\src\generic\gridsel.cpp $(CXX) /c /nologo /TP /Fo$@ $(ADVDLL_CXXFLAGS) ..\..\src\generic\gridsel.cpp @@ -13716,6 +13737,9 @@ $(OBJS)\advlib_grid.obj: ..\..\src\generic\grid.cpp $(OBJS)\advlib_gridctrl.obj: ..\..\src\generic\gridctrl.cpp $(CXX) /c /nologo /TP /Fo$@ $(ADVLIB_CXXFLAGS) ..\..\src\generic\gridctrl.cpp +$(OBJS)\advlib_grideditors.obj: ..\..\src\generic\grideditors.cpp + $(CXX) /c /nologo /TP /Fo$@ $(ADVLIB_CXXFLAGS) ..\..\src\generic\grideditors.cpp + $(OBJS)\advlib_gridsel.obj: ..\..\src\generic\gridsel.cpp $(CXX) /c /nologo /TP /Fo$@ $(ADVLIB_CXXFLAGS) ..\..\src\generic\gridsel.cpp diff --git a/build/msw/makefile.wat b/build/msw/makefile.wat index a7031ecb48..f2e49e12ab 100644 --- a/build/msw/makefile.wat +++ b/build/msw/makefile.wat @@ -712,6 +712,7 @@ ____ADVANCED_SRC_FILENAMES_OBJECTS = & $(OBJS)\monodll_editlbox.obj & $(OBJS)\monodll_grid.obj & $(OBJS)\monodll_gridctrl.obj & + $(OBJS)\monodll_grideditors.obj & $(OBJS)\monodll_gridsel.obj & $(OBJS)\monodll_helpext.obj & $(OBJS)\monodll_hyperlinkg.obj & @@ -750,6 +751,7 @@ ____ADVANCED_SRC_FILENAMES_OBJECTS = & $(OBJS)\monodll_editlbox.obj & $(OBJS)\monodll_grid.obj & $(OBJS)\monodll_gridctrl.obj & + $(OBJS)\monodll_grideditors.obj & $(OBJS)\monodll_gridsel.obj & $(OBJS)\monodll_helpext.obj & $(OBJS)\monodll_hyperlinkg.obj & @@ -1398,6 +1400,7 @@ ____ADVANCED_SRC_FILENAMES_1_OBJECTS = & $(OBJS)\monolib_editlbox.obj & $(OBJS)\monolib_grid.obj & $(OBJS)\monolib_gridctrl.obj & + $(OBJS)\monolib_grideditors.obj & $(OBJS)\monolib_gridsel.obj & $(OBJS)\monolib_helpext.obj & $(OBJS)\monolib_hyperlinkg.obj & @@ -1436,6 +1439,7 @@ ____ADVANCED_SRC_FILENAMES_1_OBJECTS = & $(OBJS)\monolib_editlbox.obj & $(OBJS)\monolib_grid.obj & $(OBJS)\monolib_gridctrl.obj & + $(OBJS)\monolib_grideditors.obj & $(OBJS)\monolib_gridsel.obj & $(OBJS)\monolib_helpext.obj & $(OBJS)\monolib_hyperlinkg.obj & @@ -2511,6 +2515,7 @@ ____ADVANCED_SRC_FILENAMES_2_OBJECTS = & $(OBJS)\advdll_editlbox.obj & $(OBJS)\advdll_grid.obj & $(OBJS)\advdll_gridctrl.obj & + $(OBJS)\advdll_grideditors.obj & $(OBJS)\advdll_gridsel.obj & $(OBJS)\advdll_helpext.obj & $(OBJS)\advdll_hyperlinkg.obj & @@ -2549,6 +2554,7 @@ ____ADVANCED_SRC_FILENAMES_2_OBJECTS = & $(OBJS)\advdll_editlbox.obj & $(OBJS)\advdll_grid.obj & $(OBJS)\advdll_gridctrl.obj & + $(OBJS)\advdll_grideditors.obj & $(OBJS)\advdll_gridsel.obj & $(OBJS)\advdll_helpext.obj & $(OBJS)\advdll_hyperlinkg.obj & @@ -2594,6 +2600,7 @@ ____ADVANCED_SRC_FILENAMES_3_OBJECTS = & $(OBJS)\advlib_editlbox.obj & $(OBJS)\advlib_grid.obj & $(OBJS)\advlib_gridctrl.obj & + $(OBJS)\advlib_grideditors.obj & $(OBJS)\advlib_gridsel.obj & $(OBJS)\advlib_helpext.obj & $(OBJS)\advlib_hyperlinkg.obj & @@ -2632,6 +2639,7 @@ ____ADVANCED_SRC_FILENAMES_3_OBJECTS = & $(OBJS)\advlib_editlbox.obj & $(OBJS)\advlib_grid.obj & $(OBJS)\advlib_gridctrl.obj & + $(OBJS)\advlib_grideditors.obj & $(OBJS)\advlib_gridsel.obj & $(OBJS)\advlib_helpext.obj & $(OBJS)\advlib_hyperlinkg.obj & @@ -7982,6 +7990,11 @@ $(OBJS)\monodll_gridctrl.obj : .AUTODEPEND ..\..\src\generic\gridctrl.cpp $(CXX) -bt=nt -zq -fo=$^@ $(MONODLL_CXXFLAGS) $< !endif +!ifeq USE_GUI 1 +$(OBJS)\monodll_grideditors.obj : .AUTODEPEND ..\..\src\generic\grideditors.cpp + $(CXX) -bt=nt -zq -fo=$^@ $(MONODLL_CXXFLAGS) $< +!endif + !ifeq USE_GUI 1 $(OBJS)\monodll_gridsel.obj : .AUTODEPEND ..\..\src\generic\gridsel.cpp $(CXX) -bt=nt -zq -fo=$^@ $(MONODLL_CXXFLAGS) $< @@ -10301,6 +10314,11 @@ $(OBJS)\monolib_gridctrl.obj : .AUTODEPEND ..\..\src\generic\gridctrl.cpp $(CXX) -bt=nt -zq -fo=$^@ $(MONOLIB_CXXFLAGS) $< !endif +!ifeq USE_GUI 1 +$(OBJS)\monolib_grideditors.obj : .AUTODEPEND ..\..\src\generic\grideditors.cpp + $(CXX) -bt=nt -zq -fo=$^@ $(MONOLIB_CXXFLAGS) $< +!endif + !ifeq USE_GUI 1 $(OBJS)\monolib_gridsel.obj : .AUTODEPEND ..\..\src\generic\gridsel.cpp $(CXX) -bt=nt -zq -fo=$^@ $(MONOLIB_CXXFLAGS) $< @@ -14106,6 +14124,9 @@ $(OBJS)\advdll_grid.obj : .AUTODEPEND ..\..\src\generic\grid.cpp $(OBJS)\advdll_gridctrl.obj : .AUTODEPEND ..\..\src\generic\gridctrl.cpp $(CXX) -bt=nt -zq -fo=$^@ $(ADVDLL_CXXFLAGS) $< +$(OBJS)\advdll_grideditors.obj : .AUTODEPEND ..\..\src\generic\grideditors.cpp + $(CXX) -bt=nt -zq -fo=$^@ $(ADVDLL_CXXFLAGS) $< + $(OBJS)\advdll_gridsel.obj : .AUTODEPEND ..\..\src\generic\gridsel.cpp $(CXX) -bt=nt -zq -fo=$^@ $(ADVDLL_CXXFLAGS) $< @@ -14219,6 +14240,9 @@ $(OBJS)\advlib_grid.obj : .AUTODEPEND ..\..\src\generic\grid.cpp $(OBJS)\advlib_gridctrl.obj : .AUTODEPEND ..\..\src\generic\gridctrl.cpp $(CXX) -bt=nt -zq -fo=$^@ $(ADVLIB_CXXFLAGS) $< +$(OBJS)\advlib_grideditors.obj : .AUTODEPEND ..\..\src\generic\grideditors.cpp + $(CXX) -bt=nt -zq -fo=$^@ $(ADVLIB_CXXFLAGS) $< + $(OBJS)\advlib_gridsel.obj : .AUTODEPEND ..\..\src\generic\gridsel.cpp $(CXX) -bt=nt -zq -fo=$^@ $(ADVLIB_CXXFLAGS) $< diff --git a/build/msw/wx_adv.dsp b/build/msw/wx_adv.dsp index f43cd8c0e3..8440b01e83 100644 --- a/build/msw/wx_adv.dsp +++ b/build/msw/wx_adv.dsp @@ -540,6 +540,10 @@ SOURCE=..\..\src\generic\gridctrl.cpp # End Source File # Begin Source File +SOURCE=..\..\src\generic\grideditors.cpp +# End Source File +# Begin Source File + SOURCE=..\..\src\generic\gridsel.cpp # End Source File # Begin Source File @@ -889,6 +893,10 @@ SOURCE=..\..\include\wx\generic\gridctrl.h # End Source File # Begin Source File +SOURCE=..\..\include\wx\generic\grideditors.h +# End Source File +# Begin Source File + SOURCE=..\..\include\wx\generic\gridsel.h # End Source File # Begin Source File diff --git a/build/msw/wx_core.dsp b/build/msw/wx_core.dsp index e19778531e..0da28e1fb1 100644 --- a/build/msw/wx_core.dsp +++ b/build/msw/wx_core.dsp @@ -5295,6 +5295,10 @@ SOURCE=..\..\include\wx\generic\gridctrl.h # End Source File # Begin Source File +SOURCE=..\..\include\wx\generic\grideditors.h +# End Source File +# Begin Source File + SOURCE=..\..\include\wx\generic\gridsel.h # End Source File # Begin Source File diff --git a/build/msw/wx_vc7_adv.vcproj b/build/msw/wx_vc7_adv.vcproj index f01bec0a06..e8db43a161 100644 --- a/build/msw/wx_vc7_adv.vcproj +++ b/build/msw/wx_vc7_adv.vcproj @@ -710,6 +710,9 @@ + + @@ -972,6 +975,9 @@ + + diff --git a/build/msw/wx_vc7_core.vcproj b/build/msw/wx_vc7_core.vcproj index d024c79259..d91089b015 100644 --- a/build/msw/wx_vc7_core.vcproj +++ b/build/msw/wx_vc7_core.vcproj @@ -3229,6 +3229,9 @@ + + diff --git a/build/msw/wx_vc8_adv.vcproj b/build/msw/wx_vc8_adv.vcproj index db5a614932..df1374b8f7 100644 --- a/build/msw/wx_vc8_adv.vcproj +++ b/build/msw/wx_vc8_adv.vcproj @@ -984,6 +984,10 @@ RelativePath="..\..\src\generic\gridctrl.cpp" > + + @@ -1319,6 +1323,10 @@ RelativePath="..\..\include\wx\generic\gridctrl.h" > + + diff --git a/build/msw/wx_vc8_core.vcproj b/build/msw/wx_vc8_core.vcproj index 5aa1e8f034..d75a09dbc2 100644 --- a/build/msw/wx_vc8_core.vcproj +++ b/build/msw/wx_vc8_core.vcproj @@ -4328,6 +4328,10 @@ RelativePath="..\..\include\wx\generic\gridctrl.h" > + + diff --git a/build/msw/wx_vc9_adv.vcproj b/build/msw/wx_vc9_adv.vcproj index 6997dfd7c4..260005611c 100644 --- a/build/msw/wx_vc9_adv.vcproj +++ b/build/msw/wx_vc9_adv.vcproj @@ -980,6 +980,10 @@ RelativePath="..\..\src\generic\gridctrl.cpp" > + + @@ -1315,6 +1319,10 @@ RelativePath="..\..\include\wx\generic\gridctrl.h" > + + diff --git a/build/msw/wx_vc9_core.vcproj b/build/msw/wx_vc9_core.vcproj index b95d665afa..19f9418152 100644 --- a/build/msw/wx_vc9_core.vcproj +++ b/build/msw/wx_vc9_core.vcproj @@ -4324,6 +4324,10 @@ RelativePath="..\..\include\wx\generic\gridctrl.h" > + + diff --git a/include/wx/generic/grid.h b/include/wx/generic/grid.h index c9ee2e7143..a6e5a5b1bf 100644 --- a/include/wx/generic/grid.h +++ b/include/wx/generic/grid.h @@ -90,6 +90,7 @@ class wxGridRowOperations; class wxGridColumnOperations; class wxGridDirectionOperations; + // ---------------------------------------------------------------------------- // macros // ---------------------------------------------------------------------------- @@ -168,129 +169,6 @@ public: virtual wxGridCellRenderer *Clone() const = 0; }; -// the default renderer for the cells containing string data -class WXDLLIMPEXP_ADV wxGridCellStringRenderer : public wxGridCellRenderer -{ -public: - // draw the string - virtual void Draw(wxGrid& grid, - wxGridCellAttr& attr, - wxDC& dc, - const wxRect& rect, - int row, int col, - bool isSelected); - - // return the string extent - virtual wxSize GetBestSize(wxGrid& grid, - wxGridCellAttr& attr, - wxDC& dc, - int row, int col); - - virtual wxGridCellRenderer *Clone() const - { return new wxGridCellStringRenderer; } - -protected: - // set the text colours before drawing - void SetTextColoursAndFont(const wxGrid& grid, - const wxGridCellAttr& attr, - wxDC& dc, - bool isSelected); - - // calc the string extent for given string/font - wxSize DoGetBestSize(const wxGridCellAttr& attr, - wxDC& dc, - const wxString& text); -}; - -// the default renderer for the cells containing numeric (long) data -class WXDLLIMPEXP_ADV wxGridCellNumberRenderer : public wxGridCellStringRenderer -{ -public: - // draw the string right aligned - virtual void Draw(wxGrid& grid, - wxGridCellAttr& attr, - wxDC& dc, - const wxRect& rect, - int row, int col, - bool isSelected); - - virtual wxSize GetBestSize(wxGrid& grid, - wxGridCellAttr& attr, - wxDC& dc, - int row, int col); - - virtual wxGridCellRenderer *Clone() const - { return new wxGridCellNumberRenderer; } - -protected: - wxString GetString(const wxGrid& grid, int row, int col); -}; - -class WXDLLIMPEXP_ADV wxGridCellFloatRenderer : public wxGridCellStringRenderer -{ -public: - wxGridCellFloatRenderer(int width = -1, int precision = -1); - - // get/change formatting parameters - int GetWidth() const { return m_width; } - void SetWidth(int width) { m_width = width; m_format.clear(); } - int GetPrecision() const { return m_precision; } - void SetPrecision(int precision) { m_precision = precision; m_format.clear(); } - - // draw the string right aligned with given width/precision - virtual void Draw(wxGrid& grid, - wxGridCellAttr& attr, - wxDC& dc, - const wxRect& rect, - int row, int col, - bool isSelected); - - virtual wxSize GetBestSize(wxGrid& grid, - wxGridCellAttr& attr, - wxDC& dc, - int row, int col); - - // parameters string format is "width[,precision]" - virtual void SetParameters(const wxString& params); - - virtual wxGridCellRenderer *Clone() const; - -protected: - wxString GetString(const wxGrid& grid, int row, int col); - -private: - // formatting parameters - int m_width, - m_precision; - - wxString m_format; -}; - -// renderer for boolean fields -class WXDLLIMPEXP_ADV wxGridCellBoolRenderer : public wxGridCellRenderer -{ -public: - // draw a check mark or nothing - virtual void Draw(wxGrid& grid, - wxGridCellAttr& attr, - wxDC& dc, - const wxRect& rect, - int row, int col, - bool isSelected); - - // return the checkmark size - virtual wxSize GetBestSize(wxGrid& grid, - wxGridCellAttr& attr, - wxDC& dc, - int row, int col); - - virtual wxGridCellRenderer *Clone() const - { return new wxGridCellBoolRenderer; } - -private: - static wxSize ms_sizeCheckMark; -}; - // ---------------------------------------------------------------------------- // wxGridCellEditor: This class is responsible for providing and manipulating // the in-place edit controls for the grid. Instances of wxGridCellEditor @@ -406,247 +284,6 @@ protected: DECLARE_NO_COPY_CLASS(wxGridCellEditor) }; -#if wxUSE_TEXTCTRL - -// the editor for string/text data -class WXDLLIMPEXP_ADV wxGridCellTextEditor : public wxGridCellEditor -{ -public: - wxGridCellTextEditor(); - - virtual void Create(wxWindow* parent, - wxWindowID id, - wxEvtHandler* evtHandler); - virtual void SetSize(const wxRect& rect); - - virtual void PaintBackground(const wxRect& rectCell, wxGridCellAttr *attr); - - virtual bool IsAcceptedKey(wxKeyEvent& event); - virtual void BeginEdit(int row, int col, wxGrid* grid); - virtual bool EndEdit(const wxString& oldval, wxString *newval); - virtual void ApplyEdit(int row, int col, wxGrid* grid); - - virtual void Reset(); - virtual void StartingKey(wxKeyEvent& event); - virtual void HandleReturn(wxKeyEvent& event); - - // parameters string format is "max_width" - virtual void SetParameters(const wxString& params); - - virtual wxGridCellEditor *Clone() const - { return new wxGridCellTextEditor; } - - // added GetValue so we can get the value which is in the control - virtual wxString GetValue() const; - -protected: - wxTextCtrl *Text() const { return (wxTextCtrl *)m_control; } - - // parts of our virtual functions reused by the derived classes - void DoCreate(wxWindow* parent, wxWindowID id, wxEvtHandler* evtHandler, - long style = 0); - void DoBeginEdit(const wxString& startValue); - void DoReset(const wxString& startValue); - -private: - size_t m_maxChars; // max number of chars allowed - wxString m_value; - - DECLARE_NO_COPY_CLASS(wxGridCellTextEditor) -}; - -// the editor for numeric (long) data -class WXDLLIMPEXP_ADV wxGridCellNumberEditor : public wxGridCellTextEditor -{ -public: - // allows to specify the range - if min == max == -1, no range checking is - // done - wxGridCellNumberEditor(int min = -1, int max = -1); - - virtual void Create(wxWindow* parent, - wxWindowID id, - wxEvtHandler* evtHandler); - - virtual bool IsAcceptedKey(wxKeyEvent& event); - virtual void BeginEdit(int row, int col, wxGrid* grid); - virtual bool EndEdit(const wxString& oldval, wxString *newval); - virtual void ApplyEdit(int row, int col, wxGrid* grid); - - virtual void Reset(); - virtual void StartingKey(wxKeyEvent& event); - - // parameters string format is "min,max" - virtual void SetParameters(const wxString& params); - - virtual wxGridCellEditor *Clone() const - { return new wxGridCellNumberEditor(m_min, m_max); } - - // added GetValue so we can get the value which is in the control - virtual wxString GetValue() const; - -protected: -#if wxUSE_SPINCTRL - wxSpinCtrl *Spin() const { return (wxSpinCtrl *)m_control; } -#endif - - // if HasRange(), we use wxSpinCtrl - otherwise wxTextCtrl - bool HasRange() const - { -#if wxUSE_SPINCTRL - return m_min != m_max; -#else - return false; -#endif - } - - // string representation of our value - wxString GetString() const - { return wxString::Format(_T("%ld"), m_value); } - -private: - int m_min, - m_max; - - long m_value; - - DECLARE_NO_COPY_CLASS(wxGridCellNumberEditor) -}; - -// the editor for floating point numbers (double) data -class WXDLLIMPEXP_ADV wxGridCellFloatEditor : public wxGridCellTextEditor -{ -public: - wxGridCellFloatEditor(int width = -1, int precision = -1); - - virtual void Create(wxWindow* parent, - wxWindowID id, - wxEvtHandler* evtHandler); - - virtual bool IsAcceptedKey(wxKeyEvent& event); - virtual void BeginEdit(int row, int col, wxGrid* grid); - virtual bool EndEdit(const wxString& oldval, wxString *newval); - virtual void ApplyEdit(int row, int col, wxGrid* grid); - - virtual void Reset(); - virtual void StartingKey(wxKeyEvent& event); - - virtual wxGridCellEditor *Clone() const - { return new wxGridCellFloatEditor(m_width, m_precision); } - - // parameters string format is "width,precision" - virtual void SetParameters(const wxString& params); - -protected: - // string representation of our value - wxString GetString() const; - -private: - int m_width, - m_precision; - double m_value; - - DECLARE_NO_COPY_CLASS(wxGridCellFloatEditor) -}; - -#endif // wxUSE_TEXTCTRL - -#if wxUSE_CHECKBOX - -// the editor for boolean data -class WXDLLIMPEXP_ADV wxGridCellBoolEditor : public wxGridCellEditor -{ -public: - wxGridCellBoolEditor() { } - - virtual void Create(wxWindow* parent, - wxWindowID id, - wxEvtHandler* evtHandler); - - virtual void SetSize(const wxRect& rect); - virtual void Show(bool show, wxGridCellAttr *attr = NULL); - - virtual bool IsAcceptedKey(wxKeyEvent& event); - virtual void BeginEdit(int row, int col, wxGrid* grid); - virtual bool EndEdit(const wxString& oldval, wxString *newval); - virtual void ApplyEdit(int row, int col, wxGrid* grid); - - virtual void Reset(); - virtual void StartingClick(); - virtual void StartingKey(wxKeyEvent& event); - - virtual wxGridCellEditor *Clone() const - { return new wxGridCellBoolEditor; } - - // added GetValue so we can get the value which is in the control, see - // also UseStringValues() - virtual wxString GetValue() const; - - // set the string values returned by GetValue() for the true and false - // states, respectively - static void UseStringValues(const wxString& valueTrue = _T("1"), - const wxString& valueFalse = wxEmptyString); - - // return true if the given string is equal to the string representation of - // true value which we currently use - static bool IsTrueValue(const wxString& value); - -protected: - wxCheckBox *CBox() const { return (wxCheckBox *)m_control; } - -private: - bool m_value; - - static wxString ms_stringValues[2]; - - DECLARE_NO_COPY_CLASS(wxGridCellBoolEditor) -}; - -#endif // wxUSE_CHECKBOX - -#if wxUSE_COMBOBOX - -// the editor for string data allowing to choose from the list of strings -class WXDLLIMPEXP_ADV wxGridCellChoiceEditor : public wxGridCellEditor -{ -public: - // if !allowOthers, user can't type a string not in choices array - wxGridCellChoiceEditor(size_t count = 0, - const wxString choices[] = NULL, - bool allowOthers = false); - wxGridCellChoiceEditor(const wxArrayString& choices, - bool allowOthers = false); - - virtual void Create(wxWindow* parent, - wxWindowID id, - wxEvtHandler* evtHandler); - - virtual void PaintBackground(const wxRect& rectCell, wxGridCellAttr *attr); - - virtual void BeginEdit(int row, int col, wxGrid* grid); - virtual bool EndEdit(const wxString& oldval, wxString *newval); - virtual void ApplyEdit(int row, int col, wxGrid* grid); - - virtual void Reset(); - - // parameters string format is "item1[,item2[...,itemN]]" - virtual void SetParameters(const wxString& params); - - virtual wxGridCellEditor *Clone() const; - - // added GetValue so we can get the value which is in the control - virtual wxString GetValue() const; - -protected: - wxComboBox *Combo() const { return (wxComboBox *)m_control; } - - wxString m_value; - wxArrayString m_choices; - bool m_allowOthers; - - DECLARE_NO_COPY_CLASS(wxGridCellChoiceEditor) -}; - -#endif // wxUSE_COMBOBOX // ---------------------------------------------------------------------------- // wxGridCellAttr: this class can be used to alter the cells appearance in diff --git a/include/wx/generic/gridctrl.h b/include/wx/generic/gridctrl.h index 748713f87b..987d2e9aed 100644 --- a/include/wx/generic/gridctrl.h +++ b/include/wx/generic/gridctrl.h @@ -19,6 +19,131 @@ #define wxGRID_VALUE_CHOICEINT _T("choiceint") #define wxGRID_VALUE_DATETIME _T("datetime") + +// the default renderer for the cells containing string data +class WXDLLIMPEXP_ADV wxGridCellStringRenderer : public wxGridCellRenderer +{ +public: + // draw the string + virtual void Draw(wxGrid& grid, + wxGridCellAttr& attr, + wxDC& dc, + const wxRect& rect, + int row, int col, + bool isSelected); + + // return the string extent + virtual wxSize GetBestSize(wxGrid& grid, + wxGridCellAttr& attr, + wxDC& dc, + int row, int col); + + virtual wxGridCellRenderer *Clone() const + { return new wxGridCellStringRenderer; } + +protected: + // set the text colours before drawing + void SetTextColoursAndFont(const wxGrid& grid, + const wxGridCellAttr& attr, + wxDC& dc, + bool isSelected); + + // calc the string extent for given string/font + wxSize DoGetBestSize(const wxGridCellAttr& attr, + wxDC& dc, + const wxString& text); +}; + +// the default renderer for the cells containing numeric (long) data +class WXDLLIMPEXP_ADV wxGridCellNumberRenderer : public wxGridCellStringRenderer +{ +public: + // draw the string right aligned + virtual void Draw(wxGrid& grid, + wxGridCellAttr& attr, + wxDC& dc, + const wxRect& rect, + int row, int col, + bool isSelected); + + virtual wxSize GetBestSize(wxGrid& grid, + wxGridCellAttr& attr, + wxDC& dc, + int row, int col); + + virtual wxGridCellRenderer *Clone() const + { return new wxGridCellNumberRenderer; } + +protected: + wxString GetString(const wxGrid& grid, int row, int col); +}; + +class WXDLLIMPEXP_ADV wxGridCellFloatRenderer : public wxGridCellStringRenderer +{ +public: + wxGridCellFloatRenderer(int width = -1, int precision = -1); + + // get/change formatting parameters + int GetWidth() const { return m_width; } + void SetWidth(int width) { m_width = width; m_format.clear(); } + int GetPrecision() const { return m_precision; } + void SetPrecision(int precision) { m_precision = precision; m_format.clear(); } + + // draw the string right aligned with given width/precision + virtual void Draw(wxGrid& grid, + wxGridCellAttr& attr, + wxDC& dc, + const wxRect& rect, + int row, int col, + bool isSelected); + + virtual wxSize GetBestSize(wxGrid& grid, + wxGridCellAttr& attr, + wxDC& dc, + int row, int col); + + // parameters string format is "width[,precision]" + virtual void SetParameters(const wxString& params); + + virtual wxGridCellRenderer *Clone() const; + +protected: + wxString GetString(const wxGrid& grid, int row, int col); + +private: + // formatting parameters + int m_width, + m_precision; + + wxString m_format; +}; + +// renderer for boolean fields +class WXDLLIMPEXP_ADV wxGridCellBoolRenderer : public wxGridCellRenderer +{ +public: + // draw a check mark or nothing + virtual void Draw(wxGrid& grid, + wxGridCellAttr& attr, + wxDC& dc, + const wxRect& rect, + int row, int col, + bool isSelected); + + // return the checkmark size + virtual wxSize GetBestSize(wxGrid& grid, + wxGridCellAttr& attr, + wxDC& dc, + int row, int col); + + virtual wxGridCellRenderer *Clone() const + { return new wxGridCellBoolRenderer; } + +private: + static wxSize ms_sizeCheckMark; +}; + + #if wxUSE_DATETIME #include "wx/datetime.h" @@ -90,42 +215,6 @@ protected: }; -#if wxUSE_COMBOBOX - -class WXDLLIMPEXP_ADV wxGridCellEnumEditor : public wxGridCellChoiceEditor -{ -public: - wxGridCellEnumEditor( const wxString& choices = wxEmptyString ); - virtual ~wxGridCellEnumEditor() {} - - virtual wxGridCellEditor* Clone() const; - - virtual void BeginEdit(int row, int col, wxGrid* grid); - virtual bool EndEdit(const wxString& oldval, wxString *newval); - virtual void ApplyEdit(int row, int col, wxGrid* grid); - -private: - long m_index; - - DECLARE_NO_COPY_CLASS(wxGridCellEnumEditor) -}; - -#endif // wxUSE_COMBOBOX - -class WXDLLIMPEXP_ADV wxGridCellAutoWrapStringEditor : public wxGridCellTextEditor -{ -public: - wxGridCellAutoWrapStringEditor() : wxGridCellTextEditor() { } - virtual void Create(wxWindow* parent, - wxWindowID id, - wxEvtHandler* evtHandler); - - virtual wxGridCellEditor *Clone() const - { return new wxGridCellAutoWrapStringEditor; } - - DECLARE_NO_COPY_CLASS(wxGridCellAutoWrapStringEditor) -}; - class WXDLLIMPEXP_ADV wxGridCellAutoWrapStringRenderer : public wxGridCellStringRenderer { public: diff --git a/include/wx/generic/grideditors.h b/include/wx/generic/grideditors.h new file mode 100644 index 0000000000..073d62662b --- /dev/null +++ b/include/wx/generic/grideditors.h @@ -0,0 +1,328 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: wx/generic/grideditors.h +// Purpose: wxGridCellEditorEvtHandler and wxGrid editors +// Author: Michael Bedward (based on code by Julian Smart, Robin Dunn) +// Modified by: Santiago Palacios +// Created: 1/08/1999 +// RCS-ID: $Id$ +// Copyright: (c) Michael Bedward +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_GENERIC_GRID_EDITORS_H_ +#define _WX_GENERIC_GRID_EDITORS_H_ + +#include "wx/defs.h" + +#if wxUSE_GRID + +class wxGridCellEditorEvtHandler : public wxEvtHandler +{ +public: + wxGridCellEditorEvtHandler(wxGrid* grid, wxGridCellEditor* editor) + : m_grid(grid), + m_editor(editor), + m_inSetFocus(false) + { + } + + void OnKillFocus(wxFocusEvent& event); + void OnKeyDown(wxKeyEvent& event); + void OnChar(wxKeyEvent& event); + + void SetInSetFocus(bool inSetFocus) { m_inSetFocus = inSetFocus; } + +private: + wxGrid *m_grid; + wxGridCellEditor *m_editor; + + // Work around the fact that a focus kill event can be sent to + // a combobox within a set focus event. + bool m_inSetFocus; + + DECLARE_EVENT_TABLE() + DECLARE_DYNAMIC_CLASS(wxGridCellEditorEvtHandler) + DECLARE_NO_COPY_CLASS(wxGridCellEditorEvtHandler) +}; + + +#if wxUSE_TEXTCTRL + +// the editor for string/text data +class WXDLLIMPEXP_ADV wxGridCellTextEditor : public wxGridCellEditor +{ +public: + wxGridCellTextEditor(); + + virtual void Create(wxWindow* parent, + wxWindowID id, + wxEvtHandler* evtHandler); + virtual void SetSize(const wxRect& rect); + + virtual void PaintBackground(const wxRect& rectCell, wxGridCellAttr *attr); + + virtual bool IsAcceptedKey(wxKeyEvent& event); + virtual void BeginEdit(int row, int col, wxGrid* grid); + virtual bool EndEdit(const wxString& oldval, wxString *newval); + virtual void ApplyEdit(int row, int col, wxGrid* grid); + + virtual void Reset(); + virtual void StartingKey(wxKeyEvent& event); + virtual void HandleReturn(wxKeyEvent& event); + + // parameters string format is "max_width" + virtual void SetParameters(const wxString& params); + + virtual wxGridCellEditor *Clone() const + { return new wxGridCellTextEditor; } + + // added GetValue so we can get the value which is in the control + virtual wxString GetValue() const; + +protected: + wxTextCtrl *Text() const { return (wxTextCtrl *)m_control; } + + // parts of our virtual functions reused by the derived classes + void DoCreate(wxWindow* parent, wxWindowID id, wxEvtHandler* evtHandler, + long style = 0); + void DoBeginEdit(const wxString& startValue); + void DoReset(const wxString& startValue); + +private: + size_t m_maxChars; // max number of chars allowed + wxString m_value; + + DECLARE_NO_COPY_CLASS(wxGridCellTextEditor) +}; + +// the editor for numeric (long) data +class WXDLLIMPEXP_ADV wxGridCellNumberEditor : public wxGridCellTextEditor +{ +public: + // allows to specify the range - if min == max == -1, no range checking is + // done + wxGridCellNumberEditor(int min = -1, int max = -1); + + virtual void Create(wxWindow* parent, + wxWindowID id, + wxEvtHandler* evtHandler); + + virtual bool IsAcceptedKey(wxKeyEvent& event); + virtual void BeginEdit(int row, int col, wxGrid* grid); + virtual bool EndEdit(const wxString& oldval, wxString *newval); + virtual void ApplyEdit(int row, int col, wxGrid* grid); + + virtual void Reset(); + virtual void StartingKey(wxKeyEvent& event); + + // parameters string format is "min,max" + virtual void SetParameters(const wxString& params); + + virtual wxGridCellEditor *Clone() const + { return new wxGridCellNumberEditor(m_min, m_max); } + + // added GetValue so we can get the value which is in the control + virtual wxString GetValue() const; + +protected: +#if wxUSE_SPINCTRL + wxSpinCtrl *Spin() const { return (wxSpinCtrl *)m_control; } +#endif + + // if HasRange(), we use wxSpinCtrl - otherwise wxTextCtrl + bool HasRange() const + { +#if wxUSE_SPINCTRL + return m_min != m_max; +#else + return false; +#endif + } + + // string representation of our value + wxString GetString() const + { return wxString::Format(_T("%ld"), m_value); } + +private: + int m_min, + m_max; + + long m_value; + + DECLARE_NO_COPY_CLASS(wxGridCellNumberEditor) +}; + +// the editor for floating point numbers (double) data +class WXDLLIMPEXP_ADV wxGridCellFloatEditor : public wxGridCellTextEditor +{ +public: + wxGridCellFloatEditor(int width = -1, int precision = -1); + + virtual void Create(wxWindow* parent, + wxWindowID id, + wxEvtHandler* evtHandler); + + virtual bool IsAcceptedKey(wxKeyEvent& event); + virtual void BeginEdit(int row, int col, wxGrid* grid); + virtual bool EndEdit(const wxString& oldval, wxString *newval); + virtual void ApplyEdit(int row, int col, wxGrid* grid); + + virtual void Reset(); + virtual void StartingKey(wxKeyEvent& event); + + virtual wxGridCellEditor *Clone() const + { return new wxGridCellFloatEditor(m_width, m_precision); } + + // parameters string format is "width,precision" + virtual void SetParameters(const wxString& params); + +protected: + // string representation of our value + wxString GetString() const; + +private: + int m_width, + m_precision; + double m_value; + + DECLARE_NO_COPY_CLASS(wxGridCellFloatEditor) +}; + +#endif // wxUSE_TEXTCTRL + +#if wxUSE_CHECKBOX + +// the editor for boolean data +class WXDLLIMPEXP_ADV wxGridCellBoolEditor : public wxGridCellEditor +{ +public: + wxGridCellBoolEditor() { } + + virtual void Create(wxWindow* parent, + wxWindowID id, + wxEvtHandler* evtHandler); + + virtual void SetSize(const wxRect& rect); + virtual void Show(bool show, wxGridCellAttr *attr = NULL); + + virtual bool IsAcceptedKey(wxKeyEvent& event); + virtual void BeginEdit(int row, int col, wxGrid* grid); + virtual bool EndEdit(const wxString& oldval, wxString *newval); + virtual void ApplyEdit(int row, int col, wxGrid* grid); + + virtual void Reset(); + virtual void StartingClick(); + virtual void StartingKey(wxKeyEvent& event); + + virtual wxGridCellEditor *Clone() const + { return new wxGridCellBoolEditor; } + + // added GetValue so we can get the value which is in the control, see + // also UseStringValues() + virtual wxString GetValue() const; + + // set the string values returned by GetValue() for the true and false + // states, respectively + static void UseStringValues(const wxString& valueTrue = _T("1"), + const wxString& valueFalse = wxEmptyString); + + // return true if the given string is equal to the string representation of + // true value which we currently use + static bool IsTrueValue(const wxString& value); + +protected: + wxCheckBox *CBox() const { return (wxCheckBox *)m_control; } + +private: + bool m_value; + + static wxString ms_stringValues[2]; + + DECLARE_NO_COPY_CLASS(wxGridCellBoolEditor) +}; + +#endif // wxUSE_CHECKBOX + +#if wxUSE_COMBOBOX + +// the editor for string data allowing to choose from the list of strings +class WXDLLIMPEXP_ADV wxGridCellChoiceEditor : public wxGridCellEditor +{ +public: + // if !allowOthers, user can't type a string not in choices array + wxGridCellChoiceEditor(size_t count = 0, + const wxString choices[] = NULL, + bool allowOthers = false); + wxGridCellChoiceEditor(const wxArrayString& choices, + bool allowOthers = false); + + virtual void Create(wxWindow* parent, + wxWindowID id, + wxEvtHandler* evtHandler); + + virtual void PaintBackground(const wxRect& rectCell, wxGridCellAttr *attr); + + virtual void BeginEdit(int row, int col, wxGrid* grid); + virtual bool EndEdit(const wxString& oldval, wxString *newval); + virtual void ApplyEdit(int row, int col, wxGrid* grid); + + virtual void Reset(); + + // parameters string format is "item1[,item2[...,itemN]]" + virtual void SetParameters(const wxString& params); + + virtual wxGridCellEditor *Clone() const; + + // added GetValue so we can get the value which is in the control + virtual wxString GetValue() const; + +protected: + wxComboBox *Combo() const { return (wxComboBox *)m_control; } + + wxString m_value; + wxArrayString m_choices; + bool m_allowOthers; + + DECLARE_NO_COPY_CLASS(wxGridCellChoiceEditor) +}; + +#endif // wxUSE_COMBOBOX + +#if wxUSE_COMBOBOX + +class WXDLLIMPEXP_ADV wxGridCellEnumEditor : public wxGridCellChoiceEditor +{ +public: + wxGridCellEnumEditor( const wxString& choices = wxEmptyString ); + virtual ~wxGridCellEnumEditor() {} + + virtual wxGridCellEditor* Clone() const; + + virtual void BeginEdit(int row, int col, wxGrid* grid); + virtual bool EndEdit(const wxString& oldval, wxString *newval); + virtual void ApplyEdit(int row, int col, wxGrid* grid); + +private: + long m_index; + + DECLARE_NO_COPY_CLASS(wxGridCellEnumEditor) +}; + +#endif // wxUSE_COMBOBOX + +class WXDLLIMPEXP_ADV wxGridCellAutoWrapStringEditor : public wxGridCellTextEditor +{ +public: + wxGridCellAutoWrapStringEditor() : wxGridCellTextEditor() { } + virtual void Create(wxWindow* parent, + wxWindowID id, + wxEvtHandler* evtHandler); + + virtual wxGridCellEditor *Clone() const + { return new wxGridCellAutoWrapStringEditor; } + + DECLARE_NO_COPY_CLASS(wxGridCellAutoWrapStringEditor) +}; + +#endif // wxUSE_GRID +#endif // _WX_GENERIC_GRID_EDITORS_H_ diff --git a/include/wx/generic/private/grid.h b/include/wx/generic/private/grid.h new file mode 100644 index 0000000000..e2ed4757d8 --- /dev/null +++ b/include/wx/generic/private/grid.h @@ -0,0 +1,826 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: wx/generic/private/grid.h +// Purpose: Private wxGrid structures +// Author: Michael Bedward (based on code by Julian Smart, Robin Dunn) +// Modified by: Santiago Palacios +// Created: 1/08/1999 +// RCS-ID: $Id$ +// Copyright: (c) Michael Bedward +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_GENERIC_GRID_PRIVATE_H_ +#define _WX_GENERIC_GRID_PRIVATE_H_ + +#include "wx/defs.h" + +#if wxUSE_GRID + +// ---------------------------------------------------------------------------- +// array classes +// ---------------------------------------------------------------------------- + +WX_DEFINE_ARRAY_WITH_DECL_PTR(wxGridCellAttr *, wxArrayAttrs, + class WXDLLIMPEXP_ADV); + +struct wxGridCellWithAttr +{ + wxGridCellWithAttr(int row, int col, wxGridCellAttr *attr_) + : coords(row, col), attr(attr_) + { + wxASSERT( attr ); + } + + wxGridCellWithAttr(const wxGridCellWithAttr& other) + : coords(other.coords), + attr(other.attr) + { + attr->IncRef(); + } + + wxGridCellWithAttr& operator=(const wxGridCellWithAttr& other) + { + coords = other.coords; + if (attr != other.attr) + { + attr->DecRef(); + attr = other.attr; + attr->IncRef(); + } + return *this; + } + + void ChangeAttr(wxGridCellAttr* new_attr) + { + if (attr != new_attr) + { + // "Delete" (i.e. DecRef) the old attribute. + attr->DecRef(); + attr = new_attr; + // Take ownership of the new attribute, i.e. no IncRef. + } + } + + ~wxGridCellWithAttr() + { + attr->DecRef(); + } + + wxGridCellCoords coords; + wxGridCellAttr *attr; +}; + +WX_DECLARE_OBJARRAY_WITH_DECL(wxGridCellWithAttr, wxGridCellWithAttrArray, + class WXDLLIMPEXP_ADV); + + +// ---------------------------------------------------------------------------- +// private classes +// ---------------------------------------------------------------------------- + +// header column providing access to the column information stored in wxGrid +// via wxHeaderColumn interface +class wxGridHeaderColumn : public wxHeaderColumn +{ +public: + wxGridHeaderColumn(wxGrid *grid, int col) + : m_grid(grid), + m_col(col) + { + } + + virtual wxString GetTitle() const { return m_grid->GetColLabelValue(m_col); } + virtual wxBitmap GetBitmap() const { return wxNullBitmap; } + virtual int GetWidth() const { return m_grid->GetColSize(m_col); } + virtual int GetMinWidth() const { return 0; } + virtual wxAlignment GetAlignment() const + { + int horz, + vert; + m_grid->GetColLabelAlignment(&horz, &vert); + + return static_cast(horz); + } + + virtual int GetFlags() const + { + // we can't know in advance whether we can sort by this column or not + // with wxGrid API so suppose we can by default + int flags = wxCOL_SORTABLE; + if ( m_grid->CanDragColSize() ) + flags |= wxCOL_RESIZABLE; + if ( m_grid->CanDragColMove() ) + flags |= wxCOL_REORDERABLE; + if ( GetWidth() == 0 ) + flags |= wxCOL_HIDDEN; + + return flags; + } + + virtual bool IsSortKey() const + { + return m_grid->IsSortingBy(m_col); + } + + virtual bool IsSortOrderAscending() const + { + return m_grid->IsSortOrderAscending(); + } + +private: + // these really should be const but are not because the column needs to be + // assignable to be used in a wxVector (in STL build, in non-STL build we + // avoid the need for this) + wxGrid *m_grid; + int m_col; +}; + +// header control retreiving column information from the grid +class wxGridHeaderCtrl : public wxHeaderCtrl +{ +public: + wxGridHeaderCtrl(wxGrid *owner) + : wxHeaderCtrl(owner, + wxID_ANY, + wxDefaultPosition, + wxDefaultSize, + wxHD_ALLOW_HIDE | + (owner->CanDragColMove() ? wxHD_ALLOW_REORDER : 0)) + { + } + +protected: + virtual const wxHeaderColumn& GetColumn(unsigned int idx) const + { + return m_columns[idx]; + } + +private: + wxGrid *GetOwner() const { return static_cast(GetParent()); } + + // override the base class method to update our m_columns array + virtual void OnColumnCountChanging(unsigned int count) + { + const unsigned countOld = m_columns.size(); + if ( count < countOld ) + { + // just discard the columns which don't exist any more (notice that + // we can't use resize() here as it would require the vector + // value_type, i.e. wxGridHeaderColumn to be default constructible, + // which it is not) + m_columns.erase(m_columns.begin() + count, m_columns.end()); + } + else // new columns added + { + // add columns for the new elements + for ( unsigned n = countOld; n < count; n++ ) + m_columns.push_back(wxGridHeaderColumn(GetOwner(), n)); + } + } + + // override to implement column auto sizing + virtual bool UpdateColumnWidthToFit(unsigned int idx, int widthTitle) + { + // TODO: currently grid doesn't support computing the column best width + // from its contents so we just use the best label width as is + GetOwner()->SetColSize(idx, widthTitle); + + return true; + } + + // overridden to react to the actions using the columns popup menu + virtual void UpdateColumnVisibility(unsigned int idx, bool show) + { + GetOwner()->SetColSize(idx, show ? wxGRID_AUTOSIZE : 0); + + // as this is done by the user we should notify the main program about + // it + GetOwner()->SendEvent(wxEVT_GRID_COL_SIZE, -1, idx); + } + + // overridden to react to the columns order changes in the customization + // dialog + virtual void UpdateColumnsOrder(const wxArrayInt& order) + { + GetOwner()->SetColumnsOrder(order); + } + + + // event handlers forwarding wxHeaderCtrl events to wxGrid + void OnClick(wxHeaderCtrlEvent& event) + { + GetOwner()->DoColHeaderClick(event.GetColumn()); + } + + void OnBeginResize(wxHeaderCtrlEvent& event) + { + GetOwner()->DoStartResizeCol(event.GetColumn()); + + event.Skip(); + } + + void OnResizing(wxHeaderCtrlEvent& event) + { + GetOwner()->DoUpdateResizeColWidth(event.GetWidth()); + } + + void OnEndResize(wxHeaderCtrlEvent& event) + { + GetOwner()->DoEndDragResizeCol(); + + event.Skip(); + } + + void OnBeginReorder(wxHeaderCtrlEvent& event) + { + GetOwner()->DoStartMoveCol(event.GetColumn()); + } + + void OnEndReorder(wxHeaderCtrlEvent& event) + { + GetOwner()->DoEndMoveCol(event.GetNewOrder()); + } + + wxVector m_columns; + + DECLARE_EVENT_TABLE() + DECLARE_NO_COPY_CLASS(wxGridHeaderCtrl) +}; + +// common base class for various grid subwindows +class WXDLLIMPEXP_ADV wxGridSubwindow : public wxWindow +{ +public: + wxGridSubwindow(wxGrid *owner, + int additionalStyle = 0, + const wxString& name = wxPanelNameStr) + : wxWindow(owner, wxID_ANY, + wxDefaultPosition, wxDefaultSize, + wxBORDER_NONE | additionalStyle, + name) + { + m_owner = owner; + } + + virtual bool AcceptsFocus() const { return false; } + + wxGrid *GetOwner() { return m_owner; } + +protected: + void OnMouseCaptureLost(wxMouseCaptureLostEvent& event); + + wxGrid *m_owner; + + DECLARE_EVENT_TABLE() + DECLARE_NO_COPY_CLASS(wxGridSubwindow) +}; + +class WXDLLIMPEXP_ADV wxGridRowLabelWindow : public wxGridSubwindow +{ +public: + wxGridRowLabelWindow(wxGrid *parent) + : wxGridSubwindow(parent) + { + } + + +private: + void OnPaint( wxPaintEvent& event ); + void OnMouseEvent( wxMouseEvent& event ); + void OnMouseWheel( wxMouseEvent& event ); + + DECLARE_EVENT_TABLE() + DECLARE_NO_COPY_CLASS(wxGridRowLabelWindow) +}; + + +class WXDLLIMPEXP_ADV wxGridColLabelWindow : public wxGridSubwindow +{ +public: + wxGridColLabelWindow(wxGrid *parent) + : wxGridSubwindow(parent) + { + } + + +private: + void OnPaint( wxPaintEvent& event ); + void OnMouseEvent( wxMouseEvent& event ); + void OnMouseWheel( wxMouseEvent& event ); + + DECLARE_EVENT_TABLE() + DECLARE_NO_COPY_CLASS(wxGridColLabelWindow) +}; + + +class WXDLLIMPEXP_ADV wxGridCornerLabelWindow : public wxGridSubwindow +{ +public: + wxGridCornerLabelWindow(wxGrid *parent) + : wxGridSubwindow(parent) + { + } + +private: + void OnMouseEvent( wxMouseEvent& event ); + void OnMouseWheel( wxMouseEvent& event ); + void OnPaint( wxPaintEvent& event ); + + DECLARE_EVENT_TABLE() + DECLARE_NO_COPY_CLASS(wxGridCornerLabelWindow) +}; + +class WXDLLIMPEXP_ADV wxGridWindow : public wxGridSubwindow +{ +public: + wxGridWindow(wxGrid *parent) + : wxGridSubwindow(parent, + wxWANTS_CHARS | wxCLIP_CHILDREN, + "GridWindow") + { + } + + + virtual void ScrollWindow( int dx, int dy, const wxRect *rect ); + + virtual bool AcceptsFocus() const { return true; } + +private: + void OnPaint( wxPaintEvent &event ); + void OnMouseWheel( wxMouseEvent& event ); + void OnMouseEvent( wxMouseEvent& event ); + void OnKeyDown( wxKeyEvent& ); + void OnKeyUp( wxKeyEvent& ); + void OnChar( wxKeyEvent& ); + void OnEraseBackground( wxEraseEvent& ); + void OnFocus( wxFocusEvent& ); + + DECLARE_EVENT_TABLE() + DECLARE_NO_COPY_CLASS(wxGridWindow) +}; + +// ---------------------------------------------------------------------------- +// the internal data representation used by wxGridCellAttrProvider +// ---------------------------------------------------------------------------- + +// this class stores attributes set for cells +class WXDLLIMPEXP_ADV wxGridCellAttrData +{ +public: + void SetAttr(wxGridCellAttr *attr, int row, int col); + wxGridCellAttr *GetAttr(int row, int col) const; + void UpdateAttrRows( size_t pos, int numRows ); + void UpdateAttrCols( size_t pos, int numCols ); + +private: + // searches for the attr for given cell, returns wxNOT_FOUND if not found + int FindIndex(int row, int col) const; + + wxGridCellWithAttrArray m_attrs; +}; + +// this class stores attributes set for rows or columns +class WXDLLIMPEXP_ADV wxGridRowOrColAttrData +{ +public: + // empty ctor to suppress warnings + wxGridRowOrColAttrData() {} + ~wxGridRowOrColAttrData(); + + void SetAttr(wxGridCellAttr *attr, int rowOrCol); + wxGridCellAttr *GetAttr(int rowOrCol) const; + void UpdateAttrRowsOrCols( size_t pos, int numRowsOrCols ); + +private: + wxArrayInt m_rowsOrCols; + wxArrayAttrs m_attrs; +}; + +// NB: this is just a wrapper around 3 objects: one which stores cell +// attributes, and 2 others for row/col ones +class WXDLLIMPEXP_ADV wxGridCellAttrProviderData +{ +public: + wxGridCellAttrData m_cellAttrs; + wxGridRowOrColAttrData m_rowAttrs, + m_colAttrs; +}; + +// ---------------------------------------------------------------------------- +// operations classes abstracting the difference between operating on rows and +// columns +// ---------------------------------------------------------------------------- + +// This class allows to write a function only once because by using its methods +// it will apply to both columns and rows. +// +// This is an abstract interface definition, the two concrete implementations +// below should be used when working with rows and columns respectively. +class wxGridOperations +{ +public: + // Returns the operations in the other direction, i.e. wxGridRowOperations + // if this object is a wxGridColumnOperations and vice versa. + virtual wxGridOperations& Dual() const = 0; + + // Return the number of rows or columns. + virtual int GetNumberOfLines(const wxGrid *grid) const = 0; + + // Return the selection mode which allows selecting rows or columns. + virtual wxGrid::wxGridSelectionModes GetSelectionMode() const = 0; + + // Make a wxGridCellCoords from the given components: thisDir is row or + // column and otherDir is column or row + virtual wxGridCellCoords MakeCoords(int thisDir, int otherDir) const = 0; + + // Calculate the scrolled position of the given abscissa or ordinate. + virtual int CalcScrolledPosition(wxGrid *grid, int pos) const = 0; + + // Selects the horizontal or vertical component from the given object. + virtual int Select(const wxGridCellCoords& coords) const = 0; + virtual int Select(const wxPoint& pt) const = 0; + virtual int Select(const wxSize& sz) const = 0; + virtual int Select(const wxRect& r) const = 0; + virtual int& Select(wxRect& r) const = 0; + + // Returns width or height of the rectangle + virtual int& SelectSize(wxRect& r) const = 0; + + // Make a wxSize such that Select() applied to it returns first component + virtual wxSize MakeSize(int first, int second) const = 0; + + // Sets the row or column component of the given cell coordinates + virtual void Set(wxGridCellCoords& coords, int line) const = 0; + + + // Draws a line parallel to the row or column, i.e. horizontal or vertical: + // pos is the horizontal or vertical position of the line and start and end + // are the coordinates of the line extremities in the other direction + virtual void + DrawParallelLine(wxDC& dc, int start, int end, int pos) const = 0; + + // Draw a horizontal or vertical line across the given rectangle + // (this is implemented in terms of above and uses Select() to extract + // start and end from the given rectangle) + void DrawParallelLineInRect(wxDC& dc, const wxRect& rect, int pos) const + { + const int posStart = Select(rect.GetPosition()); + DrawParallelLine(dc, posStart, posStart + Select(rect.GetSize()), pos); + } + + + // Return the index of the row or column at the given pixel coordinate. + virtual int + PosToLine(const wxGrid *grid, int pos, bool clip = false) const = 0; + + // Get the top/left position, in pixels, of the given row or column + virtual int GetLineStartPos(const wxGrid *grid, int line) const = 0; + + // Get the bottom/right position, in pixels, of the given row or column + virtual int GetLineEndPos(const wxGrid *grid, int line) const = 0; + + // Get the height/width of the given row/column + virtual int GetLineSize(const wxGrid *grid, int line) const = 0; + + // Get wxGrid::m_rowBottoms/m_colRights array + virtual const wxArrayInt& GetLineEnds(const wxGrid *grid) const = 0; + + // Get default height row height or column width + virtual int GetDefaultLineSize(const wxGrid *grid) const = 0; + + // Return the minimal acceptable row height or column width + virtual int GetMinimalAcceptableLineSize(const wxGrid *grid) const = 0; + + // Return the minimal row height or column width + virtual int GetMinimalLineSize(const wxGrid *grid, int line) const = 0; + + // Set the row height or column width + virtual void SetLineSize(wxGrid *grid, int line, int size) const = 0; + + // True if rows/columns can be resized by user + virtual bool CanResizeLines(const wxGrid *grid) const = 0; + + + // Return the index of the line at the given position + // + // NB: currently this is always identity for the rows as reordering is only + // implemented for the lines + virtual int GetLineAt(const wxGrid *grid, int line) const = 0; + + + // Get the row or column label window + virtual wxWindow *GetHeaderWindow(wxGrid *grid) const = 0; + + // Get the width or height of the row or column label window + virtual int GetHeaderWindowSize(wxGrid *grid) const = 0; + + + // This class is never used polymorphically but give it a virtual dtor + // anyhow to suppress g++ complaints about it + virtual ~wxGridOperations() { } +}; + +class wxGridRowOperations : public wxGridOperations +{ +public: + virtual wxGridOperations& Dual() const; + + virtual int GetNumberOfLines(const wxGrid *grid) const + { return grid->GetNumberRows(); } + + virtual wxGrid::wxGridSelectionModes GetSelectionMode() const + { return wxGrid::wxGridSelectRows; } + + virtual wxGridCellCoords MakeCoords(int thisDir, int otherDir) const + { return wxGridCellCoords(thisDir, otherDir); } + + virtual int CalcScrolledPosition(wxGrid *grid, int pos) const + { return grid->CalcScrolledPosition(wxPoint(pos, 0)).x; } + + virtual int Select(const wxGridCellCoords& c) const { return c.GetRow(); } + virtual int Select(const wxPoint& pt) const { return pt.x; } + virtual int Select(const wxSize& sz) const { return sz.x; } + virtual int Select(const wxRect& r) const { return r.x; } + virtual int& Select(wxRect& r) const { return r.x; } + virtual int& SelectSize(wxRect& r) const { return r.width; } + virtual wxSize MakeSize(int first, int second) const + { return wxSize(first, second); } + virtual void Set(wxGridCellCoords& coords, int line) const + { coords.SetRow(line); } + + virtual void DrawParallelLine(wxDC& dc, int start, int end, int pos) const + { dc.DrawLine(start, pos, end, pos); } + + virtual int PosToLine(const wxGrid *grid, int pos, bool clip = false) const + { return grid->YToRow(pos, clip); } + virtual int GetLineStartPos(const wxGrid *grid, int line) const + { return grid->GetRowTop(line); } + virtual int GetLineEndPos(const wxGrid *grid, int line) const + { return grid->GetRowBottom(line); } + virtual int GetLineSize(const wxGrid *grid, int line) const + { return grid->GetRowHeight(line); } + virtual const wxArrayInt& GetLineEnds(const wxGrid *grid) const + { return grid->m_rowBottoms; } + virtual int GetDefaultLineSize(const wxGrid *grid) const + { return grid->GetDefaultRowSize(); } + virtual int GetMinimalAcceptableLineSize(const wxGrid *grid) const + { return grid->GetRowMinimalAcceptableHeight(); } + virtual int GetMinimalLineSize(const wxGrid *grid, int line) const + { return grid->GetRowMinimalHeight(line); } + virtual void SetLineSize(wxGrid *grid, int line, int size) const + { grid->SetRowSize(line, size); } + virtual bool CanResizeLines(const wxGrid *grid) const + { return grid->CanDragRowSize(); } + + virtual int GetLineAt(const wxGrid * WXUNUSED(grid), int line) const + { return line; } // TODO: implement row reordering + + virtual wxWindow *GetHeaderWindow(wxGrid *grid) const + { return grid->GetGridRowLabelWindow(); } + virtual int GetHeaderWindowSize(wxGrid *grid) const + { return grid->GetRowLabelSize(); } +}; + +class wxGridColumnOperations : public wxGridOperations +{ +public: + virtual wxGridOperations& Dual() const; + + virtual int GetNumberOfLines(const wxGrid *grid) const + { return grid->GetNumberCols(); } + + virtual wxGrid::wxGridSelectionModes GetSelectionMode() const + { return wxGrid::wxGridSelectColumns; } + + virtual wxGridCellCoords MakeCoords(int thisDir, int otherDir) const + { return wxGridCellCoords(otherDir, thisDir); } + + virtual int CalcScrolledPosition(wxGrid *grid, int pos) const + { return grid->CalcScrolledPosition(wxPoint(0, pos)).y; } + + virtual int Select(const wxGridCellCoords& c) const { return c.GetCol(); } + virtual int Select(const wxPoint& pt) const { return pt.y; } + virtual int Select(const wxSize& sz) const { return sz.y; } + virtual int Select(const wxRect& r) const { return r.y; } + virtual int& Select(wxRect& r) const { return r.y; } + virtual int& SelectSize(wxRect& r) const { return r.height; } + virtual wxSize MakeSize(int first, int second) const + { return wxSize(second, first); } + virtual void Set(wxGridCellCoords& coords, int line) const + { coords.SetCol(line); } + + virtual void DrawParallelLine(wxDC& dc, int start, int end, int pos) const + { dc.DrawLine(pos, start, pos, end); } + + virtual int PosToLine(const wxGrid *grid, int pos, bool clip = false) const + { return grid->XToCol(pos, clip); } + virtual int GetLineStartPos(const wxGrid *grid, int line) const + { return grid->GetColLeft(line); } + virtual int GetLineEndPos(const wxGrid *grid, int line) const + { return grid->GetColRight(line); } + virtual int GetLineSize(const wxGrid *grid, int line) const + { return grid->GetColWidth(line); } + virtual const wxArrayInt& GetLineEnds(const wxGrid *grid) const + { return grid->m_colRights; } + virtual int GetDefaultLineSize(const wxGrid *grid) const + { return grid->GetDefaultColSize(); } + virtual int GetMinimalAcceptableLineSize(const wxGrid *grid) const + { return grid->GetColMinimalAcceptableWidth(); } + virtual int GetMinimalLineSize(const wxGrid *grid, int line) const + { return grid->GetColMinimalWidth(line); } + virtual void SetLineSize(wxGrid *grid, int line, int size) const + { grid->SetColSize(line, size); } + virtual bool CanResizeLines(const wxGrid *grid) const + { return grid->CanDragColSize(); } + + virtual int GetLineAt(const wxGrid *grid, int line) const + { return grid->GetColAt(line); } + + virtual wxWindow *GetHeaderWindow(wxGrid *grid) const + { return grid->GetGridColLabelWindow(); } + virtual int GetHeaderWindowSize(wxGrid *grid) const + { return grid->GetColLabelSize(); } +}; + +// This class abstracts the difference between operations going forward +// (down/right) and backward (up/left) and allows to use the same code for +// functions which differ only in the direction of grid traversal +// +// Like wxGridOperations it's an ABC with two concrete subclasses below. Unlike +// it, this is a normal object and not just a function dispatch table and has a +// non-default ctor. +// +// Note: the explanation of this discrepancy is the existence of (very useful) +// Dual() method in wxGridOperations which forces us to make wxGridOperations a +// function dispatcher only. +class wxGridDirectionOperations +{ +public: + // The oper parameter to ctor selects whether we work with rows or columns + wxGridDirectionOperations(wxGrid *grid, const wxGridOperations& oper) + : m_grid(grid), + m_oper(oper) + { + } + + // Check if the component of this point in our direction is at the + // boundary, i.e. is the first/last row/column + virtual bool IsAtBoundary(const wxGridCellCoords& coords) const = 0; + + // Increment the component of this point in our direction + virtual void Advance(wxGridCellCoords& coords) const = 0; + + // Find the line at the given distance, in pixels, away from this one + // (this uses clipping, i.e. anything after the last line is counted as the + // last one and anything before the first one as 0) + virtual int MoveByPixelDistance(int line, int distance) const = 0; + + // This class is never used polymorphically but give it a virtual dtor + // anyhow to suppress g++ complaints about it + virtual ~wxGridDirectionOperations() { } + +protected: + wxGrid * const m_grid; + const wxGridOperations& m_oper; +}; + +class wxGridBackwardOperations : public wxGridDirectionOperations +{ +public: + wxGridBackwardOperations(wxGrid *grid, const wxGridOperations& oper) + : wxGridDirectionOperations(grid, oper) + { + } + + virtual bool IsAtBoundary(const wxGridCellCoords& coords) const + { + wxASSERT_MSG( m_oper.Select(coords) >= 0, "invalid row/column" ); + + return m_oper.Select(coords) == 0; + } + + virtual void Advance(wxGridCellCoords& coords) const + { + wxASSERT( !IsAtBoundary(coords) ); + + m_oper.Set(coords, m_oper.Select(coords) - 1); + } + + virtual int MoveByPixelDistance(int line, int distance) const + { + int pos = m_oper.GetLineStartPos(m_grid, line); + return m_oper.PosToLine(m_grid, pos - distance + 1, true); + } +}; + +class wxGridForwardOperations : public wxGridDirectionOperations +{ +public: + wxGridForwardOperations(wxGrid *grid, const wxGridOperations& oper) + : wxGridDirectionOperations(grid, oper), + m_numLines(oper.GetNumberOfLines(grid)) + { + } + + virtual bool IsAtBoundary(const wxGridCellCoords& coords) const + { + wxASSERT_MSG( m_oper.Select(coords) < m_numLines, "invalid row/column" ); + + return m_oper.Select(coords) == m_numLines - 1; + } + + virtual void Advance(wxGridCellCoords& coords) const + { + wxASSERT( !IsAtBoundary(coords) ); + + m_oper.Set(coords, m_oper.Select(coords) + 1); + } + + virtual int MoveByPixelDistance(int line, int distance) const + { + int pos = m_oper.GetLineStartPos(m_grid, line); + return m_oper.PosToLine(m_grid, pos + distance, true); + } + +private: + const int m_numLines; +}; + +// ---------------------------------------------------------------------------- +// private helpers +// ---------------------------------------------------------------------------- + +namespace +{ + +// ensure that first is less or equal to second, swapping the values if +// necessary +void EnsureFirstLessThanSecond(int& first, int& second) +{ + if ( first > second ) + wxSwap(first, second); +} + +} // anonymous namespace + +// ---------------------------------------------------------------------------- +// data structures used for the data type registry +// ---------------------------------------------------------------------------- + +struct wxGridDataTypeInfo +{ + wxGridDataTypeInfo(const wxString& typeName, + wxGridCellRenderer* renderer, + wxGridCellEditor* editor) + : m_typeName(typeName), m_renderer(renderer), m_editor(editor) + {} + + ~wxGridDataTypeInfo() + { + wxSafeDecRef(m_renderer); + wxSafeDecRef(m_editor); + } + + wxString m_typeName; + wxGridCellRenderer* m_renderer; + wxGridCellEditor* m_editor; + + DECLARE_NO_COPY_CLASS(wxGridDataTypeInfo) +}; + + +WX_DEFINE_ARRAY_WITH_DECL_PTR(wxGridDataTypeInfo*, wxGridDataTypeInfoArray, + class WXDLLIMPEXP_ADV); + + +class WXDLLIMPEXP_ADV wxGridTypeRegistry +{ +public: + wxGridTypeRegistry() {} + ~wxGridTypeRegistry(); + + void RegisterDataType(const wxString& typeName, + wxGridCellRenderer* renderer, + wxGridCellEditor* editor); + + // find one of already registered data types + int FindRegisteredDataType(const wxString& typeName); + + // try to FindRegisteredDataType(), if this fails and typeName is one of + // standard typenames, register it and return its index + int FindDataType(const wxString& typeName); + + // try to FindDataType(), if it fails see if it is not one of already + // registered data types with some params in which case clone the + // registered data type and set params for it + int FindOrCloneDataType(const wxString& typeName); + + wxGridCellRenderer* GetRenderer(int index); + wxGridCellEditor* GetEditor(int index); + +private: + wxGridDataTypeInfoArray m_typeinfo; +}; + +#endif // wxUSE_GRID +#endif // _WX_GENERIC_GRID_PRIVATE_H_ diff --git a/src/generic/grid.cpp b/src/generic/grid.cpp index 1da201ad36..aff01b06a9 100644 --- a/src/generic/grid.cpp +++ b/src/generic/grid.cpp @@ -50,6 +50,9 @@ #include "wx/headerctrl.h" #include "wx/generic/gridsel.h" +#include "wx/generic/gridctrl.h" +#include "wx/generic/grideditors.h" +#include "wx/generic/private/grid.h" const char wxGridNameStr[] = "grid"; @@ -68,62 +71,40 @@ const char wxGridNameStr[] = "grid"; // Required for wxIs... functions #include + // ---------------------------------------------------------------------------- -// array classes +// globals // ---------------------------------------------------------------------------- -WX_DEFINE_ARRAY_WITH_DECL_PTR(wxGridCellAttr *, wxArrayAttrs, - class WXDLLIMPEXP_ADV); +//#define DEBUG_ATTR_CACHE +#ifdef DEBUG_ATTR_CACHE + static size_t gs_nAttrCacheHits = 0; + static size_t gs_nAttrCacheMisses = 0; +#endif -struct wxGridCellWithAttr -{ - wxGridCellWithAttr(int row, int col, wxGridCellAttr *attr_) - : coords(row, col), attr(attr_) - { - wxASSERT( attr ); - } +// ---------------------------------------------------------------------------- +// constants +// ---------------------------------------------------------------------------- - wxGridCellWithAttr(const wxGridCellWithAttr& other) - : coords(other.coords), - attr(other.attr) - { - attr->IncRef(); - } +wxGridCellCoords wxGridNoCellCoords( -1, -1 ); +wxRect wxGridNoCellRect( -1, -1, -1, -1 ); - wxGridCellWithAttr& operator=(const wxGridCellWithAttr& other) - { - coords = other.coords; - if (attr != other.attr) - { - attr->DecRef(); - attr = other.attr; - attr->IncRef(); - } - return *this; - } +namespace +{ - void ChangeAttr(wxGridCellAttr* new_attr) - { - if (attr != new_attr) - { - // "Delete" (i.e. DecRef) the old attribute. - attr->DecRef(); - attr = new_attr; - // Take ownership of the new attribute, i.e. no IncRef. - } - } +// scroll line size +const size_t GRID_SCROLL_LINE_X = 15; +const size_t GRID_SCROLL_LINE_Y = GRID_SCROLL_LINE_X; - ~wxGridCellWithAttr() - { - attr->DecRef(); - } +// the size of hash tables used a bit everywhere (the max number of elements +// in these hash tables is the number of rows/columns) +const int GRID_HASH_SIZE = 100; - wxGridCellCoords coords; - wxGridCellAttr *attr; -}; +// the minimal distance in pixels the mouse needs to move to start a drag +// operation +const int DRAG_SENSITIVITY = 3; -WX_DECLARE_OBJARRAY_WITH_DECL(wxGridCellWithAttr, wxGridCellWithAttrArray, - class WXDLLIMPEXP_ADV); +} // anonymous namespace #include "wx/arrimpl.cpp" @@ -148,2742 +129,62 @@ DEFINE_EVENT_TYPE(wxEVT_GRID_COL_SIZE) DEFINE_EVENT_TYPE(wxEVT_GRID_COL_MOVE) DEFINE_EVENT_TYPE(wxEVT_GRID_COL_SORT) DEFINE_EVENT_TYPE(wxEVT_GRID_RANGE_SELECT) -DEFINE_EVENT_TYPE(wxEVT_GRID_CELL_CHANGING) -DEFINE_EVENT_TYPE(wxEVT_GRID_CELL_CHANGED) -DEFINE_EVENT_TYPE(wxEVT_GRID_SELECT_CELL) -DEFINE_EVENT_TYPE(wxEVT_GRID_EDITOR_SHOWN) -DEFINE_EVENT_TYPE(wxEVT_GRID_EDITOR_HIDDEN) -DEFINE_EVENT_TYPE(wxEVT_GRID_EDITOR_CREATED) - -// ---------------------------------------------------------------------------- -// private classes -// ---------------------------------------------------------------------------- - -// header column providing access to the column information stored in wxGrid -// via wxHeaderColumn interface -class wxGridHeaderColumn : public wxHeaderColumn -{ -public: - wxGridHeaderColumn(wxGrid *grid, int col) - : m_grid(grid), - m_col(col) - { - } - - virtual wxString GetTitle() const { return m_grid->GetColLabelValue(m_col); } - virtual wxBitmap GetBitmap() const { return wxNullBitmap; } - virtual int GetWidth() const { return m_grid->GetColSize(m_col); } - virtual int GetMinWidth() const { return 0; } - virtual wxAlignment GetAlignment() const - { - int horz, - vert; - m_grid->GetColLabelAlignment(&horz, &vert); - - return static_cast(horz); - } - - virtual int GetFlags() const - { - // we can't know in advance whether we can sort by this column or not - // with wxGrid API so suppose we can by default - int flags = wxCOL_SORTABLE; - if ( m_grid->CanDragColSize() ) - flags |= wxCOL_RESIZABLE; - if ( m_grid->CanDragColMove() ) - flags |= wxCOL_REORDERABLE; - if ( GetWidth() == 0 ) - flags |= wxCOL_HIDDEN; - - return flags; - } - - virtual bool IsSortKey() const - { - return m_grid->IsSortingBy(m_col); - } - - virtual bool IsSortOrderAscending() const - { - return m_grid->IsSortOrderAscending(); - } - -private: - // these really should be const but are not because the column needs to be - // assignable to be used in a wxVector (in STL build, in non-STL build we - // avoid the need for this) - wxGrid *m_grid; - int m_col; -}; - -// header control retreiving column information from the grid -class wxGridHeaderCtrl : public wxHeaderCtrl -{ -public: - wxGridHeaderCtrl(wxGrid *owner) - : wxHeaderCtrl(owner, - wxID_ANY, - wxDefaultPosition, - wxDefaultSize, - wxHD_ALLOW_HIDE | - (owner->CanDragColMove() ? wxHD_ALLOW_REORDER : 0)) - { - } - -protected: - virtual const wxHeaderColumn& GetColumn(unsigned int idx) const - { - return m_columns[idx]; - } - -private: - wxGrid *GetOwner() const { return static_cast(GetParent()); } - - // override the base class method to update our m_columns array - virtual void OnColumnCountChanging(unsigned int count) - { - const unsigned countOld = m_columns.size(); - if ( count < countOld ) - { - // just discard the columns which don't exist any more (notice that - // we can't use resize() here as it would require the vector - // value_type, i.e. wxGridHeaderColumn to be default constructible, - // which it is not) - m_columns.erase(m_columns.begin() + count, m_columns.end()); - } - else // new columns added - { - // add columns for the new elements - for ( unsigned n = countOld; n < count; n++ ) - m_columns.push_back(wxGridHeaderColumn(GetOwner(), n)); - } - } - - // override to implement column auto sizing - virtual bool UpdateColumnWidthToFit(unsigned int idx, int widthTitle) - { - // TODO: currently grid doesn't support computing the column best width - // from its contents so we just use the best label width as is - GetOwner()->SetColSize(idx, widthTitle); - - return true; - } - - // overridden to react to the actions using the columns popup menu - virtual void UpdateColumnVisibility(unsigned int idx, bool show) - { - GetOwner()->SetColSize(idx, show ? wxGRID_AUTOSIZE : 0); - - // as this is done by the user we should notify the main program about - // it - GetOwner()->SendEvent(wxEVT_GRID_COL_SIZE, -1, idx); - } - - // overridden to react to the columns order changes in the customization - // dialog - virtual void UpdateColumnsOrder(const wxArrayInt& order) - { - GetOwner()->SetColumnsOrder(order); - } - - - // event handlers forwarding wxHeaderCtrl events to wxGrid - void OnClick(wxHeaderCtrlEvent& event) - { - GetOwner()->DoColHeaderClick(event.GetColumn()); - } - - void OnBeginResize(wxHeaderCtrlEvent& event) - { - GetOwner()->DoStartResizeCol(event.GetColumn()); - - event.Skip(); - } - - void OnResizing(wxHeaderCtrlEvent& event) - { - GetOwner()->DoUpdateResizeColWidth(event.GetWidth()); - } - - void OnEndResize(wxHeaderCtrlEvent& event) - { - GetOwner()->DoEndDragResizeCol(); - - event.Skip(); - } - - void OnBeginReorder(wxHeaderCtrlEvent& event) - { - GetOwner()->DoStartMoveCol(event.GetColumn()); - } - - void OnEndReorder(wxHeaderCtrlEvent& event) - { - GetOwner()->DoEndMoveCol(event.GetNewOrder()); - } - - wxVector m_columns; - - DECLARE_EVENT_TABLE() - DECLARE_NO_COPY_CLASS(wxGridHeaderCtrl) -}; - -BEGIN_EVENT_TABLE(wxGridHeaderCtrl, wxHeaderCtrl) - EVT_HEADER_CLICK(wxID_ANY, wxGridHeaderCtrl::OnClick) - - EVT_HEADER_BEGIN_RESIZE(wxID_ANY, wxGridHeaderCtrl::OnBeginResize) - EVT_HEADER_RESIZING(wxID_ANY, wxGridHeaderCtrl::OnResizing) - EVT_HEADER_END_RESIZE(wxID_ANY, wxGridHeaderCtrl::OnEndResize) - - EVT_HEADER_BEGIN_REORDER(wxID_ANY, wxGridHeaderCtrl::OnBeginReorder) - EVT_HEADER_END_REORDER(wxID_ANY, wxGridHeaderCtrl::OnEndReorder) -END_EVENT_TABLE() - -// common base class for various grid subwindows -class WXDLLIMPEXP_ADV wxGridSubwindow : public wxWindow -{ -public: - wxGridSubwindow(wxGrid *owner, - int additionalStyle = 0, - const wxString& name = wxPanelNameStr) - : wxWindow(owner, wxID_ANY, - wxDefaultPosition, wxDefaultSize, - wxBORDER_NONE | additionalStyle, - name) - { - m_owner = owner; - } - - virtual bool AcceptsFocus() const { return false; } - - wxGrid *GetOwner() { return m_owner; } - -protected: - void OnMouseCaptureLost(wxMouseCaptureLostEvent& event); - - wxGrid *m_owner; - - DECLARE_EVENT_TABLE() - DECLARE_NO_COPY_CLASS(wxGridSubwindow) -}; - -class WXDLLIMPEXP_ADV wxGridRowLabelWindow : public wxGridSubwindow -{ -public: - wxGridRowLabelWindow(wxGrid *parent) - : wxGridSubwindow(parent) - { - } - - -private: - void OnPaint( wxPaintEvent& event ); - void OnMouseEvent( wxMouseEvent& event ); - void OnMouseWheel( wxMouseEvent& event ); - - DECLARE_EVENT_TABLE() - DECLARE_NO_COPY_CLASS(wxGridRowLabelWindow) -}; - - -class WXDLLIMPEXP_ADV wxGridColLabelWindow : public wxGridSubwindow -{ -public: - wxGridColLabelWindow(wxGrid *parent) - : wxGridSubwindow(parent) - { - } - - -private: - void OnPaint( wxPaintEvent& event ); - void OnMouseEvent( wxMouseEvent& event ); - void OnMouseWheel( wxMouseEvent& event ); - - DECLARE_EVENT_TABLE() - DECLARE_NO_COPY_CLASS(wxGridColLabelWindow) -}; - - -class WXDLLIMPEXP_ADV wxGridCornerLabelWindow : public wxGridSubwindow -{ -public: - wxGridCornerLabelWindow(wxGrid *parent) - : wxGridSubwindow(parent) - { - } - -private: - void OnMouseEvent( wxMouseEvent& event ); - void OnMouseWheel( wxMouseEvent& event ); - void OnPaint( wxPaintEvent& event ); - - DECLARE_EVENT_TABLE() - DECLARE_NO_COPY_CLASS(wxGridCornerLabelWindow) -}; - -class WXDLLIMPEXP_ADV wxGridWindow : public wxGridSubwindow -{ -public: - wxGridWindow(wxGrid *parent) - : wxGridSubwindow(parent, - wxWANTS_CHARS | wxCLIP_CHILDREN, - "GridWindow") - { - } - - - virtual void ScrollWindow( int dx, int dy, const wxRect *rect ); - - virtual bool AcceptsFocus() const { return true; } - -private: - void OnPaint( wxPaintEvent &event ); - void OnMouseWheel( wxMouseEvent& event ); - void OnMouseEvent( wxMouseEvent& event ); - void OnKeyDown( wxKeyEvent& ); - void OnKeyUp( wxKeyEvent& ); - void OnChar( wxKeyEvent& ); - void OnEraseBackground( wxEraseEvent& ); - void OnFocus( wxFocusEvent& ); - - DECLARE_EVENT_TABLE() - DECLARE_NO_COPY_CLASS(wxGridWindow) -}; - - -class wxGridCellEditorEvtHandler : public wxEvtHandler -{ -public: - wxGridCellEditorEvtHandler(wxGrid* grid, wxGridCellEditor* editor) - : m_grid(grid), - m_editor(editor), - m_inSetFocus(false) - { - } - - void OnKillFocus(wxFocusEvent& event); - void OnKeyDown(wxKeyEvent& event); - void OnChar(wxKeyEvent& event); - - void SetInSetFocus(bool inSetFocus) { m_inSetFocus = inSetFocus; } - -private: - wxGrid *m_grid; - wxGridCellEditor *m_editor; - - // Work around the fact that a focus kill event can be sent to - // a combobox within a set focus event. - bool m_inSetFocus; - - DECLARE_EVENT_TABLE() - DECLARE_DYNAMIC_CLASS(wxGridCellEditorEvtHandler) - DECLARE_NO_COPY_CLASS(wxGridCellEditorEvtHandler) -}; - - -IMPLEMENT_ABSTRACT_CLASS(wxGridCellEditorEvtHandler, wxEvtHandler) - -BEGIN_EVENT_TABLE( wxGridCellEditorEvtHandler, wxEvtHandler ) - EVT_KILL_FOCUS( wxGridCellEditorEvtHandler::OnKillFocus ) - EVT_KEY_DOWN( wxGridCellEditorEvtHandler::OnKeyDown ) - EVT_CHAR( wxGridCellEditorEvtHandler::OnChar ) -END_EVENT_TABLE() - - -// ---------------------------------------------------------------------------- -// the internal data representation used by wxGridCellAttrProvider -// ---------------------------------------------------------------------------- - -// this class stores attributes set for cells -class WXDLLIMPEXP_ADV wxGridCellAttrData -{ -public: - void SetAttr(wxGridCellAttr *attr, int row, int col); - wxGridCellAttr *GetAttr(int row, int col) const; - void UpdateAttrRows( size_t pos, int numRows ); - void UpdateAttrCols( size_t pos, int numCols ); - -private: - // searches for the attr for given cell, returns wxNOT_FOUND if not found - int FindIndex(int row, int col) const; - - wxGridCellWithAttrArray m_attrs; -}; - -// this class stores attributes set for rows or columns -class WXDLLIMPEXP_ADV wxGridRowOrColAttrData -{ -public: - // empty ctor to suppress warnings - wxGridRowOrColAttrData() {} - ~wxGridRowOrColAttrData(); - - void SetAttr(wxGridCellAttr *attr, int rowOrCol); - wxGridCellAttr *GetAttr(int rowOrCol) const; - void UpdateAttrRowsOrCols( size_t pos, int numRowsOrCols ); - -private: - wxArrayInt m_rowsOrCols; - wxArrayAttrs m_attrs; -}; - -// NB: this is just a wrapper around 3 objects: one which stores cell -// attributes, and 2 others for row/col ones -class WXDLLIMPEXP_ADV wxGridCellAttrProviderData -{ -public: - wxGridCellAttrData m_cellAttrs; - wxGridRowOrColAttrData m_rowAttrs, - m_colAttrs; -}; - - -// ---------------------------------------------------------------------------- -// data structures used for the data type registry -// ---------------------------------------------------------------------------- - -struct wxGridDataTypeInfo -{ - wxGridDataTypeInfo(const wxString& typeName, - wxGridCellRenderer* renderer, - wxGridCellEditor* editor) - : m_typeName(typeName), m_renderer(renderer), m_editor(editor) - {} - - ~wxGridDataTypeInfo() - { - wxSafeDecRef(m_renderer); - wxSafeDecRef(m_editor); - } - - wxString m_typeName; - wxGridCellRenderer* m_renderer; - wxGridCellEditor* m_editor; - - DECLARE_NO_COPY_CLASS(wxGridDataTypeInfo) -}; - - -WX_DEFINE_ARRAY_WITH_DECL_PTR(wxGridDataTypeInfo*, wxGridDataTypeInfoArray, - class WXDLLIMPEXP_ADV); - - -class WXDLLIMPEXP_ADV wxGridTypeRegistry -{ -public: - wxGridTypeRegistry() {} - ~wxGridTypeRegistry(); - - void RegisterDataType(const wxString& typeName, - wxGridCellRenderer* renderer, - wxGridCellEditor* editor); - - // find one of already registered data types - int FindRegisteredDataType(const wxString& typeName); - - // try to FindRegisteredDataType(), if this fails and typeName is one of - // standard typenames, register it and return its index - int FindDataType(const wxString& typeName); - - // try to FindDataType(), if it fails see if it is not one of already - // registered data types with some params in which case clone the - // registered data type and set params for it - int FindOrCloneDataType(const wxString& typeName); - - wxGridCellRenderer* GetRenderer(int index); - wxGridCellEditor* GetEditor(int index); - -private: - wxGridDataTypeInfoArray m_typeinfo; -}; - -// ---------------------------------------------------------------------------- -// operations classes abstracting the difference between operating on rows and -// columns -// ---------------------------------------------------------------------------- - -// This class allows to write a function only once because by using its methods -// it will apply to both columns and rows. -// -// This is an abstract interface definition, the two concrete implementations -// below should be used when working with rows and columns respectively. -class wxGridOperations -{ -public: - // Returns the operations in the other direction, i.e. wxGridRowOperations - // if this object is a wxGridColumnOperations and vice versa. - virtual wxGridOperations& Dual() const = 0; - - // Return the number of rows or columns. - virtual int GetNumberOfLines(const wxGrid *grid) const = 0; - - // Return the selection mode which allows selecting rows or columns. - virtual wxGrid::wxGridSelectionModes GetSelectionMode() const = 0; - - // Make a wxGridCellCoords from the given components: thisDir is row or - // column and otherDir is column or row - virtual wxGridCellCoords MakeCoords(int thisDir, int otherDir) const = 0; - - // Calculate the scrolled position of the given abscissa or ordinate. - virtual int CalcScrolledPosition(wxGrid *grid, int pos) const = 0; - - // Selects the horizontal or vertical component from the given object. - virtual int Select(const wxGridCellCoords& coords) const = 0; - virtual int Select(const wxPoint& pt) const = 0; - virtual int Select(const wxSize& sz) const = 0; - virtual int Select(const wxRect& r) const = 0; - virtual int& Select(wxRect& r) const = 0; - - // Returns width or height of the rectangle - virtual int& SelectSize(wxRect& r) const = 0; - - // Make a wxSize such that Select() applied to it returns first component - virtual wxSize MakeSize(int first, int second) const = 0; - - // Sets the row or column component of the given cell coordinates - virtual void Set(wxGridCellCoords& coords, int line) const = 0; - - - // Draws a line parallel to the row or column, i.e. horizontal or vertical: - // pos is the horizontal or vertical position of the line and start and end - // are the coordinates of the line extremities in the other direction - virtual void - DrawParallelLine(wxDC& dc, int start, int end, int pos) const = 0; - - // Draw a horizontal or vertical line across the given rectangle - // (this is implemented in terms of above and uses Select() to extract - // start and end from the given rectangle) - void DrawParallelLineInRect(wxDC& dc, const wxRect& rect, int pos) const - { - const int posStart = Select(rect.GetPosition()); - DrawParallelLine(dc, posStart, posStart + Select(rect.GetSize()), pos); - } - - - // Return the index of the row or column at the given pixel coordinate. - virtual int - PosToLine(const wxGrid *grid, int pos, bool clip = false) const = 0; - - // Get the top/left position, in pixels, of the given row or column - virtual int GetLineStartPos(const wxGrid *grid, int line) const = 0; - - // Get the bottom/right position, in pixels, of the given row or column - virtual int GetLineEndPos(const wxGrid *grid, int line) const = 0; - - // Get the height/width of the given row/column - virtual int GetLineSize(const wxGrid *grid, int line) const = 0; - - // Get wxGrid::m_rowBottoms/m_colRights array - virtual const wxArrayInt& GetLineEnds(const wxGrid *grid) const = 0; - - // Get default height row height or column width - virtual int GetDefaultLineSize(const wxGrid *grid) const = 0; - - // Return the minimal acceptable row height or column width - virtual int GetMinimalAcceptableLineSize(const wxGrid *grid) const = 0; - - // Return the minimal row height or column width - virtual int GetMinimalLineSize(const wxGrid *grid, int line) const = 0; - - // Set the row height or column width - virtual void SetLineSize(wxGrid *grid, int line, int size) const = 0; - - // True if rows/columns can be resized by user - virtual bool CanResizeLines(const wxGrid *grid) const = 0; - - - // Return the index of the line at the given position - // - // NB: currently this is always identity for the rows as reordering is only - // implemented for the lines - virtual int GetLineAt(const wxGrid *grid, int line) const = 0; - - - // Get the row or column label window - virtual wxWindow *GetHeaderWindow(wxGrid *grid) const = 0; - - // Get the width or height of the row or column label window - virtual int GetHeaderWindowSize(wxGrid *grid) const = 0; - - - // This class is never used polymorphically but give it a virtual dtor - // anyhow to suppress g++ complaints about it - virtual ~wxGridOperations() { } -}; - -class wxGridRowOperations : public wxGridOperations -{ -public: - virtual wxGridOperations& Dual() const; - - virtual int GetNumberOfLines(const wxGrid *grid) const - { return grid->GetNumberRows(); } - - virtual wxGrid::wxGridSelectionModes GetSelectionMode() const - { return wxGrid::wxGridSelectRows; } - - virtual wxGridCellCoords MakeCoords(int thisDir, int otherDir) const - { return wxGridCellCoords(thisDir, otherDir); } - - virtual int CalcScrolledPosition(wxGrid *grid, int pos) const - { return grid->CalcScrolledPosition(wxPoint(pos, 0)).x; } - - virtual int Select(const wxGridCellCoords& c) const { return c.GetRow(); } - virtual int Select(const wxPoint& pt) const { return pt.x; } - virtual int Select(const wxSize& sz) const { return sz.x; } - virtual int Select(const wxRect& r) const { return r.x; } - virtual int& Select(wxRect& r) const { return r.x; } - virtual int& SelectSize(wxRect& r) const { return r.width; } - virtual wxSize MakeSize(int first, int second) const - { return wxSize(first, second); } - virtual void Set(wxGridCellCoords& coords, int line) const - { coords.SetRow(line); } - - virtual void DrawParallelLine(wxDC& dc, int start, int end, int pos) const - { dc.DrawLine(start, pos, end, pos); } - - virtual int PosToLine(const wxGrid *grid, int pos, bool clip = false) const - { return grid->YToRow(pos, clip); } - virtual int GetLineStartPos(const wxGrid *grid, int line) const - { return grid->GetRowTop(line); } - virtual int GetLineEndPos(const wxGrid *grid, int line) const - { return grid->GetRowBottom(line); } - virtual int GetLineSize(const wxGrid *grid, int line) const - { return grid->GetRowHeight(line); } - virtual const wxArrayInt& GetLineEnds(const wxGrid *grid) const - { return grid->m_rowBottoms; } - virtual int GetDefaultLineSize(const wxGrid *grid) const - { return grid->GetDefaultRowSize(); } - virtual int GetMinimalAcceptableLineSize(const wxGrid *grid) const - { return grid->GetRowMinimalAcceptableHeight(); } - virtual int GetMinimalLineSize(const wxGrid *grid, int line) const - { return grid->GetRowMinimalHeight(line); } - virtual void SetLineSize(wxGrid *grid, int line, int size) const - { grid->SetRowSize(line, size); } - virtual bool CanResizeLines(const wxGrid *grid) const - { return grid->CanDragRowSize(); } - - virtual int GetLineAt(const wxGrid * WXUNUSED(grid), int line) const - { return line; } // TODO: implement row reordering - - virtual wxWindow *GetHeaderWindow(wxGrid *grid) const - { return grid->GetGridRowLabelWindow(); } - virtual int GetHeaderWindowSize(wxGrid *grid) const - { return grid->GetRowLabelSize(); } -}; - -class wxGridColumnOperations : public wxGridOperations -{ -public: - virtual wxGridOperations& Dual() const; - - virtual int GetNumberOfLines(const wxGrid *grid) const - { return grid->GetNumberCols(); } - - virtual wxGrid::wxGridSelectionModes GetSelectionMode() const - { return wxGrid::wxGridSelectColumns; } - - virtual wxGridCellCoords MakeCoords(int thisDir, int otherDir) const - { return wxGridCellCoords(otherDir, thisDir); } - - virtual int CalcScrolledPosition(wxGrid *grid, int pos) const - { return grid->CalcScrolledPosition(wxPoint(0, pos)).y; } - - virtual int Select(const wxGridCellCoords& c) const { return c.GetCol(); } - virtual int Select(const wxPoint& pt) const { return pt.y; } - virtual int Select(const wxSize& sz) const { return sz.y; } - virtual int Select(const wxRect& r) const { return r.y; } - virtual int& Select(wxRect& r) const { return r.y; } - virtual int& SelectSize(wxRect& r) const { return r.height; } - virtual wxSize MakeSize(int first, int second) const - { return wxSize(second, first); } - virtual void Set(wxGridCellCoords& coords, int line) const - { coords.SetCol(line); } - - virtual void DrawParallelLine(wxDC& dc, int start, int end, int pos) const - { dc.DrawLine(pos, start, pos, end); } - - virtual int PosToLine(const wxGrid *grid, int pos, bool clip = false) const - { return grid->XToCol(pos, clip); } - virtual int GetLineStartPos(const wxGrid *grid, int line) const - { return grid->GetColLeft(line); } - virtual int GetLineEndPos(const wxGrid *grid, int line) const - { return grid->GetColRight(line); } - virtual int GetLineSize(const wxGrid *grid, int line) const - { return grid->GetColWidth(line); } - virtual const wxArrayInt& GetLineEnds(const wxGrid *grid) const - { return grid->m_colRights; } - virtual int GetDefaultLineSize(const wxGrid *grid) const - { return grid->GetDefaultColSize(); } - virtual int GetMinimalAcceptableLineSize(const wxGrid *grid) const - { return grid->GetColMinimalAcceptableWidth(); } - virtual int GetMinimalLineSize(const wxGrid *grid, int line) const - { return grid->GetColMinimalWidth(line); } - virtual void SetLineSize(wxGrid *grid, int line, int size) const - { grid->SetColSize(line, size); } - virtual bool CanResizeLines(const wxGrid *grid) const - { return grid->CanDragColSize(); } - - virtual int GetLineAt(const wxGrid *grid, int line) const - { return grid->GetColAt(line); } - - virtual wxWindow *GetHeaderWindow(wxGrid *grid) const - { return grid->GetGridColLabelWindow(); } - virtual int GetHeaderWindowSize(wxGrid *grid) const - { return grid->GetColLabelSize(); } -}; - -wxGridOperations& wxGridRowOperations::Dual() const -{ - static wxGridColumnOperations s_colOper; - - return s_colOper; -} - -wxGridOperations& wxGridColumnOperations::Dual() const -{ - static wxGridRowOperations s_rowOper; - - return s_rowOper; -} - -// This class abstracts the difference between operations going forward -// (down/right) and backward (up/left) and allows to use the same code for -// functions which differ only in the direction of grid traversal -// -// Like wxGridOperations it's an ABC with two concrete subclasses below. Unlike -// it, this is a normal object and not just a function dispatch table and has a -// non-default ctor. -// -// Note: the explanation of this discrepancy is the existence of (very useful) -// Dual() method in wxGridOperations which forces us to make wxGridOperations a -// function dispatcher only. -class wxGridDirectionOperations -{ -public: - // The oper parameter to ctor selects whether we work with rows or columns - wxGridDirectionOperations(wxGrid *grid, const wxGridOperations& oper) - : m_grid(grid), - m_oper(oper) - { - } - - // Check if the component of this point in our direction is at the - // boundary, i.e. is the first/last row/column - virtual bool IsAtBoundary(const wxGridCellCoords& coords) const = 0; - - // Increment the component of this point in our direction - virtual void Advance(wxGridCellCoords& coords) const = 0; - - // Find the line at the given distance, in pixels, away from this one - // (this uses clipping, i.e. anything after the last line is counted as the - // last one and anything before the first one as 0) - virtual int MoveByPixelDistance(int line, int distance) const = 0; - - // This class is never used polymorphically but give it a virtual dtor - // anyhow to suppress g++ complaints about it - virtual ~wxGridDirectionOperations() { } - -protected: - wxGrid * const m_grid; - const wxGridOperations& m_oper; -}; - -class wxGridBackwardOperations : public wxGridDirectionOperations -{ -public: - wxGridBackwardOperations(wxGrid *grid, const wxGridOperations& oper) - : wxGridDirectionOperations(grid, oper) - { - } - - virtual bool IsAtBoundary(const wxGridCellCoords& coords) const - { - wxASSERT_MSG( m_oper.Select(coords) >= 0, "invalid row/column" ); - - return m_oper.Select(coords) == 0; - } - - virtual void Advance(wxGridCellCoords& coords) const - { - wxASSERT( !IsAtBoundary(coords) ); - - m_oper.Set(coords, m_oper.Select(coords) - 1); - } - - virtual int MoveByPixelDistance(int line, int distance) const - { - int pos = m_oper.GetLineStartPos(m_grid, line); - return m_oper.PosToLine(m_grid, pos - distance + 1, true); - } -}; - -class wxGridForwardOperations : public wxGridDirectionOperations -{ -public: - wxGridForwardOperations(wxGrid *grid, const wxGridOperations& oper) - : wxGridDirectionOperations(grid, oper), - m_numLines(oper.GetNumberOfLines(grid)) - { - } - - virtual bool IsAtBoundary(const wxGridCellCoords& coords) const - { - wxASSERT_MSG( m_oper.Select(coords) < m_numLines, "invalid row/column" ); - - return m_oper.Select(coords) == m_numLines - 1; - } - - virtual void Advance(wxGridCellCoords& coords) const - { - wxASSERT( !IsAtBoundary(coords) ); - - m_oper.Set(coords, m_oper.Select(coords) + 1); - } - - virtual int MoveByPixelDistance(int line, int distance) const - { - int pos = m_oper.GetLineStartPos(m_grid, line); - return m_oper.PosToLine(m_grid, pos + distance, true); - } - -private: - const int m_numLines; -}; - -// ---------------------------------------------------------------------------- -// globals -// ---------------------------------------------------------------------------- - -//#define DEBUG_ATTR_CACHE -#ifdef DEBUG_ATTR_CACHE - static size_t gs_nAttrCacheHits = 0; - static size_t gs_nAttrCacheMisses = 0; -#endif - -// ---------------------------------------------------------------------------- -// constants -// ---------------------------------------------------------------------------- - -wxGridCellCoords wxGridNoCellCoords( -1, -1 ); -wxRect wxGridNoCellRect( -1, -1, -1, -1 ); - -namespace -{ - -// scroll line size -const size_t GRID_SCROLL_LINE_X = 15; -const size_t GRID_SCROLL_LINE_Y = GRID_SCROLL_LINE_X; - -// the size of hash tables used a bit everywhere (the max number of elements -// in these hash tables is the number of rows/columns) -const int GRID_HASH_SIZE = 100; - -// the minimal distance in pixels the mouse needs to move to start a drag -// operation -const int DRAG_SENSITIVITY = 3; - -} // anonymous namespace - -// ---------------------------------------------------------------------------- -// private helpers -// ---------------------------------------------------------------------------- - -namespace -{ - -// ensure that first is less or equal to second, swapping the values if -// necessary -void EnsureFirstLessThanSecond(int& first, int& second) -{ - if ( first > second ) - wxSwap(first, second); -} - -} // anonymous namespace - -// ============================================================================ -// implementation -// ============================================================================ - -// ---------------------------------------------------------------------------- -// wxGridCellEditor -// ---------------------------------------------------------------------------- - -wxGridCellEditor::wxGridCellEditor() -{ - m_control = NULL; - m_attr = NULL; -} - -wxGridCellEditor::~wxGridCellEditor() -{ - Destroy(); -} - -void wxGridCellEditor::Create(wxWindow* WXUNUSED(parent), - wxWindowID WXUNUSED(id), - wxEvtHandler* evtHandler) -{ - if ( evtHandler ) - m_control->PushEventHandler(evtHandler); -} - -void wxGridCellEditor::PaintBackground(const wxRect& rectCell, - wxGridCellAttr *attr) -{ - // erase the background because we might not fill the cell - wxClientDC dc(m_control->GetParent()); - wxGridWindow* gridWindow = wxDynamicCast(m_control->GetParent(), wxGridWindow); - if (gridWindow) - gridWindow->GetOwner()->PrepareDC(dc); - - dc.SetPen(*wxTRANSPARENT_PEN); - dc.SetBrush(wxBrush(attr->GetBackgroundColour())); - dc.DrawRectangle(rectCell); - - // redraw the control we just painted over - m_control->Refresh(); -} - -void wxGridCellEditor::Destroy() -{ - if (m_control) - { - m_control->PopEventHandler( true /* delete it*/ ); - - m_control->Destroy(); - m_control = NULL; - } -} - -void wxGridCellEditor::Show(bool show, wxGridCellAttr *attr) -{ - wxASSERT_MSG(m_control, wxT("The wxGridCellEditor must be created first!")); - - m_control->Show(show); - - if ( show ) - { - // set the colours/fonts if we have any - if ( attr ) - { - m_colFgOld = m_control->GetForegroundColour(); - m_control->SetForegroundColour(attr->GetTextColour()); - - m_colBgOld = m_control->GetBackgroundColour(); - m_control->SetBackgroundColour(attr->GetBackgroundColour()); - -// Workaround for GTK+1 font setting problem on some platforms -#if !defined(__WXGTK__) || defined(__WXGTK20__) - m_fontOld = m_control->GetFont(); - m_control->SetFont(attr->GetFont()); -#endif - - // can't do anything more in the base class version, the other - // attributes may only be used by the derived classes - } - } - else - { - // restore the standard colours fonts - if ( m_colFgOld.Ok() ) - { - m_control->SetForegroundColour(m_colFgOld); - m_colFgOld = wxNullColour; - } - - if ( m_colBgOld.Ok() ) - { - m_control->SetBackgroundColour(m_colBgOld); - m_colBgOld = wxNullColour; - } - -// Workaround for GTK+1 font setting problem on some platforms -#if !defined(__WXGTK__) || defined(__WXGTK20__) - if ( m_fontOld.Ok() ) - { - m_control->SetFont(m_fontOld); - m_fontOld = wxNullFont; - } -#endif - } -} - -void wxGridCellEditor::SetSize(const wxRect& rect) -{ - wxASSERT_MSG(m_control, wxT("The wxGridCellEditor must be created first!")); - - m_control->SetSize(rect, wxSIZE_ALLOW_MINUS_ONE); -} - -void wxGridCellEditor::HandleReturn(wxKeyEvent& event) -{ - event.Skip(); -} - -bool wxGridCellEditor::IsAcceptedKey(wxKeyEvent& event) -{ - bool ctrl = event.ControlDown(); - bool alt = event.AltDown(); - -#ifdef __WXMAC__ - // On the Mac the Alt key is more like shift and is used for entry of - // valid characters, so check for Ctrl and Meta instead. - alt = event.MetaDown(); -#endif - - // Assume it's not a valid char if ctrl or alt is down, but if both are - // down then it may be because of an AltGr key combination, so let them - // through in that case. - if ((ctrl || alt) && !(ctrl && alt)) - return false; - -#if wxUSE_UNICODE - // if the unicode key code is not really a unicode character (it may - // be a function key or etc., the platforms appear to always give us a - // small value in this case) then fallback to the ASCII key code but - // don't do anything for function keys or etc. - if ( event.GetUnicodeKey() > 127 && event.GetKeyCode() > 127 ) - return false; -#else - if ( event.GetKeyCode() > 255 ) - return false; -#endif - - return true; -} - -void wxGridCellEditor::StartingKey(wxKeyEvent& event) -{ - event.Skip(); -} - -void wxGridCellEditor::StartingClick() -{ -} - -#if wxUSE_TEXTCTRL - -// ---------------------------------------------------------------------------- -// wxGridCellTextEditor -// ---------------------------------------------------------------------------- - -wxGridCellTextEditor::wxGridCellTextEditor() -{ - m_maxChars = 0; -} - -void wxGridCellTextEditor::Create(wxWindow* parent, - wxWindowID id, - wxEvtHandler* evtHandler) -{ - DoCreate(parent, id, evtHandler); -} - -void wxGridCellTextEditor::DoCreate(wxWindow* parent, - wxWindowID id, - wxEvtHandler* evtHandler, - long style) -{ - style |= wxTE_PROCESS_ENTER | wxTE_PROCESS_TAB | wxNO_BORDER; - - m_control = new wxTextCtrl(parent, id, wxEmptyString, - wxDefaultPosition, wxDefaultSize, - style); - - // set max length allowed in the textctrl, if the parameter was set - if ( m_maxChars != 0 ) - { - Text()->SetMaxLength(m_maxChars); - } - - wxGridCellEditor::Create(parent, id, evtHandler); -} - -void wxGridCellTextEditor::PaintBackground(const wxRect& WXUNUSED(rectCell), - wxGridCellAttr * WXUNUSED(attr)) -{ - // as we fill the entire client area, - // don't do anything here to minimize flicker -} - -void wxGridCellTextEditor::SetSize(const wxRect& rectOrig) -{ - wxRect rect(rectOrig); - - // Make the edit control large enough to allow for internal margins - // - // TODO: remove this if the text ctrl sizing is improved esp. for unix - // -#if defined(__WXGTK__) - if (rect.x != 0) - { - rect.x += 1; - rect.y += 1; - rect.width -= 1; - rect.height -= 1; - } -#elif defined(__WXMSW__) - if ( rect.x == 0 ) - rect.x += 2; - else - rect.x += 3; - - if ( rect.y == 0 ) - rect.y += 2; - else - rect.y += 3; - - rect.width -= 2; - rect.height -= 2; -#else - int extra_x = ( rect.x > 2 ) ? 2 : 1; - int extra_y = ( rect.y > 2 ) ? 2 : 1; - - #if defined(__WXMOTIF__) - extra_x *= 2; - extra_y *= 2; - #endif - - rect.SetLeft( wxMax(0, rect.x - extra_x) ); - rect.SetTop( wxMax(0, rect.y - extra_y) ); - rect.SetRight( rect.GetRight() + 2 * extra_x ); - rect.SetBottom( rect.GetBottom() + 2 * extra_y ); -#endif - - wxGridCellEditor::SetSize(rect); -} - -void wxGridCellTextEditor::BeginEdit(int row, int col, wxGrid* grid) -{ - wxASSERT_MSG(m_control, wxT("The wxGridCellEditor must be created first!")); - - m_value = grid->GetTable()->GetValue(row, col); - - DoBeginEdit(m_value); -} - -void wxGridCellTextEditor::DoBeginEdit(const wxString& startValue) -{ - Text()->SetValue(startValue); - Text()->SetInsertionPointEnd(); - Text()->SetSelection(-1, -1); - Text()->SetFocus(); -} - -bool wxGridCellTextEditor::EndEdit(const wxString& WXUNUSED(oldval), - wxString *newval) -{ - wxCHECK_MSG( m_control, false, - "wxGridCellTextEditor must be created first!" ); - - const wxString value = Text()->GetValue(); - if ( value == m_value ) - return false; - - m_value = value; - - if ( newval ) - *newval = m_value; - - return true; -} - -void wxGridCellTextEditor::ApplyEdit(int row, int col, wxGrid* grid) -{ - grid->GetTable()->SetValue(row, col, m_value); - m_value.clear(); -} - -void wxGridCellTextEditor::Reset() -{ - wxASSERT_MSG( m_control, "wxGridCellTextEditor must be created first!" ); - - DoReset(m_value); -} - -void wxGridCellTextEditor::DoReset(const wxString& startValue) -{ - Text()->SetValue(startValue); - Text()->SetInsertionPointEnd(); -} - -bool wxGridCellTextEditor::IsAcceptedKey(wxKeyEvent& event) -{ - return wxGridCellEditor::IsAcceptedKey(event); -} - -void wxGridCellTextEditor::StartingKey(wxKeyEvent& event) -{ - // Since this is now happening in the EVT_CHAR event EmulateKeyPress is no - // longer an appropriate way to get the character into the text control. - // Do it ourselves instead. We know that if we get this far that we have - // a valid character, so not a whole lot of testing needs to be done. - - wxTextCtrl* tc = Text(); - wxChar ch; - long pos; - -#if wxUSE_UNICODE - ch = event.GetUnicodeKey(); - if (ch <= 127) - ch = (wxChar)event.GetKeyCode(); -#else - ch = (wxChar)event.GetKeyCode(); -#endif - - switch (ch) - { - case WXK_DELETE: - // delete the character at the cursor - pos = tc->GetInsertionPoint(); - if (pos < tc->GetLastPosition()) - tc->Remove(pos, pos + 1); - break; - - case WXK_BACK: - // delete the character before the cursor - pos = tc->GetInsertionPoint(); - if (pos > 0) - tc->Remove(pos - 1, pos); - break; - - default: - tc->WriteText(ch); - break; - } -} - -void wxGridCellTextEditor::HandleReturn( wxKeyEvent& - WXUNUSED_GTK(WXUNUSED_MOTIF(event)) ) -{ -#if defined(__WXMOTIF__) || defined(__WXGTK__) - // wxMotif needs a little extra help... - size_t pos = (size_t)( Text()->GetInsertionPoint() ); - wxString s( Text()->GetValue() ); - s = s.Left(pos) + wxT("\n") + s.Mid(pos); - Text()->SetValue(s); - Text()->SetInsertionPoint( pos ); -#else - // the other ports can handle a Return key press - // - event.Skip(); -#endif -} - -void wxGridCellTextEditor::SetParameters(const wxString& params) -{ - if ( !params ) - { - // reset to default - m_maxChars = 0; - } - else - { - long tmp; - if ( params.ToLong(&tmp) ) - { - m_maxChars = (size_t)tmp; - } - else - { - wxLogDebug( _T("Invalid wxGridCellTextEditor parameter string '%s' ignored"), params.c_str() ); - } - } -} - -// return the value in the text control -wxString wxGridCellTextEditor::GetValue() const -{ - return Text()->GetValue(); -} - -// ---------------------------------------------------------------------------- -// wxGridCellNumberEditor -// ---------------------------------------------------------------------------- - -wxGridCellNumberEditor::wxGridCellNumberEditor(int min, int max) -{ - m_min = min; - m_max = max; -} - -void wxGridCellNumberEditor::Create(wxWindow* parent, - wxWindowID id, - wxEvtHandler* evtHandler) -{ -#if wxUSE_SPINCTRL - if ( HasRange() ) - { - // create a spin ctrl - m_control = new wxSpinCtrl(parent, wxID_ANY, wxEmptyString, - wxDefaultPosition, wxDefaultSize, - wxSP_ARROW_KEYS, - m_min, m_max); - - wxGridCellEditor::Create(parent, id, evtHandler); - } - else -#endif - { - // just a text control - wxGridCellTextEditor::Create(parent, id, evtHandler); - -#if wxUSE_VALIDATORS - Text()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); -#endif - } -} - -void wxGridCellNumberEditor::BeginEdit(int row, int col, wxGrid* grid) -{ - // first get the value - wxGridTableBase *table = grid->GetTable(); - if ( table->CanGetValueAs(row, col, wxGRID_VALUE_NUMBER) ) - { - m_value = table->GetValueAsLong(row, col); - } - else - { - m_value = 0; - wxString sValue = table->GetValue(row, col); - if (! sValue.ToLong(&m_value) && ! sValue.empty()) - { - wxFAIL_MSG( _T("this cell doesn't have numeric value") ); - return; - } - } - -#if wxUSE_SPINCTRL - if ( HasRange() ) - { - Spin()->SetValue((int)m_value); - Spin()->SetFocus(); - } - else -#endif - { - DoBeginEdit(GetString()); - } -} - -bool wxGridCellNumberEditor::EndEdit(const wxString& oldval, wxString *newval) -{ - long value = 0; - wxString text; - -#if wxUSE_SPINCTRL - if ( HasRange() ) - { - value = Spin()->GetValue(); - if ( value == m_value ) - return false; - - text.Printf(wxT("%ld"), value); - } - else // using unconstrained input -#endif // wxUSE_SPINCTRL - { - text = Text()->GetValue(); - if ( text.empty() ) - { - if ( oldval.empty() ) - return false; - } - else // non-empty text now (maybe 0) - { - if ( !text.ToLong(&value) ) - return false; - - // if value == m_value == 0 but old text was "" and new one is - // "0" something still did change - if ( value == m_value && (value || !oldval.empty()) ) - return false; - } - } - - m_value = value; - - if ( newval ) - *newval = text; - - return true; -} - -void wxGridCellNumberEditor::ApplyEdit(int row, int col, wxGrid* grid) -{ - wxGridTableBase * const table = grid->GetTable(); - if ( table->CanSetValueAs(row, col, wxGRID_VALUE_NUMBER) ) - table->SetValueAsLong(row, col, m_value); - else - table->SetValue(row, col, wxString::Format("%ld", m_value)); -} - -void wxGridCellNumberEditor::Reset() -{ -#if wxUSE_SPINCTRL - if ( HasRange() ) - { - Spin()->SetValue((int)m_value); - } - else -#endif - { - DoReset(GetString()); - } -} - -bool wxGridCellNumberEditor::IsAcceptedKey(wxKeyEvent& event) -{ - if ( wxGridCellEditor::IsAcceptedKey(event) ) - { - int keycode = event.GetKeyCode(); - if ( (keycode < 128) && - (wxIsdigit(keycode) || keycode == '+' || keycode == '-')) - { - return true; - } - } - - return false; -} - -void wxGridCellNumberEditor::StartingKey(wxKeyEvent& event) -{ - int keycode = event.GetKeyCode(); - if ( !HasRange() ) - { - if ( wxIsdigit(keycode) || keycode == '+' || keycode == '-') - { - wxGridCellTextEditor::StartingKey(event); - - // skip Skip() below - return; - } - } -#if wxUSE_SPINCTRL - else - { - if ( wxIsdigit(keycode) ) - { - wxSpinCtrl* spin = (wxSpinCtrl*)m_control; - spin->SetValue(keycode - '0'); - spin->SetSelection(1,1); - return; - } - } -#endif - - event.Skip(); -} - -void wxGridCellNumberEditor::SetParameters(const wxString& params) -{ - if ( !params ) - { - // reset to default - m_min = - m_max = -1; - } - else - { - long tmp; - if ( params.BeforeFirst(_T(',')).ToLong(&tmp) ) - { - m_min = (int)tmp; - - if ( params.AfterFirst(_T(',')).ToLong(&tmp) ) - { - m_max = (int)tmp; - - // skip the error message below - return; - } - } - - wxLogDebug(_T("Invalid wxGridCellNumberEditor parameter string '%s' ignored"), params.c_str()); - } -} - -// return the value in the spin control if it is there (the text control otherwise) -wxString wxGridCellNumberEditor::GetValue() const -{ - wxString s; - -#if wxUSE_SPINCTRL - if ( HasRange() ) - { - long value = Spin()->GetValue(); - s.Printf(wxT("%ld"), value); - } - else -#endif - { - s = Text()->GetValue(); - } - - return s; -} - -// ---------------------------------------------------------------------------- -// wxGridCellFloatEditor -// ---------------------------------------------------------------------------- - -wxGridCellFloatEditor::wxGridCellFloatEditor(int width, int precision) -{ - m_width = width; - m_precision = precision; -} - -void wxGridCellFloatEditor::Create(wxWindow* parent, - wxWindowID id, - wxEvtHandler* evtHandler) -{ - wxGridCellTextEditor::Create(parent, id, evtHandler); - -#if wxUSE_VALIDATORS - Text()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); -#endif -} - -void wxGridCellFloatEditor::BeginEdit(int row, int col, wxGrid* grid) -{ - // first get the value - wxGridTableBase * const table = grid->GetTable(); - if ( table->CanGetValueAs(row, col, wxGRID_VALUE_FLOAT) ) - { - m_value = table->GetValueAsDouble(row, col); - } - else - { - m_value = 0.0; - - const wxString value = table->GetValue(row, col); - if ( !value.empty() ) - { - if ( !value.ToDouble(&m_value) ) - { - wxFAIL_MSG( _T("this cell doesn't have float value") ); - return; - } - } - } - - DoBeginEdit(GetString()); -} - -bool wxGridCellFloatEditor::EndEdit(const wxString& oldval, wxString *newval) -{ - const wxString text(Text()->GetValue()); - - double value; - if ( !text.empty() ) - { - if ( !text.ToDouble(&value) ) - return false; - } - else // new value is empty string - { - if ( oldval.empty() ) - return false; // nothing changed - - value = 0.; - } - - // the test for empty strings ensures that we don't skip the value setting - // when "" is replaced by "0" or vice versa as "" numeric value is also 0. - if ( wxIsSameDouble(value, m_value) && !text.empty() && !oldval.empty() ) - return false; // nothing changed - - m_value = value; - - if ( newval ) - *newval = text; - - return true; -} - -void wxGridCellFloatEditor::ApplyEdit(int row, int col, wxGrid* grid) -{ - wxGridTableBase * const table = grid->GetTable(); - - if ( table->CanSetValueAs(row, col, wxGRID_VALUE_FLOAT) ) - table->SetValueAsDouble(row, col, m_value); - else - table->SetValue(row, col, Text()->GetValue()); -} - -void wxGridCellFloatEditor::Reset() -{ - DoReset(GetString()); -} - -void wxGridCellFloatEditor::StartingKey(wxKeyEvent& event) -{ - int keycode = event.GetKeyCode(); - char tmpbuf[2]; - tmpbuf[0] = (char) keycode; - tmpbuf[1] = '\0'; - wxString strbuf(tmpbuf, *wxConvCurrent); - -#if wxUSE_INTL - bool is_decimal_point = ( strbuf == - wxLocale::GetInfo(wxLOCALE_DECIMAL_POINT, wxLOCALE_CAT_NUMBER) ); -#else - bool is_decimal_point = ( strbuf == _T(".") ); -#endif - - if ( wxIsdigit(keycode) || keycode == '+' || keycode == '-' - || is_decimal_point ) - { - wxGridCellTextEditor::StartingKey(event); - - // skip Skip() below - return; - } - - event.Skip(); -} - -void wxGridCellFloatEditor::SetParameters(const wxString& params) -{ - if ( !params ) - { - // reset to default - m_width = - m_precision = -1; - } - else - { - long tmp; - if ( params.BeforeFirst(_T(',')).ToLong(&tmp) ) - { - m_width = (int)tmp; - - if ( params.AfterFirst(_T(',')).ToLong(&tmp) ) - { - m_precision = (int)tmp; - - // skip the error message below - return; - } - } - - wxLogDebug(_T("Invalid wxGridCellFloatEditor parameter string '%s' ignored"), params.c_str()); - } -} - -wxString wxGridCellFloatEditor::GetString() const -{ - wxString fmt; - if ( m_precision == -1 && m_width != -1) - { - // default precision - fmt.Printf(_T("%%%d.f"), m_width); - } - else if ( m_precision != -1 && m_width == -1) - { - // default width - fmt.Printf(_T("%%.%df"), m_precision); - } - else if ( m_precision != -1 && m_width != -1 ) - { - fmt.Printf(_T("%%%d.%df"), m_width, m_precision); - } - else - { - // default width/precision - fmt = _T("%f"); - } - - return wxString::Format(fmt, m_value); -} - -bool wxGridCellFloatEditor::IsAcceptedKey(wxKeyEvent& event) -{ - if ( wxGridCellEditor::IsAcceptedKey(event) ) - { - const int keycode = event.GetKeyCode(); - if ( isascii(keycode) ) - { - char tmpbuf[2]; - tmpbuf[0] = (char) keycode; - tmpbuf[1] = '\0'; - wxString strbuf(tmpbuf, *wxConvCurrent); - -#if wxUSE_INTL - const wxString decimalPoint = - wxLocale::GetInfo(wxLOCALE_DECIMAL_POINT, wxLOCALE_CAT_NUMBER); -#else - const wxString decimalPoint(_T('.')); -#endif - - // accept digits, 'e' as in '1e+6', also '-', '+', and '.' - if ( wxIsdigit(keycode) || - tolower(keycode) == 'e' || - keycode == decimalPoint || - keycode == '+' || - keycode == '-' ) - { - return true; - } - } - } - - return false; -} - -#endif // wxUSE_TEXTCTRL - -#if wxUSE_CHECKBOX - -// ---------------------------------------------------------------------------- -// wxGridCellBoolEditor -// ---------------------------------------------------------------------------- - -// the default values for GetValue() -wxString wxGridCellBoolEditor::ms_stringValues[2] = { _T(""), _T("1") }; - -void wxGridCellBoolEditor::Create(wxWindow* parent, - wxWindowID id, - wxEvtHandler* evtHandler) -{ - m_control = new wxCheckBox(parent, id, wxEmptyString, - wxDefaultPosition, wxDefaultSize, - wxNO_BORDER); - - wxGridCellEditor::Create(parent, id, evtHandler); -} - -void wxGridCellBoolEditor::SetSize(const wxRect& r) -{ - bool resize = false; - wxSize size = m_control->GetSize(); - wxCoord minSize = wxMin(r.width, r.height); - - // check if the checkbox is not too big/small for this cell - wxSize sizeBest = m_control->GetBestSize(); - if ( !(size == sizeBest) ) - { - // reset to default size if it had been made smaller - size = sizeBest; - - resize = true; - } - - if ( size.x >= minSize || size.y >= minSize ) - { - // leave 1 pixel margin - size.x = size.y = minSize - 2; - - resize = true; - } - - if ( resize ) - { - m_control->SetSize(size); - } - - // position it in the centre of the rectangle (TODO: support alignment?) - -#if defined(__WXGTK__) || defined (__WXMOTIF__) - // the checkbox without label still has some space to the right in wxGTK, - // so shift it to the right - size.x -= 8; -#elif defined(__WXMSW__) - // here too, but in other way - size.x += 1; - size.y -= 2; -#endif - - int hAlign = wxALIGN_CENTRE; - int vAlign = wxALIGN_CENTRE; - if (GetCellAttr()) - GetCellAttr()->GetAlignment(& hAlign, & vAlign); - - int x = 0, y = 0; - if (hAlign == wxALIGN_LEFT) - { - x = r.x + 2; - -#ifdef __WXMSW__ - x += 2; -#endif - - y = r.y + r.height / 2 - size.y / 2; - } - else if (hAlign == wxALIGN_RIGHT) - { - x = r.x + r.width - size.x - 2; - y = r.y + r.height / 2 - size.y / 2; - } - else if (hAlign == wxALIGN_CENTRE) - { - x = r.x + r.width / 2 - size.x / 2; - y = r.y + r.height / 2 - size.y / 2; - } - - m_control->Move(x, y); -} - -void wxGridCellBoolEditor::Show(bool show, wxGridCellAttr *attr) -{ - m_control->Show(show); - - if ( show ) - { - wxColour colBg = attr ? attr->GetBackgroundColour() : *wxLIGHT_GREY; - CBox()->SetBackgroundColour(colBg); - } -} - -void wxGridCellBoolEditor::BeginEdit(int row, int col, wxGrid* grid) -{ - wxASSERT_MSG(m_control, - wxT("The wxGridCellEditor must be created first!")); - - if (grid->GetTable()->CanGetValueAs(row, col, wxGRID_VALUE_BOOL)) - { - m_value = grid->GetTable()->GetValueAsBool(row, col); - } - else - { - wxString cellval( grid->GetTable()->GetValue(row, col) ); - - if ( cellval == ms_stringValues[false] ) - m_value = false; - else if ( cellval == ms_stringValues[true] ) - m_value = true; - else - { - // do not try to be smart here and convert it to true or false - // because we'll still overwrite it with something different and - // this risks to be very surprising for the user code, let them - // know about it - wxFAIL_MSG( _T("invalid value for a cell with bool editor!") ); - } - } - - CBox()->SetValue(m_value); - CBox()->SetFocus(); -} - -bool wxGridCellBoolEditor::EndEdit(const wxString& WXUNUSED(oldval), - wxString *newval) -{ - bool value = CBox()->GetValue(); - if ( value == m_value ) - return false; - - m_value = value; - - if ( newval ) - *newval = GetValue(); - - return true; -} - -void wxGridCellBoolEditor::ApplyEdit(int row, int col, wxGrid* grid) -{ - wxGridTableBase * const table = grid->GetTable(); - if ( table->CanSetValueAs(row, col, wxGRID_VALUE_BOOL) ) - table->SetValueAsBool(row, col, m_value); - else - table->SetValue(row, col, GetValue()); -} - -void wxGridCellBoolEditor::Reset() -{ - wxASSERT_MSG(m_control, - wxT("The wxGridCellEditor must be created first!")); - - CBox()->SetValue(m_value); -} - -void wxGridCellBoolEditor::StartingClick() -{ - CBox()->SetValue(!CBox()->GetValue()); -} - -bool wxGridCellBoolEditor::IsAcceptedKey(wxKeyEvent& event) -{ - if ( wxGridCellEditor::IsAcceptedKey(event) ) - { - int keycode = event.GetKeyCode(); - switch ( keycode ) - { - case WXK_SPACE: - case '+': - case '-': - return true; - } - } - - return false; -} - -void wxGridCellBoolEditor::StartingKey(wxKeyEvent& event) -{ - int keycode = event.GetKeyCode(); - switch ( keycode ) - { - case WXK_SPACE: - CBox()->SetValue(!CBox()->GetValue()); - break; - - case '+': - CBox()->SetValue(true); - break; - - case '-': - CBox()->SetValue(false); - break; - } -} - -wxString wxGridCellBoolEditor::GetValue() const -{ - return ms_stringValues[CBox()->GetValue()]; -} - -/* static */ void -wxGridCellBoolEditor::UseStringValues(const wxString& valueTrue, - const wxString& valueFalse) -{ - ms_stringValues[false] = valueFalse; - ms_stringValues[true] = valueTrue; -} - -/* static */ bool -wxGridCellBoolEditor::IsTrueValue(const wxString& value) -{ - return value == ms_stringValues[true]; -} - -#endif // wxUSE_CHECKBOX - -#if wxUSE_COMBOBOX - -// ---------------------------------------------------------------------------- -// wxGridCellChoiceEditor -// ---------------------------------------------------------------------------- - -wxGridCellChoiceEditor::wxGridCellChoiceEditor(const wxArrayString& choices, - bool allowOthers) - : m_choices(choices), - m_allowOthers(allowOthers) { } - -wxGridCellChoiceEditor::wxGridCellChoiceEditor(size_t count, - const wxString choices[], - bool allowOthers) - : m_allowOthers(allowOthers) -{ - if ( count ) - { - m_choices.Alloc(count); - for ( size_t n = 0; n < count; n++ ) - { - m_choices.Add(choices[n]); - } - } -} - -wxGridCellEditor *wxGridCellChoiceEditor::Clone() const -{ - wxGridCellChoiceEditor *editor = new wxGridCellChoiceEditor; - editor->m_allowOthers = m_allowOthers; - editor->m_choices = m_choices; - - return editor; -} - -void wxGridCellChoiceEditor::Create(wxWindow* parent, - wxWindowID id, - wxEvtHandler* evtHandler) -{ - int style = wxTE_PROCESS_ENTER | - wxTE_PROCESS_TAB | - wxBORDER_NONE; - - if ( !m_allowOthers ) - style |= wxCB_READONLY; - m_control = new wxComboBox(parent, id, wxEmptyString, - wxDefaultPosition, wxDefaultSize, - m_choices, - style); - - wxGridCellEditor::Create(parent, id, evtHandler); -} - -void wxGridCellChoiceEditor::PaintBackground(const wxRect& rectCell, - wxGridCellAttr * attr) -{ - // as we fill the entire client area, don't do anything here to minimize - // flicker - - // TODO: It doesn't actually fill the client area since the height of a - // combo always defaults to the standard. Until someone has time to - // figure out the right rectangle to paint, just do it the normal way. - wxGridCellEditor::PaintBackground(rectCell, attr); -} - -void wxGridCellChoiceEditor::BeginEdit(int row, int col, wxGrid* grid) -{ - wxASSERT_MSG(m_control, - wxT("The wxGridCellEditor must be created first!")); - - wxGridCellEditorEvtHandler* evtHandler = NULL; - if (m_control) - evtHandler = wxDynamicCast(m_control->GetEventHandler(), wxGridCellEditorEvtHandler); - - // Don't immediately end if we get a kill focus event within BeginEdit - if (evtHandler) - evtHandler->SetInSetFocus(true); - - m_value = grid->GetTable()->GetValue(row, col); - - Reset(); // this updates combo box to correspond to m_value - - Combo()->SetFocus(); - - if (evtHandler) - { - // When dropping down the menu, a kill focus event - // happens after this point, so we can't reset the flag yet. -#if !defined(__WXGTK20__) - evtHandler->SetInSetFocus(false); -#endif - } -} - -bool wxGridCellChoiceEditor::EndEdit(const wxString& WXUNUSED(oldval), - wxString *newval) -{ - const wxString value = Combo()->GetValue(); - if ( value == m_value ) - return false; - - m_value = value; - - if ( newval ) - *newval = value; - - return true; -} - -void wxGridCellChoiceEditor::ApplyEdit(int row, int col, wxGrid* grid) -{ - grid->GetTable()->SetValue(row, col, m_value); -} - -void wxGridCellChoiceEditor::Reset() -{ - if (m_allowOthers) - { - Combo()->SetValue(m_value); - Combo()->SetInsertionPointEnd(); - } - else // the combobox is read-only - { - // find the right position, or default to the first if not found - int pos = Combo()->FindString(m_value); - if (pos == wxNOT_FOUND) - pos = 0; - Combo()->SetSelection(pos); - } -} - -void wxGridCellChoiceEditor::SetParameters(const wxString& params) -{ - if ( !params ) - { - // what can we do? - return; - } - - m_choices.Empty(); - - wxStringTokenizer tk(params, _T(',')); - while ( tk.HasMoreTokens() ) - { - m_choices.Add(tk.GetNextToken()); - } -} - -// return the value in the text control -wxString wxGridCellChoiceEditor::GetValue() const -{ - return Combo()->GetValue(); -} - -#endif // wxUSE_COMBOBOX - -// ---------------------------------------------------------------------------- -// wxGridCellEditorEvtHandler -// ---------------------------------------------------------------------------- - -void wxGridCellEditorEvtHandler::OnKillFocus(wxFocusEvent& event) -{ - // Don't disable the cell if we're just starting to edit it - if (m_inSetFocus) - return; - - // accept changes - m_grid->DisableCellEditControl(); - - event.Skip(); -} - -void wxGridCellEditorEvtHandler::OnKeyDown(wxKeyEvent& event) -{ - switch ( event.GetKeyCode() ) - { - case WXK_ESCAPE: - m_editor->Reset(); - m_grid->DisableCellEditControl(); - break; - - case WXK_TAB: - m_grid->GetEventHandler()->ProcessEvent( event ); - break; - - case WXK_RETURN: - case WXK_NUMPAD_ENTER: - if (!m_grid->GetEventHandler()->ProcessEvent(event)) - m_editor->HandleReturn(event); - break; - - default: - event.Skip(); - break; - } -} - -void wxGridCellEditorEvtHandler::OnChar(wxKeyEvent& event) -{ - int row = m_grid->GetGridCursorRow(); - int col = m_grid->GetGridCursorCol(); - wxRect rect = m_grid->CellToRect( row, col ); - int cw, ch; - m_grid->GetGridWindow()->GetClientSize( &cw, &ch ); - - // if cell width is smaller than grid client area, cell is wholly visible - bool wholeCellVisible = (rect.GetWidth() < cw); - - switch ( event.GetKeyCode() ) - { - case WXK_ESCAPE: - case WXK_TAB: - case WXK_RETURN: - case WXK_NUMPAD_ENTER: - break; - - case WXK_HOME: - { - if ( wholeCellVisible ) - { - // no special processing needed... - event.Skip(); - break; - } - - // do special processing for partly visible cell... - - // get the widths of all cells previous to this one - int colXPos = 0; - for ( int i = 0; i < col; i++ ) - { - colXPos += m_grid->GetColSize(i); - } - - int xUnit = 1, yUnit = 1; - m_grid->GetScrollPixelsPerUnit(&xUnit, &yUnit); - if (col != 0) - { - m_grid->Scroll(colXPos / xUnit - 1, m_grid->GetScrollPos(wxVERTICAL)); - } - else - { - m_grid->Scroll(colXPos / xUnit, m_grid->GetScrollPos(wxVERTICAL)); - } - event.Skip(); - break; - } - - case WXK_END: - { - if ( wholeCellVisible ) - { - // no special processing needed... - event.Skip(); - break; - } - - // do special processing for partly visible cell... - - int textWidth = 0; - wxString value = m_grid->GetCellValue(row, col); - if ( wxEmptyString != value ) - { - // get width of cell CONTENTS (text) - int y; - wxFont font = m_grid->GetCellFont(row, col); - m_grid->GetTextExtent(value, &textWidth, &y, NULL, NULL, &font); - - // try to RIGHT align the text by scrolling - int client_right = m_grid->GetGridWindow()->GetClientSize().GetWidth(); - - // (m_grid->GetScrollLineX()*2) is a factor for not scrolling to far, - // otherwise the last part of the cell content might be hidden below the scroll bar - // FIXME: maybe there is a more suitable correction? - textWidth -= (client_right - (m_grid->GetScrollLineX() * 2)); - if ( textWidth < 0 ) - { - textWidth = 0; - } - } - - // get the widths of all cells previous to this one - int colXPos = 0; - for ( int i = 0; i < col; i++ ) - { - colXPos += m_grid->GetColSize(i); - } - - // and add the (modified) text width of the cell contents - // as we'd like to see the last part of the cell contents - colXPos += textWidth; - - int xUnit = 1, yUnit = 1; - m_grid->GetScrollPixelsPerUnit(&xUnit, &yUnit); - m_grid->Scroll(colXPos / xUnit - 1, m_grid->GetScrollPos(wxVERTICAL)); - event.Skip(); - break; - } - - default: - event.Skip(); - break; - } -} - -// ---------------------------------------------------------------------------- -// wxGridCellWorker is an (almost) empty common base class for -// wxGridCellRenderer and wxGridCellEditor managing ref counting -// ---------------------------------------------------------------------------- - -void wxGridCellWorker::SetParameters(const wxString& WXUNUSED(params)) -{ - // nothing to do -} - -wxGridCellWorker::~wxGridCellWorker() -{ -} - -// ============================================================================ -// renderer classes -// ============================================================================ - -// ---------------------------------------------------------------------------- -// wxGridCellRenderer -// ---------------------------------------------------------------------------- - -void wxGridCellRenderer::Draw(wxGrid& grid, - wxGridCellAttr& attr, - wxDC& dc, - const wxRect& rect, - int WXUNUSED(row), int WXUNUSED(col), - bool isSelected) -{ - dc.SetBackgroundMode( wxBRUSHSTYLE_SOLID ); - - wxColour clr; - if ( grid.IsEnabled() ) - { - if ( isSelected ) - { - if ( grid.HasFocus() ) - clr = grid.GetSelectionBackground(); - else - clr = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNSHADOW); - } - else - { - clr = attr.GetBackgroundColour(); - } - } - else // grey out fields if the grid is disabled - { - clr = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE); - } - - dc.SetBrush(clr); - dc.SetPen( *wxTRANSPARENT_PEN ); - dc.DrawRectangle(rect); -} - -// ---------------------------------------------------------------------------- -// wxGridCellStringRenderer -// ---------------------------------------------------------------------------- - -void wxGridCellStringRenderer::SetTextColoursAndFont(const wxGrid& grid, - const wxGridCellAttr& attr, - wxDC& dc, - bool isSelected) -{ - dc.SetBackgroundMode( wxBRUSHSTYLE_TRANSPARENT ); - - // TODO some special colours for attr.IsReadOnly() case? - - // different coloured text when the grid is disabled - if ( grid.IsEnabled() ) - { - if ( isSelected ) - { - wxColour clr; - if ( grid.HasFocus() ) - clr = grid.GetSelectionBackground(); - else - clr = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNSHADOW); - dc.SetTextBackground( clr ); - dc.SetTextForeground( grid.GetSelectionForeground() ); - } - else - { - dc.SetTextBackground( attr.GetBackgroundColour() ); - dc.SetTextForeground( attr.GetTextColour() ); - } - } - else - { - dc.SetTextBackground(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)); - dc.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT)); - } - - dc.SetFont( attr.GetFont() ); -} - -wxSize wxGridCellStringRenderer::DoGetBestSize(const wxGridCellAttr& attr, - wxDC& dc, - const wxString& text) -{ - wxCoord x = 0, y = 0, max_x = 0; - dc.SetFont(attr.GetFont()); - wxStringTokenizer tk(text, _T('\n')); - while ( tk.HasMoreTokens() ) - { - dc.GetTextExtent(tk.GetNextToken(), &x, &y); - max_x = wxMax(max_x, x); - } - - y *= 1 + text.Freq(wxT('\n')); // multiply by the number of lines. - - return wxSize(max_x, y); -} - -wxSize wxGridCellStringRenderer::GetBestSize(wxGrid& grid, - wxGridCellAttr& attr, - wxDC& dc, - int row, int col) -{ - return DoGetBestSize(attr, dc, grid.GetCellValue(row, col)); -} - -void wxGridCellStringRenderer::Draw(wxGrid& grid, - wxGridCellAttr& attr, - wxDC& dc, - const wxRect& rectCell, - int row, int col, - bool isSelected) -{ - wxRect rect = rectCell; - rect.Inflate(-1); - - // erase only this cells background, overflow cells should have been erased - wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected); - - int hAlign, vAlign; - attr.GetAlignment(&hAlign, &vAlign); - - int overflowCols = 0; - - if (attr.GetOverflow()) - { - int cols = grid.GetNumberCols(); - int best_width = GetBestSize(grid,attr,dc,row,col).GetWidth(); - int cell_rows, cell_cols; - attr.GetSize( &cell_rows, &cell_cols ); // shouldn't get here if <= 0 - if ((best_width > rectCell.width) && (col < cols) && grid.GetTable()) - { - int i, c_cols, c_rows; - for (i = col+cell_cols; i < cols; i++) - { - bool is_empty = true; - for (int j=row; j < row + cell_rows; j++) - { - // check w/ anchor cell for multicell block - grid.GetCellSize(j, i, &c_rows, &c_cols); - if (c_rows > 0) - c_rows = 0; - if (!grid.GetTable()->IsEmptyCell(j + c_rows, i)) - { - is_empty = false; - break; - } - } - - if (is_empty) - { - rect.width += grid.GetColSize(i); - } - else - { - i--; - break; - } - - if (rect.width >= best_width) - break; - } - - overflowCols = i - col - cell_cols + 1; - if (overflowCols >= cols) - overflowCols = cols - 1; - } - - if (overflowCols > 0) // redraw overflow cells w/ proper hilight - { - hAlign = wxALIGN_LEFT; // if oveflowed then it's left aligned - wxRect clip = rect; - clip.x += rectCell.width; - // draw each overflow cell individually - int col_end = col + cell_cols + overflowCols; - if (col_end >= grid.GetNumberCols()) - col_end = grid.GetNumberCols() - 1; - for (int i = col + cell_cols; i <= col_end; i++) - { - clip.width = grid.GetColSize(i) - 1; - dc.DestroyClippingRegion(); - dc.SetClippingRegion(clip); - - SetTextColoursAndFont(grid, attr, dc, - grid.IsInSelection(row,i)); - - grid.DrawTextRectangle(dc, grid.GetCellValue(row, col), - rect, hAlign, vAlign); - clip.x += grid.GetColSize(i) - 1; - } - - rect = rectCell; - rect.Inflate(-1); - rect.width++; - dc.DestroyClippingRegion(); - } - } - - // now we only have to draw the text - SetTextColoursAndFont(grid, attr, dc, isSelected); - - grid.DrawTextRectangle(dc, grid.GetCellValue(row, col), - rect, hAlign, vAlign); -} - -// ---------------------------------------------------------------------------- -// wxGridCellNumberRenderer -// ---------------------------------------------------------------------------- - -wxString wxGridCellNumberRenderer::GetString(const wxGrid& grid, int row, int col) -{ - wxGridTableBase *table = grid.GetTable(); - wxString text; - if ( table->CanGetValueAs(row, col, wxGRID_VALUE_NUMBER) ) - { - text.Printf(_T("%ld"), table->GetValueAsLong(row, col)); - } - else - { - text = table->GetValue(row, col); - } - - return text; -} - -void wxGridCellNumberRenderer::Draw(wxGrid& grid, - wxGridCellAttr& attr, - wxDC& dc, - const wxRect& rectCell, - int row, int col, - bool isSelected) -{ - wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected); - - SetTextColoursAndFont(grid, attr, dc, isSelected); - - // draw the text right aligned by default - int hAlign, vAlign; - attr.GetAlignment(&hAlign, &vAlign); - hAlign = wxALIGN_RIGHT; - - wxRect rect = rectCell; - rect.Inflate(-1); - - grid.DrawTextRectangle(dc, GetString(grid, row, col), rect, hAlign, vAlign); -} - -wxSize wxGridCellNumberRenderer::GetBestSize(wxGrid& grid, - wxGridCellAttr& attr, - wxDC& dc, - int row, int col) -{ - return DoGetBestSize(attr, dc, GetString(grid, row, col)); -} - -// ---------------------------------------------------------------------------- -// wxGridCellFloatRenderer -// ---------------------------------------------------------------------------- - -wxGridCellFloatRenderer::wxGridCellFloatRenderer(int width, int precision) -{ - SetWidth(width); - SetPrecision(precision); -} - -wxGridCellRenderer *wxGridCellFloatRenderer::Clone() const -{ - wxGridCellFloatRenderer *renderer = new wxGridCellFloatRenderer; - renderer->m_width = m_width; - renderer->m_precision = m_precision; - renderer->m_format = m_format; - - return renderer; -} - -wxString wxGridCellFloatRenderer::GetString(const wxGrid& grid, int row, int col) -{ - wxGridTableBase *table = grid.GetTable(); - - bool hasDouble; - double val; - wxString text; - if ( table->CanGetValueAs(row, col, wxGRID_VALUE_FLOAT) ) - { - val = table->GetValueAsDouble(row, col); - hasDouble = true; - } - else - { - text = table->GetValue(row, col); - hasDouble = text.ToDouble(&val); - } - - if ( hasDouble ) - { - if ( !m_format ) - { - if ( m_width == -1 ) - { - if ( m_precision == -1 ) - { - // default width/precision - m_format = _T("%f"); - } - else - { - m_format.Printf(_T("%%.%df"), m_precision); - } - } - else if ( m_precision == -1 ) - { - // default precision - m_format.Printf(_T("%%%d.f"), m_width); - } - else - { - m_format.Printf(_T("%%%d.%df"), m_width, m_precision); - } - } - - text.Printf(m_format, val); - - } - //else: text already contains the string +DEFINE_EVENT_TYPE(wxEVT_GRID_CELL_CHANGING) +DEFINE_EVENT_TYPE(wxEVT_GRID_CELL_CHANGED) +DEFINE_EVENT_TYPE(wxEVT_GRID_SELECT_CELL) +DEFINE_EVENT_TYPE(wxEVT_GRID_EDITOR_SHOWN) +DEFINE_EVENT_TYPE(wxEVT_GRID_EDITOR_HIDDEN) +DEFINE_EVENT_TYPE(wxEVT_GRID_EDITOR_CREATED) - return text; -} +// ============================================================================ +// implementation +// ============================================================================ -void wxGridCellFloatRenderer::Draw(wxGrid& grid, - wxGridCellAttr& attr, - wxDC& dc, - const wxRect& rectCell, - int row, int col, - bool isSelected) -{ - wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected); +IMPLEMENT_ABSTRACT_CLASS(wxGridCellEditorEvtHandler, wxEvtHandler) - SetTextColoursAndFont(grid, attr, dc, isSelected); +BEGIN_EVENT_TABLE( wxGridCellEditorEvtHandler, wxEvtHandler ) + EVT_KILL_FOCUS( wxGridCellEditorEvtHandler::OnKillFocus ) + EVT_KEY_DOWN( wxGridCellEditorEvtHandler::OnKeyDown ) + EVT_CHAR( wxGridCellEditorEvtHandler::OnChar ) +END_EVENT_TABLE() - // draw the text right aligned by default - int hAlign, vAlign; - attr.GetAlignment(&hAlign, &vAlign); - hAlign = wxALIGN_RIGHT; +BEGIN_EVENT_TABLE(wxGridHeaderCtrl, wxHeaderCtrl) + EVT_HEADER_CLICK(wxID_ANY, wxGridHeaderCtrl::OnClick) - wxRect rect = rectCell; - rect.Inflate(-1); + EVT_HEADER_BEGIN_RESIZE(wxID_ANY, wxGridHeaderCtrl::OnBeginResize) + EVT_HEADER_RESIZING(wxID_ANY, wxGridHeaderCtrl::OnResizing) + EVT_HEADER_END_RESIZE(wxID_ANY, wxGridHeaderCtrl::OnEndResize) - grid.DrawTextRectangle(dc, GetString(grid, row, col), rect, hAlign, vAlign); -} + EVT_HEADER_BEGIN_REORDER(wxID_ANY, wxGridHeaderCtrl::OnBeginReorder) + EVT_HEADER_END_REORDER(wxID_ANY, wxGridHeaderCtrl::OnEndReorder) +END_EVENT_TABLE() -wxSize wxGridCellFloatRenderer::GetBestSize(wxGrid& grid, - wxGridCellAttr& attr, - wxDC& dc, - int row, int col) +wxGridOperations& wxGridRowOperations::Dual() const { - return DoGetBestSize(attr, dc, GetString(grid, row, col)); + static wxGridColumnOperations s_colOper; + + return s_colOper; } -void wxGridCellFloatRenderer::SetParameters(const wxString& params) +wxGridOperations& wxGridColumnOperations::Dual() const { - if ( !params ) - { - // reset to defaults - SetWidth(-1); - SetPrecision(-1); - } - else - { - wxString tmp = params.BeforeFirst(_T(',')); - if ( !tmp.empty() ) - { - long width; - if ( tmp.ToLong(&width) ) - { - SetWidth((int)width); - } - else - { - wxLogDebug(_T("Invalid wxGridCellFloatRenderer width parameter string '%s ignored"), params.c_str()); - } - } + static wxGridRowOperations s_rowOper; - tmp = params.AfterFirst(_T(',')); - if ( !tmp.empty() ) - { - long precision; - if ( tmp.ToLong(&precision) ) - { - SetPrecision((int)precision); - } - else - { - wxLogDebug(_T("Invalid wxGridCellFloatRenderer precision parameter string '%s ignored"), params.c_str()); - } - } - } + return s_rowOper; } // ---------------------------------------------------------------------------- -// wxGridCellBoolRenderer +// wxGridCellWorker is an (almost) empty common base class for +// wxGridCellRenderer and wxGridCellEditor managing ref counting // ---------------------------------------------------------------------------- -wxSize wxGridCellBoolRenderer::ms_sizeCheckMark; - -// FIXME these checkbox size calculations are really ugly... - -// between checkmark and box -static const wxCoord wxGRID_CHECKMARK_MARGIN = 2; - -wxSize wxGridCellBoolRenderer::GetBestSize(wxGrid& grid, - wxGridCellAttr& WXUNUSED(attr), - wxDC& WXUNUSED(dc), - int WXUNUSED(row), - int WXUNUSED(col)) +void wxGridCellWorker::SetParameters(const wxString& WXUNUSED(params)) { - // compute it only once (no locks for MT safeness in GUI thread...) - if ( !ms_sizeCheckMark.x ) - { - // get checkbox size - wxCheckBox *checkbox = new wxCheckBox(&grid, wxID_ANY, wxEmptyString); - wxSize size = checkbox->GetBestSize(); - wxCoord checkSize = size.y + 2 * wxGRID_CHECKMARK_MARGIN; - -#if defined(__WXMOTIF__) - checkSize -= size.y / 2; -#endif - - delete checkbox; - - ms_sizeCheckMark.x = ms_sizeCheckMark.y = checkSize; - } - - return ms_sizeCheckMark; + // nothing to do } -void wxGridCellBoolRenderer::Draw(wxGrid& grid, - wxGridCellAttr& attr, - wxDC& dc, - const wxRect& rect, - int row, int col, - bool isSelected) +wxGridCellWorker::~wxGridCellWorker() { - wxGridCellRenderer::Draw(grid, attr, dc, rect, row, col, isSelected); - - // draw a check mark in the centre (ignoring alignment - TODO) - wxSize size = GetBestSize(grid, attr, dc, row, col); - - // don't draw outside the cell - wxCoord minSize = wxMin(rect.width, rect.height); - if ( size.x >= minSize || size.y >= minSize ) - { - // and even leave (at least) 1 pixel margin - size.x = size.y = minSize; - } - - // draw a border around checkmark - int vAlign, hAlign; - attr.GetAlignment(&hAlign, &vAlign); - - wxRect rectBorder; - if (hAlign == wxALIGN_CENTRE) - { - rectBorder.x = rect.x + rect.width / 2 - size.x / 2; - rectBorder.y = rect.y + rect.height / 2 - size.y / 2; - rectBorder.width = size.x; - rectBorder.height = size.y; - } - else if (hAlign == wxALIGN_LEFT) - { - rectBorder.x = rect.x + 2; - rectBorder.y = rect.y + rect.height / 2 - size.y / 2; - rectBorder.width = size.x; - rectBorder.height = size.y; - } - else if (hAlign == wxALIGN_RIGHT) - { - rectBorder.x = rect.x + rect.width - size.x - 2; - rectBorder.y = rect.y + rect.height / 2 - size.y / 2; - rectBorder.width = size.x; - rectBorder.height = size.y; - } - - bool value; - if ( grid.GetTable()->CanGetValueAs(row, col, wxGRID_VALUE_BOOL) ) - { - value = grid.GetTable()->GetValueAsBool(row, col); - } - else - { - wxString cellval( grid.GetTable()->GetValue(row, col) ); - value = wxGridCellBoolEditor::IsTrueValue(cellval); - } - - int flags = 0; - if (value) - flags |= wxCONTROL_CHECKED; - - wxRendererNative::Get().DrawCheckBox( &grid, dc, rectBorder, flags ); } // ---------------------------------------------------------------------------- @@ -3485,236 +786,75 @@ wxGridCellAttr *wxGridCellAttrProvider::GetAttr(int row, int col, attr = attrcell; } } - } - break; - - case (wxGridCellAttr::Cell): - attr = m_data->m_cellAttrs.GetAttr(row, col); - break; - - case (wxGridCellAttr::Col): - attr = m_data->m_colAttrs.GetAttr(col); - break; - - case (wxGridCellAttr::Row): - attr = m_data->m_rowAttrs.GetAttr(row); - break; - - default: - // unused as yet... - // (wxGridCellAttr::Default): - // (wxGridCellAttr::Merged): - break; - } - } - - return attr; -} - -void wxGridCellAttrProvider::SetAttr(wxGridCellAttr *attr, - int row, int col) -{ - if ( !m_data ) - InitData(); - - m_data->m_cellAttrs.SetAttr(attr, row, col); -} - -void wxGridCellAttrProvider::SetRowAttr(wxGridCellAttr *attr, int row) -{ - if ( !m_data ) - InitData(); - - m_data->m_rowAttrs.SetAttr(attr, row); -} - -void wxGridCellAttrProvider::SetColAttr(wxGridCellAttr *attr, int col) -{ - if ( !m_data ) - InitData(); - - m_data->m_colAttrs.SetAttr(attr, col); -} - -void wxGridCellAttrProvider::UpdateAttrRows( size_t pos, int numRows ) -{ - if ( m_data ) - { - m_data->m_cellAttrs.UpdateAttrRows( pos, numRows ); - - m_data->m_rowAttrs.UpdateAttrRowsOrCols( pos, numRows ); - } -} - -void wxGridCellAttrProvider::UpdateAttrCols( size_t pos, int numCols ) -{ - if ( m_data ) - { - m_data->m_cellAttrs.UpdateAttrCols( pos, numCols ); - - m_data->m_colAttrs.UpdateAttrRowsOrCols( pos, numCols ); - } -} - -// ---------------------------------------------------------------------------- -// wxGridTypeRegistry -// ---------------------------------------------------------------------------- - -wxGridTypeRegistry::~wxGridTypeRegistry() -{ - size_t count = m_typeinfo.GetCount(); - for ( size_t i = 0; i < count; i++ ) - delete m_typeinfo[i]; -} - -void wxGridTypeRegistry::RegisterDataType(const wxString& typeName, - wxGridCellRenderer* renderer, - wxGridCellEditor* editor) -{ - wxGridDataTypeInfo* info = new wxGridDataTypeInfo(typeName, renderer, editor); - - // is it already registered? - int loc = FindRegisteredDataType(typeName); - if ( loc != wxNOT_FOUND ) - { - delete m_typeinfo[loc]; - m_typeinfo[loc] = info; - } - else - { - m_typeinfo.Add(info); - } -} - -int wxGridTypeRegistry::FindRegisteredDataType(const wxString& typeName) -{ - size_t count = m_typeinfo.GetCount(); - for ( size_t i = 0; i < count; i++ ) - { - if ( typeName == m_typeinfo[i]->m_typeName ) - { - return i; - } - } - - return wxNOT_FOUND; -} - -int wxGridTypeRegistry::FindDataType(const wxString& typeName) -{ - int index = FindRegisteredDataType(typeName); - if ( index == wxNOT_FOUND ) - { - // check whether this is one of the standard ones, in which case - // register it "on the fly" -#if wxUSE_TEXTCTRL - if ( typeName == wxGRID_VALUE_STRING ) - { - RegisterDataType(wxGRID_VALUE_STRING, - new wxGridCellStringRenderer, - new wxGridCellTextEditor); - } - else -#endif // wxUSE_TEXTCTRL -#if wxUSE_CHECKBOX - if ( typeName == wxGRID_VALUE_BOOL ) - { - RegisterDataType(wxGRID_VALUE_BOOL, - new wxGridCellBoolRenderer, - new wxGridCellBoolEditor); - } - else -#endif // wxUSE_CHECKBOX -#if wxUSE_TEXTCTRL - if ( typeName == wxGRID_VALUE_NUMBER ) - { - RegisterDataType(wxGRID_VALUE_NUMBER, - new wxGridCellNumberRenderer, - new wxGridCellNumberEditor); - } - else if ( typeName == wxGRID_VALUE_FLOAT ) - { - RegisterDataType(wxGRID_VALUE_FLOAT, - new wxGridCellFloatRenderer, - new wxGridCellFloatEditor); - } - else -#endif // wxUSE_TEXTCTRL -#if wxUSE_COMBOBOX - if ( typeName == wxGRID_VALUE_CHOICE ) - { - RegisterDataType(wxGRID_VALUE_CHOICE, - new wxGridCellStringRenderer, - new wxGridCellChoiceEditor); - } - else -#endif // wxUSE_COMBOBOX - { - return wxNOT_FOUND; - } + } + break; - // we get here only if just added the entry for this type, so return - // the last index - index = m_typeinfo.GetCount() - 1; + case (wxGridCellAttr::Cell): + attr = m_data->m_cellAttrs.GetAttr(row, col); + break; + + case (wxGridCellAttr::Col): + attr = m_data->m_colAttrs.GetAttr(col); + break; + + case (wxGridCellAttr::Row): + attr = m_data->m_rowAttrs.GetAttr(row); + break; + + default: + // unused as yet... + // (wxGridCellAttr::Default): + // (wxGridCellAttr::Merged): + break; + } } - return index; + return attr; } -int wxGridTypeRegistry::FindOrCloneDataType(const wxString& typeName) +void wxGridCellAttrProvider::SetAttr(wxGridCellAttr *attr, + int row, int col) { - int index = FindDataType(typeName); - if ( index == wxNOT_FOUND ) - { - // the first part of the typename is the "real" type, anything after ':' - // are the parameters for the renderer - index = FindDataType(typeName.BeforeFirst(_T(':'))); - if ( index == wxNOT_FOUND ) - { - return wxNOT_FOUND; - } - - wxGridCellRenderer *renderer = GetRenderer(index); - wxGridCellRenderer *rendererOld = renderer; - renderer = renderer->Clone(); - rendererOld->DecRef(); + if ( !m_data ) + InitData(); - wxGridCellEditor *editor = GetEditor(index); - wxGridCellEditor *editorOld = editor; - editor = editor->Clone(); - editorOld->DecRef(); + m_data->m_cellAttrs.SetAttr(attr, row, col); +} - // do it even if there are no parameters to reset them to defaults - wxString params = typeName.AfterFirst(_T(':')); - renderer->SetParameters(params); - editor->SetParameters(params); +void wxGridCellAttrProvider::SetRowAttr(wxGridCellAttr *attr, int row) +{ + if ( !m_data ) + InitData(); - // register the new typename - RegisterDataType(typeName, renderer, editor); + m_data->m_rowAttrs.SetAttr(attr, row); +} - // we just registered it, it's the last one - index = m_typeinfo.GetCount() - 1; - } +void wxGridCellAttrProvider::SetColAttr(wxGridCellAttr *attr, int col) +{ + if ( !m_data ) + InitData(); - return index; + m_data->m_colAttrs.SetAttr(attr, col); } -wxGridCellRenderer* wxGridTypeRegistry::GetRenderer(int index) +void wxGridCellAttrProvider::UpdateAttrRows( size_t pos, int numRows ) { - wxGridCellRenderer* renderer = m_typeinfo[index]->m_renderer; - if (renderer) - renderer->IncRef(); + if ( m_data ) + { + m_data->m_cellAttrs.UpdateAttrRows( pos, numRows ); - return renderer; + m_data->m_rowAttrs.UpdateAttrRowsOrCols( pos, numRows ); + } } -wxGridCellEditor* wxGridTypeRegistry::GetEditor(int index) +void wxGridCellAttrProvider::UpdateAttrCols( size_t pos, int numCols ) { - wxGridCellEditor* editor = m_typeinfo[index]->m_editor; - if (editor) - editor->IncRef(); + if ( m_data ) + { + m_data->m_cellAttrs.UpdateAttrCols( pos, numCols ); - return editor; + m_data->m_colAttrs.UpdateAttrRowsOrCols( pos, numCols ); + } } // ---------------------------------------------------------------------------- @@ -11268,4 +8408,166 @@ wxGridEditorCreatedEvent::wxGridEditorCreatedEvent(int id, wxEventType type, m_ctrl = ctrl; } + +// ---------------------------------------------------------------------------- +// wxGridTypeRegistry +// ---------------------------------------------------------------------------- + +wxGridTypeRegistry::~wxGridTypeRegistry() +{ + size_t count = m_typeinfo.GetCount(); + for ( size_t i = 0; i < count; i++ ) + delete m_typeinfo[i]; +} + +void wxGridTypeRegistry::RegisterDataType(const wxString& typeName, + wxGridCellRenderer* renderer, + wxGridCellEditor* editor) +{ + wxGridDataTypeInfo* info = new wxGridDataTypeInfo(typeName, renderer, editor); + + // is it already registered? + int loc = FindRegisteredDataType(typeName); + if ( loc != wxNOT_FOUND ) + { + delete m_typeinfo[loc]; + m_typeinfo[loc] = info; + } + else + { + m_typeinfo.Add(info); + } +} + +int wxGridTypeRegistry::FindRegisteredDataType(const wxString& typeName) +{ + size_t count = m_typeinfo.GetCount(); + for ( size_t i = 0; i < count; i++ ) + { + if ( typeName == m_typeinfo[i]->m_typeName ) + { + return i; + } + } + + return wxNOT_FOUND; +} + +int wxGridTypeRegistry::FindDataType(const wxString& typeName) +{ + int index = FindRegisteredDataType(typeName); + if ( index == wxNOT_FOUND ) + { + // check whether this is one of the standard ones, in which case + // register it "on the fly" +#if wxUSE_TEXTCTRL + if ( typeName == wxGRID_VALUE_STRING ) + { + RegisterDataType(wxGRID_VALUE_STRING, + new wxGridCellStringRenderer, + new wxGridCellTextEditor); + } + else +#endif // wxUSE_TEXTCTRL +#if wxUSE_CHECKBOX + if ( typeName == wxGRID_VALUE_BOOL ) + { + RegisterDataType(wxGRID_VALUE_BOOL, + new wxGridCellBoolRenderer, + new wxGridCellBoolEditor); + } + else +#endif // wxUSE_CHECKBOX +#if wxUSE_TEXTCTRL + if ( typeName == wxGRID_VALUE_NUMBER ) + { + RegisterDataType(wxGRID_VALUE_NUMBER, + new wxGridCellNumberRenderer, + new wxGridCellNumberEditor); + } + else if ( typeName == wxGRID_VALUE_FLOAT ) + { + RegisterDataType(wxGRID_VALUE_FLOAT, + new wxGridCellFloatRenderer, + new wxGridCellFloatEditor); + } + else +#endif // wxUSE_TEXTCTRL +#if wxUSE_COMBOBOX + if ( typeName == wxGRID_VALUE_CHOICE ) + { + RegisterDataType(wxGRID_VALUE_CHOICE, + new wxGridCellStringRenderer, + new wxGridCellChoiceEditor); + } + else +#endif // wxUSE_COMBOBOX + { + return wxNOT_FOUND; + } + + // we get here only if just added the entry for this type, so return + // the last index + index = m_typeinfo.GetCount() - 1; + } + + return index; +} + +int wxGridTypeRegistry::FindOrCloneDataType(const wxString& typeName) +{ + int index = FindDataType(typeName); + if ( index == wxNOT_FOUND ) + { + // the first part of the typename is the "real" type, anything after ':' + // are the parameters for the renderer + index = FindDataType(typeName.BeforeFirst(_T(':'))); + if ( index == wxNOT_FOUND ) + { + return wxNOT_FOUND; + } + + wxGridCellRenderer *renderer = GetRenderer(index); + wxGridCellRenderer *rendererOld = renderer; + renderer = renderer->Clone(); + rendererOld->DecRef(); + + wxGridCellEditor *editor = GetEditor(index); + wxGridCellEditor *editorOld = editor; + editor = editor->Clone(); + editorOld->DecRef(); + + // do it even if there are no parameters to reset them to defaults + wxString params = typeName.AfterFirst(_T(':')); + renderer->SetParameters(params); + editor->SetParameters(params); + + // register the new typename + RegisterDataType(typeName, renderer, editor); + + // we just registered it, it's the last one + index = m_typeinfo.GetCount() - 1; + } + + return index; +} + +wxGridCellRenderer* wxGridTypeRegistry::GetRenderer(int index) +{ + wxGridCellRenderer* renderer = m_typeinfo[index]->m_renderer; + if (renderer) + renderer->IncRef(); + + return renderer; +} + +wxGridCellEditor* wxGridTypeRegistry::GetEditor(int index) +{ + wxGridCellEditor* editor = m_typeinfo[index]->m_editor; + if (editor) + editor->IncRef(); + + return editor; +} + #endif // wxUSE_GRID diff --git a/src/generic/gridctrl.cpp b/src/generic/gridctrl.cpp index 052dfbd49f..d1df91d099 100644 --- a/src/generic/gridctrl.cpp +++ b/src/generic/gridctrl.cpp @@ -18,6 +18,7 @@ #if wxUSE_GRID #include "wx/generic/gridctrl.h" +#include "wx/generic/grideditors.h" #ifndef WX_PRECOMP #include "wx/textctrl.h" @@ -26,6 +27,7 @@ #endif // WX_PRECOMP #include "wx/tokenzr.h" +#include "wx/renderer.h" // ---------------------------------------------------------------------------- // wxGridCellDateTimeRenderer @@ -212,100 +214,11 @@ void wxGridCellEnumRenderer::SetParameters(const wxString& params) } } -#if wxUSE_COMBOBOX // ---------------------------------------------------------------------------- -// wxGridCellEnumEditor +// wxGridCellAutoWrapStringRenderer // ---------------------------------------------------------------------------- -// A cell editor which displays an enum number as a textual equivalent. eg -// data in cell is 0,1,2 ... n the cell could be displayed as -// "John","Fred"..."Bob" in the combo choice box - -wxGridCellEnumEditor::wxGridCellEnumEditor(const wxString& choices) - :wxGridCellChoiceEditor() -{ - m_index = -1; - - if (!choices.empty()) - SetParameters(choices); -} - -wxGridCellEditor *wxGridCellEnumEditor::Clone() const -{ - wxGridCellEnumEditor *editor = new wxGridCellEnumEditor(); - editor->m_index = m_index; - return editor; -} - -void wxGridCellEnumEditor::BeginEdit(int row, int col, wxGrid* grid) -{ - wxASSERT_MSG(m_control, - wxT("The wxGridCellEnumEditor must be Created first!")); - - wxGridTableBase *table = grid->GetTable(); - - if ( table->CanGetValueAs(row, col, wxGRID_VALUE_NUMBER) ) - { - m_index = table->GetValueAsLong(row, col); - } - else - { - wxString startValue = table->GetValue(row, col); - if (startValue.IsNumber() && !startValue.empty()) - { - startValue.ToLong(&m_index); - } - else - { - m_index = -1; - } - } - - Combo()->SetSelection(m_index); - Combo()->SetInsertionPointEnd(); - Combo()->SetFocus(); - -} - -bool wxGridCellEnumEditor::EndEdit(const wxString& WXUNUSED(oldval), - wxString *newval) -{ - long idx = Combo()->GetSelection(); - if ( idx == m_index ) - return false; - - m_index = idx; - - if ( newval ) - newval->Printf("%ld", m_index); - - return true; -} - -void wxGridCellEnumEditor::ApplyEdit(int row, int col, wxGrid* grid) -{ - wxGridTableBase * const table = grid->GetTable(); - if ( table->CanSetValueAs(row, col, wxGRID_VALUE_NUMBER) ) - table->SetValueAsLong(row, col, m_index); - else - table->SetValue(row, col, wxString::Format("%ld", m_index)); -} - -#endif // wxUSE_COMBOBOX - -// ---------------------------------------------------------------------------- -// wxGridCellAutoWrapStringEditor -// ---------------------------------------------------------------------------- - -void -wxGridCellAutoWrapStringEditor::Create(wxWindow* parent, - wxWindowID id, - wxEvtHandler* evtHandler) -{ - wxGridCellTextEditor::DoCreate(parent, id, evtHandler, - wxTE_MULTILINE | wxTE_RICH); -} void wxGridCellAutoWrapStringRenderer::Draw(wxGrid& grid, @@ -411,5 +324,505 @@ wxGridCellAutoWrapStringRenderer::GetBestSize(wxGrid& grid, return wxSize(width,height); } + +// ---------------------------------------------------------------------------- +// wxGridCellRenderer +// ---------------------------------------------------------------------------- + +void wxGridCellRenderer::Draw(wxGrid& grid, + wxGridCellAttr& attr, + wxDC& dc, + const wxRect& rect, + int WXUNUSED(row), int WXUNUSED(col), + bool isSelected) +{ + dc.SetBackgroundMode( wxBRUSHSTYLE_SOLID ); + + wxColour clr; + if ( grid.IsEnabled() ) + { + if ( isSelected ) + { + if ( grid.HasFocus() ) + clr = grid.GetSelectionBackground(); + else + clr = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNSHADOW); + } + else + { + clr = attr.GetBackgroundColour(); + } + } + else // grey out fields if the grid is disabled + { + clr = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE); + } + + dc.SetBrush(clr); + dc.SetPen( *wxTRANSPARENT_PEN ); + dc.DrawRectangle(rect); +} + +// ---------------------------------------------------------------------------- +// wxGridCellStringRenderer +// ---------------------------------------------------------------------------- + +void wxGridCellStringRenderer::SetTextColoursAndFont(const wxGrid& grid, + const wxGridCellAttr& attr, + wxDC& dc, + bool isSelected) +{ + dc.SetBackgroundMode( wxBRUSHSTYLE_TRANSPARENT ); + + // TODO some special colours for attr.IsReadOnly() case? + + // different coloured text when the grid is disabled + if ( grid.IsEnabled() ) + { + if ( isSelected ) + { + wxColour clr; + if ( grid.HasFocus() ) + clr = grid.GetSelectionBackground(); + else + clr = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNSHADOW); + dc.SetTextBackground( clr ); + dc.SetTextForeground( grid.GetSelectionForeground() ); + } + else + { + dc.SetTextBackground( attr.GetBackgroundColour() ); + dc.SetTextForeground( attr.GetTextColour() ); + } + } + else + { + dc.SetTextBackground(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)); + dc.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT)); + } + + dc.SetFont( attr.GetFont() ); +} + +wxSize wxGridCellStringRenderer::DoGetBestSize(const wxGridCellAttr& attr, + wxDC& dc, + const wxString& text) +{ + wxCoord x = 0, y = 0, max_x = 0; + dc.SetFont(attr.GetFont()); + wxStringTokenizer tk(text, _T('\n')); + while ( tk.HasMoreTokens() ) + { + dc.GetTextExtent(tk.GetNextToken(), &x, &y); + max_x = wxMax(max_x, x); + } + + y *= 1 + text.Freq(wxT('\n')); // multiply by the number of lines. + + return wxSize(max_x, y); +} + +wxSize wxGridCellStringRenderer::GetBestSize(wxGrid& grid, + wxGridCellAttr& attr, + wxDC& dc, + int row, int col) +{ + return DoGetBestSize(attr, dc, grid.GetCellValue(row, col)); +} + +void wxGridCellStringRenderer::Draw(wxGrid& grid, + wxGridCellAttr& attr, + wxDC& dc, + const wxRect& rectCell, + int row, int col, + bool isSelected) +{ + wxRect rect = rectCell; + rect.Inflate(-1); + + // erase only this cells background, overflow cells should have been erased + wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected); + + int hAlign, vAlign; + attr.GetAlignment(&hAlign, &vAlign); + + int overflowCols = 0; + + if (attr.GetOverflow()) + { + int cols = grid.GetNumberCols(); + int best_width = GetBestSize(grid,attr,dc,row,col).GetWidth(); + int cell_rows, cell_cols; + attr.GetSize( &cell_rows, &cell_cols ); // shouldn't get here if <= 0 + if ((best_width > rectCell.width) && (col < cols) && grid.GetTable()) + { + int i, c_cols, c_rows; + for (i = col+cell_cols; i < cols; i++) + { + bool is_empty = true; + for (int j=row; j < row + cell_rows; j++) + { + // check w/ anchor cell for multicell block + grid.GetCellSize(j, i, &c_rows, &c_cols); + if (c_rows > 0) + c_rows = 0; + if (!grid.GetTable()->IsEmptyCell(j + c_rows, i)) + { + is_empty = false; + break; + } + } + + if (is_empty) + { + rect.width += grid.GetColSize(i); + } + else + { + i--; + break; + } + + if (rect.width >= best_width) + break; + } + + overflowCols = i - col - cell_cols + 1; + if (overflowCols >= cols) + overflowCols = cols - 1; + } + + if (overflowCols > 0) // redraw overflow cells w/ proper hilight + { + hAlign = wxALIGN_LEFT; // if oveflowed then it's left aligned + wxRect clip = rect; + clip.x += rectCell.width; + // draw each overflow cell individually + int col_end = col + cell_cols + overflowCols; + if (col_end >= grid.GetNumberCols()) + col_end = grid.GetNumberCols() - 1; + for (int i = col + cell_cols; i <= col_end; i++) + { + clip.width = grid.GetColSize(i) - 1; + dc.DestroyClippingRegion(); + dc.SetClippingRegion(clip); + + SetTextColoursAndFont(grid, attr, dc, + grid.IsInSelection(row,i)); + + grid.DrawTextRectangle(dc, grid.GetCellValue(row, col), + rect, hAlign, vAlign); + clip.x += grid.GetColSize(i) - 1; + } + + rect = rectCell; + rect.Inflate(-1); + rect.width++; + dc.DestroyClippingRegion(); + } + } + + // now we only have to draw the text + SetTextColoursAndFont(grid, attr, dc, isSelected); + + grid.DrawTextRectangle(dc, grid.GetCellValue(row, col), + rect, hAlign, vAlign); +} + +// ---------------------------------------------------------------------------- +// wxGridCellNumberRenderer +// ---------------------------------------------------------------------------- + +wxString wxGridCellNumberRenderer::GetString(const wxGrid& grid, int row, int col) +{ + wxGridTableBase *table = grid.GetTable(); + wxString text; + if ( table->CanGetValueAs(row, col, wxGRID_VALUE_NUMBER) ) + { + text.Printf(_T("%ld"), table->GetValueAsLong(row, col)); + } + else + { + text = table->GetValue(row, col); + } + + return text; +} + +void wxGridCellNumberRenderer::Draw(wxGrid& grid, + wxGridCellAttr& attr, + wxDC& dc, + const wxRect& rectCell, + int row, int col, + bool isSelected) +{ + wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected); + + SetTextColoursAndFont(grid, attr, dc, isSelected); + + // draw the text right aligned by default + int hAlign, vAlign; + attr.GetAlignment(&hAlign, &vAlign); + hAlign = wxALIGN_RIGHT; + + wxRect rect = rectCell; + rect.Inflate(-1); + + grid.DrawTextRectangle(dc, GetString(grid, row, col), rect, hAlign, vAlign); +} + +wxSize wxGridCellNumberRenderer::GetBestSize(wxGrid& grid, + wxGridCellAttr& attr, + wxDC& dc, + int row, int col) +{ + return DoGetBestSize(attr, dc, GetString(grid, row, col)); +} + +// ---------------------------------------------------------------------------- +// wxGridCellFloatRenderer +// ---------------------------------------------------------------------------- + +wxGridCellFloatRenderer::wxGridCellFloatRenderer(int width, int precision) +{ + SetWidth(width); + SetPrecision(precision); +} + +wxGridCellRenderer *wxGridCellFloatRenderer::Clone() const +{ + wxGridCellFloatRenderer *renderer = new wxGridCellFloatRenderer; + renderer->m_width = m_width; + renderer->m_precision = m_precision; + renderer->m_format = m_format; + + return renderer; +} + +wxString wxGridCellFloatRenderer::GetString(const wxGrid& grid, int row, int col) +{ + wxGridTableBase *table = grid.GetTable(); + + bool hasDouble; + double val; + wxString text; + if ( table->CanGetValueAs(row, col, wxGRID_VALUE_FLOAT) ) + { + val = table->GetValueAsDouble(row, col); + hasDouble = true; + } + else + { + text = table->GetValue(row, col); + hasDouble = text.ToDouble(&val); + } + + if ( hasDouble ) + { + if ( !m_format ) + { + if ( m_width == -1 ) + { + if ( m_precision == -1 ) + { + // default width/precision + m_format = _T("%f"); + } + else + { + m_format.Printf(_T("%%.%df"), m_precision); + } + } + else if ( m_precision == -1 ) + { + // default precision + m_format.Printf(_T("%%%d.f"), m_width); + } + else + { + m_format.Printf(_T("%%%d.%df"), m_width, m_precision); + } + } + + text.Printf(m_format, val); + + } + //else: text already contains the string + + return text; +} + +void wxGridCellFloatRenderer::Draw(wxGrid& grid, + wxGridCellAttr& attr, + wxDC& dc, + const wxRect& rectCell, + int row, int col, + bool isSelected) +{ + wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected); + + SetTextColoursAndFont(grid, attr, dc, isSelected); + + // draw the text right aligned by default + int hAlign, vAlign; + attr.GetAlignment(&hAlign, &vAlign); + hAlign = wxALIGN_RIGHT; + + wxRect rect = rectCell; + rect.Inflate(-1); + + grid.DrawTextRectangle(dc, GetString(grid, row, col), rect, hAlign, vAlign); +} + +wxSize wxGridCellFloatRenderer::GetBestSize(wxGrid& grid, + wxGridCellAttr& attr, + wxDC& dc, + int row, int col) +{ + return DoGetBestSize(attr, dc, GetString(grid, row, col)); +} + +void wxGridCellFloatRenderer::SetParameters(const wxString& params) +{ + if ( !params ) + { + // reset to defaults + SetWidth(-1); + SetPrecision(-1); + } + else + { + wxString tmp = params.BeforeFirst(_T(',')); + if ( !tmp.empty() ) + { + long width; + if ( tmp.ToLong(&width) ) + { + SetWidth((int)width); + } + else + { + wxLogDebug(_T("Invalid wxGridCellFloatRenderer width parameter string '%s ignored"), params.c_str()); + } + } + + tmp = params.AfterFirst(_T(',')); + if ( !tmp.empty() ) + { + long precision; + if ( tmp.ToLong(&precision) ) + { + SetPrecision((int)precision); + } + else + { + wxLogDebug(_T("Invalid wxGridCellFloatRenderer precision parameter string '%s ignored"), params.c_str()); + } + } + } +} + +// ---------------------------------------------------------------------------- +// wxGridCellBoolRenderer +// ---------------------------------------------------------------------------- + +wxSize wxGridCellBoolRenderer::ms_sizeCheckMark; + +// FIXME these checkbox size calculations are really ugly... + +// between checkmark and box +static const wxCoord wxGRID_CHECKMARK_MARGIN = 2; + +wxSize wxGridCellBoolRenderer::GetBestSize(wxGrid& grid, + wxGridCellAttr& WXUNUSED(attr), + wxDC& WXUNUSED(dc), + int WXUNUSED(row), + int WXUNUSED(col)) +{ + // compute it only once (no locks for MT safeness in GUI thread...) + if ( !ms_sizeCheckMark.x ) + { + // get checkbox size + wxCheckBox *checkbox = new wxCheckBox(&grid, wxID_ANY, wxEmptyString); + wxSize size = checkbox->GetBestSize(); + wxCoord checkSize = size.y + 2 * wxGRID_CHECKMARK_MARGIN; + +#if defined(__WXMOTIF__) + checkSize -= size.y / 2; +#endif + + delete checkbox; + + ms_sizeCheckMark.x = ms_sizeCheckMark.y = checkSize; + } + + return ms_sizeCheckMark; +} + +void wxGridCellBoolRenderer::Draw(wxGrid& grid, + wxGridCellAttr& attr, + wxDC& dc, + const wxRect& rect, + int row, int col, + bool isSelected) +{ + wxGridCellRenderer::Draw(grid, attr, dc, rect, row, col, isSelected); + + // draw a check mark in the centre (ignoring alignment - TODO) + wxSize size = GetBestSize(grid, attr, dc, row, col); + + // don't draw outside the cell + wxCoord minSize = wxMin(rect.width, rect.height); + if ( size.x >= minSize || size.y >= minSize ) + { + // and even leave (at least) 1 pixel margin + size.x = size.y = minSize; + } + + // draw a border around checkmark + int vAlign, hAlign; + attr.GetAlignment(&hAlign, &vAlign); + + wxRect rectBorder; + if (hAlign == wxALIGN_CENTRE) + { + rectBorder.x = rect.x + rect.width / 2 - size.x / 2; + rectBorder.y = rect.y + rect.height / 2 - size.y / 2; + rectBorder.width = size.x; + rectBorder.height = size.y; + } + else if (hAlign == wxALIGN_LEFT) + { + rectBorder.x = rect.x + 2; + rectBorder.y = rect.y + rect.height / 2 - size.y / 2; + rectBorder.width = size.x; + rectBorder.height = size.y; + } + else if (hAlign == wxALIGN_RIGHT) + { + rectBorder.x = rect.x + rect.width - size.x - 2; + rectBorder.y = rect.y + rect.height / 2 - size.y / 2; + rectBorder.width = size.x; + rectBorder.height = size.y; + } + + bool value; + if ( grid.GetTable()->CanGetValueAs(row, col, wxGRID_VALUE_BOOL) ) + { + value = grid.GetTable()->GetValueAsBool(row, col); + } + else + { + wxString cellval( grid.GetTable()->GetValue(row, col) ); + value = wxGridCellBoolEditor::IsTrueValue(cellval); + } + + int flags = 0; + if (value) + flags |= wxCONTROL_CHECKED; + + wxRendererNative::Get().DrawCheckBox( &grid, dc, rectBorder, flags ); +} + #endif // wxUSE_GRID diff --git a/src/generic/grideditors.cpp b/src/generic/grideditors.cpp new file mode 100644 index 0000000000..997626c10e --- /dev/null +++ b/src/generic/grideditors.cpp @@ -0,0 +1,1524 @@ +/////////////////////////////////////////////////////////////////////////// +// Name: src/generic/grideditors.cpp +// Purpose: wxGridCellEditorEvtHandler and wxGrid editors +// Author: Michael Bedward (based on code by Julian Smart, Robin Dunn) +// Modified by: Robin Dunn, Vadim Zeitlin, Santiago Palacios +// Created: 1/08/1999 +// RCS-ID: $Id$ +// Copyright: (c) Michael Bedward (mbedward@ozemail.com.au) +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +// For compilers that support precompilation, includes "wx/wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#if wxUSE_GRID + +#include "wx/grid.h" + +#ifndef WX_PRECOMP + #include "wx/utils.h" + #include "wx/dcclient.h" + #include "wx/settings.h" + #include "wx/log.h" + #include "wx/textctrl.h" + #include "wx/checkbox.h" + #include "wx/combobox.h" + #include "wx/valtext.h" + #include "wx/intl.h" + #include "wx/math.h" + #include "wx/listbox.h" +#endif + +#include "wx/textfile.h" +#include "wx/spinctrl.h" +#include "wx/tokenzr.h" +#include "wx/renderer.h" +#include "wx/headerctrl.h" + +#include "wx/generic/gridsel.h" +#include "wx/generic/grideditors.h" +#include "wx/generic/private/grid.h" + +#if defined(__WXMOTIF__) + #define WXUNUSED_MOTIF(identifier) WXUNUSED(identifier) +#else + #define WXUNUSED_MOTIF(identifier) identifier +#endif + +#if defined(__WXGTK__) + #define WXUNUSED_GTK(identifier) WXUNUSED(identifier) +#else + #define WXUNUSED_GTK(identifier) identifier +#endif + +// Required for wxIs... functions +#include + +// ============================================================================ +// implementation +// ============================================================================ + +// ---------------------------------------------------------------------------- +// wxGridCellEditorEvtHandler +// ---------------------------------------------------------------------------- + +void wxGridCellEditorEvtHandler::OnKillFocus(wxFocusEvent& event) +{ + // Don't disable the cell if we're just starting to edit it + if (m_inSetFocus) + return; + + // accept changes + m_grid->DisableCellEditControl(); + + event.Skip(); +} + +void wxGridCellEditorEvtHandler::OnKeyDown(wxKeyEvent& event) +{ + switch ( event.GetKeyCode() ) + { + case WXK_ESCAPE: + m_editor->Reset(); + m_grid->DisableCellEditControl(); + break; + + case WXK_TAB: + m_grid->GetEventHandler()->ProcessEvent( event ); + break; + + case WXK_RETURN: + case WXK_NUMPAD_ENTER: + if (!m_grid->GetEventHandler()->ProcessEvent(event)) + m_editor->HandleReturn(event); + break; + + default: + event.Skip(); + break; + } +} + +void wxGridCellEditorEvtHandler::OnChar(wxKeyEvent& event) +{ + int row = m_grid->GetGridCursorRow(); + int col = m_grid->GetGridCursorCol(); + wxRect rect = m_grid->CellToRect( row, col ); + int cw, ch; + m_grid->GetGridWindow()->GetClientSize( &cw, &ch ); + + // if cell width is smaller than grid client area, cell is wholly visible + bool wholeCellVisible = (rect.GetWidth() < cw); + + switch ( event.GetKeyCode() ) + { + case WXK_ESCAPE: + case WXK_TAB: + case WXK_RETURN: + case WXK_NUMPAD_ENTER: + break; + + case WXK_HOME: + { + if ( wholeCellVisible ) + { + // no special processing needed... + event.Skip(); + break; + } + + // do special processing for partly visible cell... + + // get the widths of all cells previous to this one + int colXPos = 0; + for ( int i = 0; i < col; i++ ) + { + colXPos += m_grid->GetColSize(i); + } + + int xUnit = 1, yUnit = 1; + m_grid->GetScrollPixelsPerUnit(&xUnit, &yUnit); + if (col != 0) + { + m_grid->Scroll(colXPos / xUnit - 1, m_grid->GetScrollPos(wxVERTICAL)); + } + else + { + m_grid->Scroll(colXPos / xUnit, m_grid->GetScrollPos(wxVERTICAL)); + } + event.Skip(); + break; + } + + case WXK_END: + { + if ( wholeCellVisible ) + { + // no special processing needed... + event.Skip(); + break; + } + + // do special processing for partly visible cell... + + int textWidth = 0; + wxString value = m_grid->GetCellValue(row, col); + if ( wxEmptyString != value ) + { + // get width of cell CONTENTS (text) + int y; + wxFont font = m_grid->GetCellFont(row, col); + m_grid->GetTextExtent(value, &textWidth, &y, NULL, NULL, &font); + + // try to RIGHT align the text by scrolling + int client_right = m_grid->GetGridWindow()->GetClientSize().GetWidth(); + + // (m_grid->GetScrollLineX()*2) is a factor for not scrolling to far, + // otherwise the last part of the cell content might be hidden below the scroll bar + // FIXME: maybe there is a more suitable correction? + textWidth -= (client_right - (m_grid->GetScrollLineX() * 2)); + if ( textWidth < 0 ) + { + textWidth = 0; + } + } + + // get the widths of all cells previous to this one + int colXPos = 0; + for ( int i = 0; i < col; i++ ) + { + colXPos += m_grid->GetColSize(i); + } + + // and add the (modified) text width of the cell contents + // as we'd like to see the last part of the cell contents + colXPos += textWidth; + + int xUnit = 1, yUnit = 1; + m_grid->GetScrollPixelsPerUnit(&xUnit, &yUnit); + m_grid->Scroll(colXPos / xUnit - 1, m_grid->GetScrollPos(wxVERTICAL)); + event.Skip(); + break; + } + + default: + event.Skip(); + break; + } +} + +// ---------------------------------------------------------------------------- +// wxGridCellEditor +// ---------------------------------------------------------------------------- + +wxGridCellEditor::wxGridCellEditor() +{ + m_control = NULL; + m_attr = NULL; +} + +wxGridCellEditor::~wxGridCellEditor() +{ + Destroy(); +} + +void wxGridCellEditor::Create(wxWindow* WXUNUSED(parent), + wxWindowID WXUNUSED(id), + wxEvtHandler* evtHandler) +{ + if ( evtHandler ) + m_control->PushEventHandler(evtHandler); +} + +void wxGridCellEditor::PaintBackground(const wxRect& rectCell, + wxGridCellAttr *attr) +{ + // erase the background because we might not fill the cell + wxClientDC dc(m_control->GetParent()); + wxGridWindow* gridWindow = wxDynamicCast(m_control->GetParent(), wxGridWindow); + if (gridWindow) + gridWindow->GetOwner()->PrepareDC(dc); + + dc.SetPen(*wxTRANSPARENT_PEN); + dc.SetBrush(wxBrush(attr->GetBackgroundColour())); + dc.DrawRectangle(rectCell); + + // redraw the control we just painted over + m_control->Refresh(); +} + +void wxGridCellEditor::Destroy() +{ + if (m_control) + { + m_control->PopEventHandler( true /* delete it*/ ); + + m_control->Destroy(); + m_control = NULL; + } +} + +void wxGridCellEditor::Show(bool show, wxGridCellAttr *attr) +{ + wxASSERT_MSG(m_control, wxT("The wxGridCellEditor must be created first!")); + + m_control->Show(show); + + if ( show ) + { + // set the colours/fonts if we have any + if ( attr ) + { + m_colFgOld = m_control->GetForegroundColour(); + m_control->SetForegroundColour(attr->GetTextColour()); + + m_colBgOld = m_control->GetBackgroundColour(); + m_control->SetBackgroundColour(attr->GetBackgroundColour()); + +// Workaround for GTK+1 font setting problem on some platforms +#if !defined(__WXGTK__) || defined(__WXGTK20__) + m_fontOld = m_control->GetFont(); + m_control->SetFont(attr->GetFont()); +#endif + + // can't do anything more in the base class version, the other + // attributes may only be used by the derived classes + } + } + else + { + // restore the standard colours fonts + if ( m_colFgOld.Ok() ) + { + m_control->SetForegroundColour(m_colFgOld); + m_colFgOld = wxNullColour; + } + + if ( m_colBgOld.Ok() ) + { + m_control->SetBackgroundColour(m_colBgOld); + m_colBgOld = wxNullColour; + } + +// Workaround for GTK+1 font setting problem on some platforms +#if !defined(__WXGTK__) || defined(__WXGTK20__) + if ( m_fontOld.Ok() ) + { + m_control->SetFont(m_fontOld); + m_fontOld = wxNullFont; + } +#endif + } +} + +void wxGridCellEditor::SetSize(const wxRect& rect) +{ + wxASSERT_MSG(m_control, wxT("The wxGridCellEditor must be created first!")); + + m_control->SetSize(rect, wxSIZE_ALLOW_MINUS_ONE); +} + +void wxGridCellEditor::HandleReturn(wxKeyEvent& event) +{ + event.Skip(); +} + +bool wxGridCellEditor::IsAcceptedKey(wxKeyEvent& event) +{ + bool ctrl = event.ControlDown(); + bool alt = event.AltDown(); + +#ifdef __WXMAC__ + // On the Mac the Alt key is more like shift and is used for entry of + // valid characters, so check for Ctrl and Meta instead. + alt = event.MetaDown(); +#endif + + // Assume it's not a valid char if ctrl or alt is down, but if both are + // down then it may be because of an AltGr key combination, so let them + // through in that case. + if ((ctrl || alt) && !(ctrl && alt)) + return false; + +#if wxUSE_UNICODE + // if the unicode key code is not really a unicode character (it may + // be a function key or etc., the platforms appear to always give us a + // small value in this case) then fallback to the ASCII key code but + // don't do anything for function keys or etc. + if ( event.GetUnicodeKey() > 127 && event.GetKeyCode() > 127 ) + return false; +#else + if ( event.GetKeyCode() > 255 ) + return false; +#endif + + return true; +} + +void wxGridCellEditor::StartingKey(wxKeyEvent& event) +{ + event.Skip(); +} + +void wxGridCellEditor::StartingClick() +{ +} + +#if wxUSE_TEXTCTRL + +// ---------------------------------------------------------------------------- +// wxGridCellTextEditor +// ---------------------------------------------------------------------------- + +wxGridCellTextEditor::wxGridCellTextEditor() +{ + m_maxChars = 0; +} + +void wxGridCellTextEditor::Create(wxWindow* parent, + wxWindowID id, + wxEvtHandler* evtHandler) +{ + DoCreate(parent, id, evtHandler); +} + +void wxGridCellTextEditor::DoCreate(wxWindow* parent, + wxWindowID id, + wxEvtHandler* evtHandler, + long style) +{ + style |= wxTE_PROCESS_ENTER | wxTE_PROCESS_TAB | wxNO_BORDER; + + m_control = new wxTextCtrl(parent, id, wxEmptyString, + wxDefaultPosition, wxDefaultSize, + style); + + // set max length allowed in the textctrl, if the parameter was set + if ( m_maxChars != 0 ) + { + Text()->SetMaxLength(m_maxChars); + } + + wxGridCellEditor::Create(parent, id, evtHandler); +} + +void wxGridCellTextEditor::PaintBackground(const wxRect& WXUNUSED(rectCell), + wxGridCellAttr * WXUNUSED(attr)) +{ + // as we fill the entire client area, + // don't do anything here to minimize flicker +} + +void wxGridCellTextEditor::SetSize(const wxRect& rectOrig) +{ + wxRect rect(rectOrig); + + // Make the edit control large enough to allow for internal margins + // + // TODO: remove this if the text ctrl sizing is improved esp. for unix + // +#if defined(__WXGTK__) + if (rect.x != 0) + { + rect.x += 1; + rect.y += 1; + rect.width -= 1; + rect.height -= 1; + } +#elif defined(__WXMSW__) + if ( rect.x == 0 ) + rect.x += 2; + else + rect.x += 3; + + if ( rect.y == 0 ) + rect.y += 2; + else + rect.y += 3; + + rect.width -= 2; + rect.height -= 2; +#else + int extra_x = ( rect.x > 2 ) ? 2 : 1; + int extra_y = ( rect.y > 2 ) ? 2 : 1; + + #if defined(__WXMOTIF__) + extra_x *= 2; + extra_y *= 2; + #endif + + rect.SetLeft( wxMax(0, rect.x - extra_x) ); + rect.SetTop( wxMax(0, rect.y - extra_y) ); + rect.SetRight( rect.GetRight() + 2 * extra_x ); + rect.SetBottom( rect.GetBottom() + 2 * extra_y ); +#endif + + wxGridCellEditor::SetSize(rect); +} + +void wxGridCellTextEditor::BeginEdit(int row, int col, wxGrid* grid) +{ + wxASSERT_MSG(m_control, wxT("The wxGridCellEditor must be created first!")); + + m_value = grid->GetTable()->GetValue(row, col); + + DoBeginEdit(m_value); +} + +void wxGridCellTextEditor::DoBeginEdit(const wxString& startValue) +{ + Text()->SetValue(startValue); + Text()->SetInsertionPointEnd(); + Text()->SetSelection(-1, -1); + Text()->SetFocus(); +} + +bool wxGridCellTextEditor::EndEdit(const wxString& WXUNUSED(oldval), + wxString *newval) +{ + wxCHECK_MSG( m_control, false, + "wxGridCellTextEditor must be created first!" ); + + const wxString value = Text()->GetValue(); + if ( value == m_value ) + return false; + + m_value = value; + + if ( newval ) + *newval = m_value; + + return true; +} + +void wxGridCellTextEditor::ApplyEdit(int row, int col, wxGrid* grid) +{ + grid->GetTable()->SetValue(row, col, m_value); + m_value.clear(); +} + +void wxGridCellTextEditor::Reset() +{ + wxASSERT_MSG( m_control, "wxGridCellTextEditor must be created first!" ); + + DoReset(m_value); +} + +void wxGridCellTextEditor::DoReset(const wxString& startValue) +{ + Text()->SetValue(startValue); + Text()->SetInsertionPointEnd(); +} + +bool wxGridCellTextEditor::IsAcceptedKey(wxKeyEvent& event) +{ + return wxGridCellEditor::IsAcceptedKey(event); +} + +void wxGridCellTextEditor::StartingKey(wxKeyEvent& event) +{ + // Since this is now happening in the EVT_CHAR event EmulateKeyPress is no + // longer an appropriate way to get the character into the text control. + // Do it ourselves instead. We know that if we get this far that we have + // a valid character, so not a whole lot of testing needs to be done. + + wxTextCtrl* tc = Text(); + wxChar ch; + long pos; + +#if wxUSE_UNICODE + ch = event.GetUnicodeKey(); + if (ch <= 127) + ch = (wxChar)event.GetKeyCode(); +#else + ch = (wxChar)event.GetKeyCode(); +#endif + + switch (ch) + { + case WXK_DELETE: + // delete the character at the cursor + pos = tc->GetInsertionPoint(); + if (pos < tc->GetLastPosition()) + tc->Remove(pos, pos + 1); + break; + + case WXK_BACK: + // delete the character before the cursor + pos = tc->GetInsertionPoint(); + if (pos > 0) + tc->Remove(pos - 1, pos); + break; + + default: + tc->WriteText(ch); + break; + } +} + +void wxGridCellTextEditor::HandleReturn( wxKeyEvent& + WXUNUSED_GTK(WXUNUSED_MOTIF(event)) ) +{ +#if defined(__WXMOTIF__) || defined(__WXGTK__) + // wxMotif needs a little extra help... + size_t pos = (size_t)( Text()->GetInsertionPoint() ); + wxString s( Text()->GetValue() ); + s = s.Left(pos) + wxT("\n") + s.Mid(pos); + Text()->SetValue(s); + Text()->SetInsertionPoint( pos ); +#else + // the other ports can handle a Return key press + // + event.Skip(); +#endif +} + +void wxGridCellTextEditor::SetParameters(const wxString& params) +{ + if ( !params ) + { + // reset to default + m_maxChars = 0; + } + else + { + long tmp; + if ( params.ToLong(&tmp) ) + { + m_maxChars = (size_t)tmp; + } + else + { + wxLogDebug( _T("Invalid wxGridCellTextEditor parameter string '%s' ignored"), params.c_str() ); + } + } +} + +// return the value in the text control +wxString wxGridCellTextEditor::GetValue() const +{ + return Text()->GetValue(); +} + +// ---------------------------------------------------------------------------- +// wxGridCellNumberEditor +// ---------------------------------------------------------------------------- + +wxGridCellNumberEditor::wxGridCellNumberEditor(int min, int max) +{ + m_min = min; + m_max = max; +} + +void wxGridCellNumberEditor::Create(wxWindow* parent, + wxWindowID id, + wxEvtHandler* evtHandler) +{ +#if wxUSE_SPINCTRL + if ( HasRange() ) + { + // create a spin ctrl + m_control = new wxSpinCtrl(parent, wxID_ANY, wxEmptyString, + wxDefaultPosition, wxDefaultSize, + wxSP_ARROW_KEYS, + m_min, m_max); + + wxGridCellEditor::Create(parent, id, evtHandler); + } + else +#endif + { + // just a text control + wxGridCellTextEditor::Create(parent, id, evtHandler); + +#if wxUSE_VALIDATORS + Text()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); +#endif + } +} + +void wxGridCellNumberEditor::BeginEdit(int row, int col, wxGrid* grid) +{ + // first get the value + wxGridTableBase *table = grid->GetTable(); + if ( table->CanGetValueAs(row, col, wxGRID_VALUE_NUMBER) ) + { + m_value = table->GetValueAsLong(row, col); + } + else + { + m_value = 0; + wxString sValue = table->GetValue(row, col); + if (! sValue.ToLong(&m_value) && ! sValue.empty()) + { + wxFAIL_MSG( _T("this cell doesn't have numeric value") ); + return; + } + } + +#if wxUSE_SPINCTRL + if ( HasRange() ) + { + Spin()->SetValue((int)m_value); + Spin()->SetFocus(); + } + else +#endif + { + DoBeginEdit(GetString()); + } +} + +bool wxGridCellNumberEditor::EndEdit(const wxString& oldval, wxString *newval) +{ + long value = 0; + wxString text; + +#if wxUSE_SPINCTRL + if ( HasRange() ) + { + value = Spin()->GetValue(); + if ( value == m_value ) + return false; + + text.Printf(wxT("%ld"), value); + } + else // using unconstrained input +#endif // wxUSE_SPINCTRL + { + text = Text()->GetValue(); + if ( text.empty() ) + { + if ( oldval.empty() ) + return false; + } + else // non-empty text now (maybe 0) + { + if ( !text.ToLong(&value) ) + return false; + + // if value == m_value == 0 but old text was "" and new one is + // "0" something still did change + if ( value == m_value && (value || !oldval.empty()) ) + return false; + } + } + + m_value = value; + + if ( newval ) + *newval = text; + + return true; +} + +void wxGridCellNumberEditor::ApplyEdit(int row, int col, wxGrid* grid) +{ + wxGridTableBase * const table = grid->GetTable(); + if ( table->CanSetValueAs(row, col, wxGRID_VALUE_NUMBER) ) + table->SetValueAsLong(row, col, m_value); + else + table->SetValue(row, col, wxString::Format("%ld", m_value)); +} + +void wxGridCellNumberEditor::Reset() +{ +#if wxUSE_SPINCTRL + if ( HasRange() ) + { + Spin()->SetValue((int)m_value); + } + else +#endif + { + DoReset(GetString()); + } +} + +bool wxGridCellNumberEditor::IsAcceptedKey(wxKeyEvent& event) +{ + if ( wxGridCellEditor::IsAcceptedKey(event) ) + { + int keycode = event.GetKeyCode(); + if ( (keycode < 128) && + (wxIsdigit(keycode) || keycode == '+' || keycode == '-')) + { + return true; + } + } + + return false; +} + +void wxGridCellNumberEditor::StartingKey(wxKeyEvent& event) +{ + int keycode = event.GetKeyCode(); + if ( !HasRange() ) + { + if ( wxIsdigit(keycode) || keycode == '+' || keycode == '-') + { + wxGridCellTextEditor::StartingKey(event); + + // skip Skip() below + return; + } + } +#if wxUSE_SPINCTRL + else + { + if ( wxIsdigit(keycode) ) + { + wxSpinCtrl* spin = (wxSpinCtrl*)m_control; + spin->SetValue(keycode - '0'); + spin->SetSelection(1,1); + return; + } + } +#endif + + event.Skip(); +} + +void wxGridCellNumberEditor::SetParameters(const wxString& params) +{ + if ( !params ) + { + // reset to default + m_min = + m_max = -1; + } + else + { + long tmp; + if ( params.BeforeFirst(_T(',')).ToLong(&tmp) ) + { + m_min = (int)tmp; + + if ( params.AfterFirst(_T(',')).ToLong(&tmp) ) + { + m_max = (int)tmp; + + // skip the error message below + return; + } + } + + wxLogDebug(_T("Invalid wxGridCellNumberEditor parameter string '%s' ignored"), params.c_str()); + } +} + +// return the value in the spin control if it is there (the text control otherwise) +wxString wxGridCellNumberEditor::GetValue() const +{ + wxString s; + +#if wxUSE_SPINCTRL + if ( HasRange() ) + { + long value = Spin()->GetValue(); + s.Printf(wxT("%ld"), value); + } + else +#endif + { + s = Text()->GetValue(); + } + + return s; +} + +// ---------------------------------------------------------------------------- +// wxGridCellFloatEditor +// ---------------------------------------------------------------------------- + +wxGridCellFloatEditor::wxGridCellFloatEditor(int width, int precision) +{ + m_width = width; + m_precision = precision; +} + +void wxGridCellFloatEditor::Create(wxWindow* parent, + wxWindowID id, + wxEvtHandler* evtHandler) +{ + wxGridCellTextEditor::Create(parent, id, evtHandler); + +#if wxUSE_VALIDATORS + Text()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); +#endif +} + +void wxGridCellFloatEditor::BeginEdit(int row, int col, wxGrid* grid) +{ + // first get the value + wxGridTableBase * const table = grid->GetTable(); + if ( table->CanGetValueAs(row, col, wxGRID_VALUE_FLOAT) ) + { + m_value = table->GetValueAsDouble(row, col); + } + else + { + m_value = 0.0; + + const wxString value = table->GetValue(row, col); + if ( !value.empty() ) + { + if ( !value.ToDouble(&m_value) ) + { + wxFAIL_MSG( _T("this cell doesn't have float value") ); + return; + } + } + } + + DoBeginEdit(GetString()); +} + +bool wxGridCellFloatEditor::EndEdit(const wxString& oldval, wxString *newval) +{ + const wxString text(Text()->GetValue()); + + double value; + if ( !text.empty() ) + { + if ( !text.ToDouble(&value) ) + return false; + } + else // new value is empty string + { + if ( oldval.empty() ) + return false; // nothing changed + + value = 0.; + } + + // the test for empty strings ensures that we don't skip the value setting + // when "" is replaced by "0" or vice versa as "" numeric value is also 0. + if ( wxIsSameDouble(value, m_value) && !text.empty() && !oldval.empty() ) + return false; // nothing changed + + m_value = value; + + if ( newval ) + *newval = text; + + return true; +} + +void wxGridCellFloatEditor::ApplyEdit(int row, int col, wxGrid* grid) +{ + wxGridTableBase * const table = grid->GetTable(); + + if ( table->CanSetValueAs(row, col, wxGRID_VALUE_FLOAT) ) + table->SetValueAsDouble(row, col, m_value); + else + table->SetValue(row, col, Text()->GetValue()); +} + +void wxGridCellFloatEditor::Reset() +{ + DoReset(GetString()); +} + +void wxGridCellFloatEditor::StartingKey(wxKeyEvent& event) +{ + int keycode = event.GetKeyCode(); + char tmpbuf[2]; + tmpbuf[0] = (char) keycode; + tmpbuf[1] = '\0'; + wxString strbuf(tmpbuf, *wxConvCurrent); + +#if wxUSE_INTL + bool is_decimal_point = ( strbuf == + wxLocale::GetInfo(wxLOCALE_DECIMAL_POINT, wxLOCALE_CAT_NUMBER) ); +#else + bool is_decimal_point = ( strbuf == _T(".") ); +#endif + + if ( wxIsdigit(keycode) || keycode == '+' || keycode == '-' + || is_decimal_point ) + { + wxGridCellTextEditor::StartingKey(event); + + // skip Skip() below + return; + } + + event.Skip(); +} + +void wxGridCellFloatEditor::SetParameters(const wxString& params) +{ + if ( !params ) + { + // reset to default + m_width = + m_precision = -1; + } + else + { + long tmp; + if ( params.BeforeFirst(_T(',')).ToLong(&tmp) ) + { + m_width = (int)tmp; + + if ( params.AfterFirst(_T(',')).ToLong(&tmp) ) + { + m_precision = (int)tmp; + + // skip the error message below + return; + } + } + + wxLogDebug(_T("Invalid wxGridCellFloatEditor parameter string '%s' ignored"), params.c_str()); + } +} + +wxString wxGridCellFloatEditor::GetString() const +{ + wxString fmt; + if ( m_precision == -1 && m_width != -1) + { + // default precision + fmt.Printf(_T("%%%d.f"), m_width); + } + else if ( m_precision != -1 && m_width == -1) + { + // default width + fmt.Printf(_T("%%.%df"), m_precision); + } + else if ( m_precision != -1 && m_width != -1 ) + { + fmt.Printf(_T("%%%d.%df"), m_width, m_precision); + } + else + { + // default width/precision + fmt = _T("%f"); + } + + return wxString::Format(fmt, m_value); +} + +bool wxGridCellFloatEditor::IsAcceptedKey(wxKeyEvent& event) +{ + if ( wxGridCellEditor::IsAcceptedKey(event) ) + { + const int keycode = event.GetKeyCode(); + if ( isascii(keycode) ) + { + char tmpbuf[2]; + tmpbuf[0] = (char) keycode; + tmpbuf[1] = '\0'; + wxString strbuf(tmpbuf, *wxConvCurrent); + +#if wxUSE_INTL + const wxString decimalPoint = + wxLocale::GetInfo(wxLOCALE_DECIMAL_POINT, wxLOCALE_CAT_NUMBER); +#else + const wxString decimalPoint(_T('.')); +#endif + + // accept digits, 'e' as in '1e+6', also '-', '+', and '.' + if ( wxIsdigit(keycode) || + tolower(keycode) == 'e' || + keycode == decimalPoint || + keycode == '+' || + keycode == '-' ) + { + return true; + } + } + } + + return false; +} + +#endif // wxUSE_TEXTCTRL + +#if wxUSE_CHECKBOX + +// ---------------------------------------------------------------------------- +// wxGridCellBoolEditor +// ---------------------------------------------------------------------------- + +// the default values for GetValue() +wxString wxGridCellBoolEditor::ms_stringValues[2] = { _T(""), _T("1") }; + +void wxGridCellBoolEditor::Create(wxWindow* parent, + wxWindowID id, + wxEvtHandler* evtHandler) +{ + m_control = new wxCheckBox(parent, id, wxEmptyString, + wxDefaultPosition, wxDefaultSize, + wxNO_BORDER); + + wxGridCellEditor::Create(parent, id, evtHandler); +} + +void wxGridCellBoolEditor::SetSize(const wxRect& r) +{ + bool resize = false; + wxSize size = m_control->GetSize(); + wxCoord minSize = wxMin(r.width, r.height); + + // check if the checkbox is not too big/small for this cell + wxSize sizeBest = m_control->GetBestSize(); + if ( !(size == sizeBest) ) + { + // reset to default size if it had been made smaller + size = sizeBest; + + resize = true; + } + + if ( size.x >= minSize || size.y >= minSize ) + { + // leave 1 pixel margin + size.x = size.y = minSize - 2; + + resize = true; + } + + if ( resize ) + { + m_control->SetSize(size); + } + + // position it in the centre of the rectangle (TODO: support alignment?) + +#if defined(__WXGTK__) || defined (__WXMOTIF__) + // the checkbox without label still has some space to the right in wxGTK, + // so shift it to the right + size.x -= 8; +#elif defined(__WXMSW__) + // here too, but in other way + size.x += 1; + size.y -= 2; +#endif + + int hAlign = wxALIGN_CENTRE; + int vAlign = wxALIGN_CENTRE; + if (GetCellAttr()) + GetCellAttr()->GetAlignment(& hAlign, & vAlign); + + int x = 0, y = 0; + if (hAlign == wxALIGN_LEFT) + { + x = r.x + 2; + +#ifdef __WXMSW__ + x += 2; +#endif + + y = r.y + r.height / 2 - size.y / 2; + } + else if (hAlign == wxALIGN_RIGHT) + { + x = r.x + r.width - size.x - 2; + y = r.y + r.height / 2 - size.y / 2; + } + else if (hAlign == wxALIGN_CENTRE) + { + x = r.x + r.width / 2 - size.x / 2; + y = r.y + r.height / 2 - size.y / 2; + } + + m_control->Move(x, y); +} + +void wxGridCellBoolEditor::Show(bool show, wxGridCellAttr *attr) +{ + m_control->Show(show); + + if ( show ) + { + wxColour colBg = attr ? attr->GetBackgroundColour() : *wxLIGHT_GREY; + CBox()->SetBackgroundColour(colBg); + } +} + +void wxGridCellBoolEditor::BeginEdit(int row, int col, wxGrid* grid) +{ + wxASSERT_MSG(m_control, + wxT("The wxGridCellEditor must be created first!")); + + if (grid->GetTable()->CanGetValueAs(row, col, wxGRID_VALUE_BOOL)) + { + m_value = grid->GetTable()->GetValueAsBool(row, col); + } + else + { + wxString cellval( grid->GetTable()->GetValue(row, col) ); + + if ( cellval == ms_stringValues[false] ) + m_value = false; + else if ( cellval == ms_stringValues[true] ) + m_value = true; + else + { + // do not try to be smart here and convert it to true or false + // because we'll still overwrite it with something different and + // this risks to be very surprising for the user code, let them + // know about it + wxFAIL_MSG( _T("invalid value for a cell with bool editor!") ); + } + } + + CBox()->SetValue(m_value); + CBox()->SetFocus(); +} + +bool wxGridCellBoolEditor::EndEdit(const wxString& WXUNUSED(oldval), + wxString *newval) +{ + bool value = CBox()->GetValue(); + if ( value == m_value ) + return false; + + m_value = value; + + if ( newval ) + *newval = GetValue(); + + return true; +} + +void wxGridCellBoolEditor::ApplyEdit(int row, int col, wxGrid* grid) +{ + wxGridTableBase * const table = grid->GetTable(); + if ( table->CanSetValueAs(row, col, wxGRID_VALUE_BOOL) ) + table->SetValueAsBool(row, col, m_value); + else + table->SetValue(row, col, GetValue()); +} + +void wxGridCellBoolEditor::Reset() +{ + wxASSERT_MSG(m_control, + wxT("The wxGridCellEditor must be created first!")); + + CBox()->SetValue(m_value); +} + +void wxGridCellBoolEditor::StartingClick() +{ + CBox()->SetValue(!CBox()->GetValue()); +} + +bool wxGridCellBoolEditor::IsAcceptedKey(wxKeyEvent& event) +{ + if ( wxGridCellEditor::IsAcceptedKey(event) ) + { + int keycode = event.GetKeyCode(); + switch ( keycode ) + { + case WXK_SPACE: + case '+': + case '-': + return true; + } + } + + return false; +} + +void wxGridCellBoolEditor::StartingKey(wxKeyEvent& event) +{ + int keycode = event.GetKeyCode(); + switch ( keycode ) + { + case WXK_SPACE: + CBox()->SetValue(!CBox()->GetValue()); + break; + + case '+': + CBox()->SetValue(true); + break; + + case '-': + CBox()->SetValue(false); + break; + } +} + +wxString wxGridCellBoolEditor::GetValue() const +{ + return ms_stringValues[CBox()->GetValue()]; +} + +/* static */ void +wxGridCellBoolEditor::UseStringValues(const wxString& valueTrue, + const wxString& valueFalse) +{ + ms_stringValues[false] = valueFalse; + ms_stringValues[true] = valueTrue; +} + +/* static */ bool +wxGridCellBoolEditor::IsTrueValue(const wxString& value) +{ + return value == ms_stringValues[true]; +} + +#endif // wxUSE_CHECKBOX + +#if wxUSE_COMBOBOX + +// ---------------------------------------------------------------------------- +// wxGridCellChoiceEditor +// ---------------------------------------------------------------------------- + +wxGridCellChoiceEditor::wxGridCellChoiceEditor(const wxArrayString& choices, + bool allowOthers) + : m_choices(choices), + m_allowOthers(allowOthers) { } + +wxGridCellChoiceEditor::wxGridCellChoiceEditor(size_t count, + const wxString choices[], + bool allowOthers) + : m_allowOthers(allowOthers) +{ + if ( count ) + { + m_choices.Alloc(count); + for ( size_t n = 0; n < count; n++ ) + { + m_choices.Add(choices[n]); + } + } +} + +wxGridCellEditor *wxGridCellChoiceEditor::Clone() const +{ + wxGridCellChoiceEditor *editor = new wxGridCellChoiceEditor; + editor->m_allowOthers = m_allowOthers; + editor->m_choices = m_choices; + + return editor; +} + +void wxGridCellChoiceEditor::Create(wxWindow* parent, + wxWindowID id, + wxEvtHandler* evtHandler) +{ + int style = wxTE_PROCESS_ENTER | + wxTE_PROCESS_TAB | + wxBORDER_NONE; + + if ( !m_allowOthers ) + style |= wxCB_READONLY; + m_control = new wxComboBox(parent, id, wxEmptyString, + wxDefaultPosition, wxDefaultSize, + m_choices, + style); + + wxGridCellEditor::Create(parent, id, evtHandler); +} + +void wxGridCellChoiceEditor::PaintBackground(const wxRect& rectCell, + wxGridCellAttr * attr) +{ + // as we fill the entire client area, don't do anything here to minimize + // flicker + + // TODO: It doesn't actually fill the client area since the height of a + // combo always defaults to the standard. Until someone has time to + // figure out the right rectangle to paint, just do it the normal way. + wxGridCellEditor::PaintBackground(rectCell, attr); +} + +void wxGridCellChoiceEditor::BeginEdit(int row, int col, wxGrid* grid) +{ + wxASSERT_MSG(m_control, + wxT("The wxGridCellEditor must be created first!")); + + wxGridCellEditorEvtHandler* evtHandler = NULL; + if (m_control) + evtHandler = wxDynamicCast(m_control->GetEventHandler(), wxGridCellEditorEvtHandler); + + // Don't immediately end if we get a kill focus event within BeginEdit + if (evtHandler) + evtHandler->SetInSetFocus(true); + + m_value = grid->GetTable()->GetValue(row, col); + + Reset(); // this updates combo box to correspond to m_value + + Combo()->SetFocus(); + + if (evtHandler) + { + // When dropping down the menu, a kill focus event + // happens after this point, so we can't reset the flag yet. +#if !defined(__WXGTK20__) + evtHandler->SetInSetFocus(false); +#endif + } +} + +bool wxGridCellChoiceEditor::EndEdit(const wxString& WXUNUSED(oldval), + wxString *newval) +{ + const wxString value = Combo()->GetValue(); + if ( value == m_value ) + return false; + + m_value = value; + + if ( newval ) + *newval = value; + + return true; +} + +void wxGridCellChoiceEditor::ApplyEdit(int row, int col, wxGrid* grid) +{ + grid->GetTable()->SetValue(row, col, m_value); +} + +void wxGridCellChoiceEditor::Reset() +{ + if (m_allowOthers) + { + Combo()->SetValue(m_value); + Combo()->SetInsertionPointEnd(); + } + else // the combobox is read-only + { + // find the right position, or default to the first if not found + int pos = Combo()->FindString(m_value); + if (pos == wxNOT_FOUND) + pos = 0; + Combo()->SetSelection(pos); + } +} + +void wxGridCellChoiceEditor::SetParameters(const wxString& params) +{ + if ( !params ) + { + // what can we do? + return; + } + + m_choices.Empty(); + + wxStringTokenizer tk(params, _T(',')); + while ( tk.HasMoreTokens() ) + { + m_choices.Add(tk.GetNextToken()); + } +} + +// return the value in the text control +wxString wxGridCellChoiceEditor::GetValue() const +{ + return Combo()->GetValue(); +} + +#endif // wxUSE_COMBOBOX + +#if wxUSE_COMBOBOX + +// ---------------------------------------------------------------------------- +// wxGridCellEnumEditor +// ---------------------------------------------------------------------------- + +// A cell editor which displays an enum number as a textual equivalent. eg +// data in cell is 0,1,2 ... n the cell could be displayed as +// "John","Fred"..."Bob" in the combo choice box + +wxGridCellEnumEditor::wxGridCellEnumEditor(const wxString& choices) + :wxGridCellChoiceEditor() +{ + m_index = -1; + + if (!choices.empty()) + SetParameters(choices); +} + +wxGridCellEditor *wxGridCellEnumEditor::Clone() const +{ + wxGridCellEnumEditor *editor = new wxGridCellEnumEditor(); + editor->m_index = m_index; + return editor; +} + +void wxGridCellEnumEditor::BeginEdit(int row, int col, wxGrid* grid) +{ + wxASSERT_MSG(m_control, + wxT("The wxGridCellEnumEditor must be Created first!")); + + wxGridTableBase *table = grid->GetTable(); + + if ( table->CanGetValueAs(row, col, wxGRID_VALUE_NUMBER) ) + { + m_index = table->GetValueAsLong(row, col); + } + else + { + wxString startValue = table->GetValue(row, col); + if (startValue.IsNumber() && !startValue.empty()) + { + startValue.ToLong(&m_index); + } + else + { + m_index = -1; + } + } + + Combo()->SetSelection(m_index); + Combo()->SetInsertionPointEnd(); + Combo()->SetFocus(); + +} + +bool wxGridCellEnumEditor::EndEdit(const wxString& WXUNUSED(oldval), + wxString *newval) +{ + long idx = Combo()->GetSelection(); + if ( idx == m_index ) + return false; + + m_index = idx; + + if ( newval ) + newval->Printf("%ld", m_index); + + return true; +} + +void wxGridCellEnumEditor::ApplyEdit(int row, int col, wxGrid* grid) +{ + wxGridTableBase * const table = grid->GetTable(); + if ( table->CanSetValueAs(row, col, wxGRID_VALUE_NUMBER) ) + table->SetValueAsLong(row, col, m_index); + else + table->SetValue(row, col, wxString::Format("%ld", m_index)); +} + +#endif // wxUSE_COMBOBOX + +// ---------------------------------------------------------------------------- +// wxGridCellAutoWrapStringEditor +// ---------------------------------------------------------------------------- + +void +wxGridCellAutoWrapStringEditor::Create(wxWindow* parent, + wxWindowID id, + wxEvtHandler* evtHandler) +{ + wxGridCellTextEditor::DoCreate(parent, id, evtHandler, + wxTE_MULTILINE | wxTE_RICH); +} + + +#endif // wxUSE_GRID -- 2.45.2