From 39bc0347fda3505f7fb43447f21efd84b9e00b3c Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 1 Apr 2007 14:13:15 +0000 Subject: [PATCH] added support for ellipsization and markup in wxStaticText (modified patch 1629946) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@45199 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- Makefile.in | 20 ++ build/bakefiles/files.bkl | 1 + build/msw/makefile.bcc | 28 ++ build/msw/makefile.gcc | 28 ++ build/msw/makefile.vc | 28 ++ build/msw/makefile.wat | 28 ++ build/msw/wx_core.dsp | 4 + docs/changes.txt | 1 + docs/latex/wx/stattext.tex | 86 +++++- include/wx/control.h | 33 ++- include/wx/defs.h | 7 - include/wx/gtk/control.h | 12 +- include/wx/gtk/stattext.h | 8 +- include/wx/mac/carbon/stattext.h | 3 + include/wx/motif/stattext.h | 3 + include/wx/msw/stattext.h | 3 + include/wx/os2/stattext.h | 3 + include/wx/private/stattext.h | 95 ++++++ include/wx/stattext.h | 63 +++- include/wx/univ/control.h | 13 +- include/wx/univ/stattext.h | 3 + samples/widgets/static.cpp | 140 ++++++++- src/common/ctrlcmn.cpp | 13 +- src/common/dlgcmn.cpp | 146 +--------- src/common/stattextcmn.cpp | 480 +++++++++++++++++++++++++++++++ src/gtk/checkbox.cpp | 3 + src/gtk/control.cpp | 89 ++++-- src/gtk/stattext.cpp | 78 ++++- src/mac/carbon/stattext.cpp | 59 +++- src/motif/stattext.cpp | 30 +- src/msw/control.cpp | 4 + src/msw/stattext.cpp | 74 ++++- src/os2/stattext.cpp | 37 ++- src/univ/control.cpp | 13 +- src/univ/stattext.cpp | 29 +- 35 files changed, 1386 insertions(+), 279 deletions(-) create mode 100644 include/wx/private/stattext.h create mode 100644 src/common/stattextcmn.cpp diff --git a/Makefile.in b/Makefile.in index a11a61603f..b7d95d7eb6 100644 --- a/Makefile.in +++ b/Makefile.in @@ -3549,6 +3549,7 @@ COND_USE_GUI_1_WXUNIV_0___CORE_SRC_OBJECTS = \ monodll_sizer.o \ monodll_srchcmn.o \ monodll_statbar.o \ + monodll_stattextcmn.o \ monodll_stockitem.o \ monodll_tbarbase.o \ monodll_textcmn.o \ @@ -3725,6 +3726,7 @@ COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS = \ monodll_sizer.o \ monodll_srchcmn.o \ monodll_statbar.o \ + monodll_stattextcmn.o \ monodll_stockitem.o \ monodll_tbarbase.o \ monodll_textcmn.o \ @@ -5342,6 +5344,7 @@ COND_USE_GUI_1_WXUNIV_0___CORE_SRC_OBJECTS_1 = \ monolib_sizer.o \ monolib_srchcmn.o \ monolib_statbar.o \ + monolib_stattextcmn.o \ monolib_stockitem.o \ monolib_tbarbase.o \ monolib_textcmn.o \ @@ -5518,6 +5521,7 @@ COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS_1 = \ monolib_sizer.o \ monolib_srchcmn.o \ monolib_statbar.o \ + monolib_stattextcmn.o \ monolib_stockitem.o \ monolib_tbarbase.o \ monolib_textcmn.o \ @@ -7369,6 +7373,7 @@ COND_USE_GUI_1_WXUNIV_0___CORE_SRC_OBJECTS_2 = \ coredll_sizer.o \ coredll_srchcmn.o \ coredll_statbar.o \ + coredll_stattextcmn.o \ coredll_stockitem.o \ coredll_tbarbase.o \ coredll_textcmn.o \ @@ -7545,6 +7550,7 @@ COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS_2 = \ coredll_sizer.o \ coredll_srchcmn.o \ coredll_statbar.o \ + coredll_stattextcmn.o \ coredll_stockitem.o \ coredll_tbarbase.o \ coredll_textcmn.o \ @@ -8834,6 +8840,7 @@ COND_USE_GUI_1_WXUNIV_0___CORE_SRC_OBJECTS_3 = \ corelib_sizer.o \ corelib_srchcmn.o \ corelib_statbar.o \ + corelib_stattextcmn.o \ corelib_stockitem.o \ corelib_tbarbase.o \ corelib_textcmn.o \ @@ -9010,6 +9017,7 @@ COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS_3 = \ corelib_sizer.o \ corelib_srchcmn.o \ corelib_statbar.o \ + corelib_stattextcmn.o \ corelib_stockitem.o \ corelib_tbarbase.o \ corelib_textcmn.o \ @@ -16465,6 +16473,9 @@ monodll_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(MONODLL_ODEP) @COND_USE_GUI_1@monodll_statbar.o: $(srcdir)/src/common/statbar.cpp $(MONODLL_ODEP) @COND_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/common/statbar.cpp +@COND_USE_GUI_1@monodll_stattextcmn.o: $(srcdir)/src/common/stattextcmn.cpp $(MONODLL_ODEP) +@COND_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/common/stattextcmn.cpp + @COND_USE_GUI_1@monodll_stockitem.o: $(srcdir)/src/common/stockitem.cpp $(MONODLL_ODEP) @COND_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/common/stockitem.cpp @@ -20620,6 +20631,9 @@ monolib_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(MONOLIB_ODEP) @COND_USE_GUI_1@monolib_statbar.o: $(srcdir)/src/common/statbar.cpp $(MONOLIB_ODEP) @COND_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/common/statbar.cpp +@COND_USE_GUI_1@monolib_stattextcmn.o: $(srcdir)/src/common/stattextcmn.cpp $(MONOLIB_ODEP) +@COND_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/common/stattextcmn.cpp + @COND_USE_GUI_1@monolib_stockitem.o: $(srcdir)/src/common/stockitem.cpp $(MONOLIB_ODEP) @COND_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/common/stockitem.cpp @@ -25135,6 +25149,9 @@ coredll_win32.o: $(srcdir)/src/univ/themes/win32.cpp $(COREDLL_ODEP) @COND_USE_GUI_1@coredll_statbar.o: $(srcdir)/src/common/statbar.cpp $(COREDLL_ODEP) @COND_USE_GUI_1@ $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/common/statbar.cpp +@COND_USE_GUI_1@coredll_stattextcmn.o: $(srcdir)/src/common/stattextcmn.cpp $(COREDLL_ODEP) +@COND_USE_GUI_1@ $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/common/stattextcmn.cpp + @COND_USE_GUI_1@coredll_stockitem.o: $(srcdir)/src/common/stockitem.cpp $(COREDLL_ODEP) @COND_USE_GUI_1@ $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/common/stockitem.cpp @@ -28105,6 +28122,9 @@ corelib_win32.o: $(srcdir)/src/univ/themes/win32.cpp $(CORELIB_ODEP) @COND_USE_GUI_1@corelib_statbar.o: $(srcdir)/src/common/statbar.cpp $(CORELIB_ODEP) @COND_USE_GUI_1@ $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/common/statbar.cpp +@COND_USE_GUI_1@corelib_stattextcmn.o: $(srcdir)/src/common/stattextcmn.cpp $(CORELIB_ODEP) +@COND_USE_GUI_1@ $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/common/stattextcmn.cpp + @COND_USE_GUI_1@corelib_stockitem.o: $(srcdir)/src/common/stockitem.cpp $(CORELIB_ODEP) @COND_USE_GUI_1@ $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/common/stockitem.cpp diff --git a/build/bakefiles/files.bkl b/build/bakefiles/files.bkl index 01f7341cb9..6eed1fa755 100644 --- a/build/bakefiles/files.bkl +++ b/build/bakefiles/files.bkl @@ -651,6 +651,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! src/common/sizer.cpp src/common/srchcmn.cpp src/common/statbar.cpp + src/common/stattextcmn.cpp src/common/stockitem.cpp src/common/tbarbase.cpp src/common/textcmn.cpp diff --git a/build/msw/makefile.bcc b/build/msw/makefile.bcc index dc001d7807..7285e34058 100644 --- a/build/msw/makefile.bcc +++ b/build/msw/makefile.bcc @@ -1515,6 +1515,7 @@ ____CORE_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_sizer.obj \ $(OBJS)\monodll_srchcmn.obj \ $(OBJS)\monodll_statbar.obj \ + $(OBJS)\monodll_stattextcmn.obj \ $(OBJS)\monodll_stockitem.obj \ $(OBJS)\monodll_tbarbase.obj \ $(OBJS)\monodll_textcmn.obj \ @@ -1742,6 +1743,7 @@ ____CORE_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_sizer.obj \ $(OBJS)\monodll_srchcmn.obj \ $(OBJS)\monodll_statbar.obj \ + $(OBJS)\monodll_stattextcmn.obj \ $(OBJS)\monodll_stockitem.obj \ $(OBJS)\monodll_tbarbase.obj \ $(OBJS)\monodll_textcmn.obj \ @@ -2137,6 +2139,7 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_sizer.obj \ $(OBJS)\monolib_srchcmn.obj \ $(OBJS)\monolib_statbar.obj \ + $(OBJS)\monolib_stattextcmn.obj \ $(OBJS)\monolib_stockitem.obj \ $(OBJS)\monolib_tbarbase.obj \ $(OBJS)\monolib_textcmn.obj \ @@ -2364,6 +2367,7 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_sizer.obj \ $(OBJS)\monolib_srchcmn.obj \ $(OBJS)\monolib_statbar.obj \ + $(OBJS)\monolib_stattextcmn.obj \ $(OBJS)\monolib_stockitem.obj \ $(OBJS)\monolib_tbarbase.obj \ $(OBJS)\monolib_textcmn.obj \ @@ -2679,6 +2683,7 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\coredll_sizer.obj \ $(OBJS)\coredll_srchcmn.obj \ $(OBJS)\coredll_statbar.obj \ + $(OBJS)\coredll_stattextcmn.obj \ $(OBJS)\coredll_stockitem.obj \ $(OBJS)\coredll_tbarbase.obj \ $(OBJS)\coredll_textcmn.obj \ @@ -2906,6 +2911,7 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\coredll_sizer.obj \ $(OBJS)\coredll_srchcmn.obj \ $(OBJS)\coredll_statbar.obj \ + $(OBJS)\coredll_stattextcmn.obj \ $(OBJS)\coredll_stockitem.obj \ $(OBJS)\coredll_tbarbase.obj \ $(OBJS)\coredll_textcmn.obj \ @@ -3134,6 +3140,7 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\corelib_sizer.obj \ $(OBJS)\corelib_srchcmn.obj \ $(OBJS)\corelib_statbar.obj \ + $(OBJS)\corelib_stattextcmn.obj \ $(OBJS)\corelib_stockitem.obj \ $(OBJS)\corelib_tbarbase.obj \ $(OBJS)\corelib_textcmn.obj \ @@ -3361,6 +3368,7 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\corelib_sizer.obj \ $(OBJS)\corelib_srchcmn.obj \ $(OBJS)\corelib_statbar.obj \ + $(OBJS)\corelib_stattextcmn.obj \ $(OBJS)\corelib_stockitem.obj \ $(OBJS)\corelib_tbarbase.obj \ $(OBJS)\corelib_textcmn.obj \ @@ -6384,6 +6392,11 @@ $(OBJS)\monodll_statbar.obj: ..\..\src\common\statbar.cpp $(CXX) -q -c -P -o$@ $(MONODLL_CXXFLAGS) $** !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\monodll_stattextcmn.obj: ..\..\src\common\stattextcmn.cpp + $(CXX) -q -c -P -o$@ $(MONODLL_CXXFLAGS) $** +!endif + !if "$(USE_GUI)" == "1" $(OBJS)\monodll_stockitem.obj: ..\..\src\common\stockitem.cpp $(CXX) -q -c -P -o$@ $(MONODLL_CXXFLAGS) $** @@ -8411,6 +8424,11 @@ $(OBJS)\monolib_statbar.obj: ..\..\src\common\statbar.cpp $(CXX) -q -c -P -o$@ $(MONOLIB_CXXFLAGS) $** !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\monolib_stattextcmn.obj: ..\..\src\common\stattextcmn.cpp + $(CXX) -q -c -P -o$@ $(MONOLIB_CXXFLAGS) $** +!endif + !if "$(USE_GUI)" == "1" $(OBJS)\monolib_stockitem.obj: ..\..\src\common\stockitem.cpp $(CXX) -q -c -P -o$@ $(MONOLIB_CXXFLAGS) $** @@ -10477,6 +10495,11 @@ $(OBJS)\coredll_statbar.obj: ..\..\src\common\statbar.cpp $(CXX) -q -c -P -o$@ $(COREDLL_CXXFLAGS) $** !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\coredll_stattextcmn.obj: ..\..\src\common\stattextcmn.cpp + $(CXX) -q -c -P -o$@ $(COREDLL_CXXFLAGS) $** +!endif + !if "$(USE_GUI)" == "1" $(OBJS)\coredll_stockitem.obj: ..\..\src\common\stockitem.cpp $(CXX) -q -c -P -o$@ $(COREDLL_CXXFLAGS) $** @@ -11762,6 +11785,11 @@ $(OBJS)\corelib_statbar.obj: ..\..\src\common\statbar.cpp $(CXX) -q -c -P -o$@ $(CORELIB_CXXFLAGS) $** !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\corelib_stattextcmn.obj: ..\..\src\common\stattextcmn.cpp + $(CXX) -q -c -P -o$@ $(CORELIB_CXXFLAGS) $** +!endif + !if "$(USE_GUI)" == "1" $(OBJS)\corelib_stockitem.obj: ..\..\src\common\stockitem.cpp $(CXX) -q -c -P -o$@ $(CORELIB_CXXFLAGS) $** diff --git a/build/msw/makefile.gcc b/build/msw/makefile.gcc index b5d09554d5..7f22f62a94 100644 --- a/build/msw/makefile.gcc +++ b/build/msw/makefile.gcc @@ -1525,6 +1525,7 @@ ____CORE_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_sizer.o \ $(OBJS)\monodll_srchcmn.o \ $(OBJS)\monodll_statbar.o \ + $(OBJS)\monodll_stattextcmn.o \ $(OBJS)\monodll_stockitem.o \ $(OBJS)\monodll_tbarbase.o \ $(OBJS)\monodll_textcmn.o \ @@ -1754,6 +1755,7 @@ ____CORE_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_sizer.o \ $(OBJS)\monodll_srchcmn.o \ $(OBJS)\monodll_statbar.o \ + $(OBJS)\monodll_stattextcmn.o \ $(OBJS)\monodll_stockitem.o \ $(OBJS)\monodll_tbarbase.o \ $(OBJS)\monodll_textcmn.o \ @@ -2153,6 +2155,7 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_sizer.o \ $(OBJS)\monolib_srchcmn.o \ $(OBJS)\monolib_statbar.o \ + $(OBJS)\monolib_stattextcmn.o \ $(OBJS)\monolib_stockitem.o \ $(OBJS)\monolib_tbarbase.o \ $(OBJS)\monolib_textcmn.o \ @@ -2382,6 +2385,7 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_sizer.o \ $(OBJS)\monolib_srchcmn.o \ $(OBJS)\monolib_statbar.o \ + $(OBJS)\monolib_stattextcmn.o \ $(OBJS)\monolib_stockitem.o \ $(OBJS)\monolib_tbarbase.o \ $(OBJS)\monolib_textcmn.o \ @@ -2711,6 +2715,7 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\coredll_sizer.o \ $(OBJS)\coredll_srchcmn.o \ $(OBJS)\coredll_statbar.o \ + $(OBJS)\coredll_stattextcmn.o \ $(OBJS)\coredll_stockitem.o \ $(OBJS)\coredll_tbarbase.o \ $(OBJS)\coredll_textcmn.o \ @@ -2940,6 +2945,7 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\coredll_sizer.o \ $(OBJS)\coredll_srchcmn.o \ $(OBJS)\coredll_statbar.o \ + $(OBJS)\coredll_stattextcmn.o \ $(OBJS)\coredll_stockitem.o \ $(OBJS)\coredll_tbarbase.o \ $(OBJS)\coredll_textcmn.o \ @@ -3174,6 +3180,7 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\corelib_sizer.o \ $(OBJS)\corelib_srchcmn.o \ $(OBJS)\corelib_statbar.o \ + $(OBJS)\corelib_stattextcmn.o \ $(OBJS)\corelib_stockitem.o \ $(OBJS)\corelib_tbarbase.o \ $(OBJS)\corelib_textcmn.o \ @@ -3403,6 +3410,7 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\corelib_sizer.o \ $(OBJS)\corelib_srchcmn.o \ $(OBJS)\corelib_statbar.o \ + $(OBJS)\corelib_stattextcmn.o \ $(OBJS)\corelib_stockitem.o \ $(OBJS)\corelib_tbarbase.o \ $(OBJS)\corelib_textcmn.o \ @@ -6635,6 +6643,11 @@ $(OBJS)\monodll_statbar.o: ../../src/common/statbar.cpp $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $< endif +ifeq ($(USE_GUI),1) +$(OBJS)\monodll_stattextcmn.o: ../../src/common/stattextcmn.cpp + $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $< +endif + ifeq ($(USE_GUI),1) $(OBJS)\monodll_stockitem.o: ../../src/common/stockitem.cpp $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $< @@ -8762,6 +8775,11 @@ $(OBJS)\monolib_statbar.o: ../../src/common/statbar.cpp $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< endif +ifeq ($(USE_GUI),1) +$(OBJS)\monolib_stattextcmn.o: ../../src/common/stattextcmn.cpp + $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< +endif + ifeq ($(USE_GUI),1) $(OBJS)\monolib_stockitem.o: ../../src/common/stockitem.cpp $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< @@ -10928,6 +10946,11 @@ $(OBJS)\coredll_statbar.o: ../../src/common/statbar.cpp $(CXX) -c -o $@ $(COREDLL_CXXFLAGS) $(CPPDEPS) $< endif +ifeq ($(USE_GUI),1) +$(OBJS)\coredll_stattextcmn.o: ../../src/common/stattextcmn.cpp + $(CXX) -c -o $@ $(COREDLL_CXXFLAGS) $(CPPDEPS) $< +endif + ifeq ($(USE_GUI),1) $(OBJS)\coredll_stockitem.o: ../../src/common/stockitem.cpp $(CXX) -c -o $@ $(COREDLL_CXXFLAGS) $(CPPDEPS) $< @@ -12313,6 +12336,11 @@ $(OBJS)\corelib_statbar.o: ../../src/common/statbar.cpp $(CXX) -c -o $@ $(CORELIB_CXXFLAGS) $(CPPDEPS) $< endif +ifeq ($(USE_GUI),1) +$(OBJS)\corelib_stattextcmn.o: ../../src/common/stattextcmn.cpp + $(CXX) -c -o $@ $(CORELIB_CXXFLAGS) $(CPPDEPS) $< +endif + ifeq ($(USE_GUI),1) $(OBJS)\corelib_stockitem.o: ../../src/common/stockitem.cpp $(CXX) -c -o $@ $(CORELIB_CXXFLAGS) $(CPPDEPS) $< diff --git a/build/msw/makefile.vc b/build/msw/makefile.vc index df9223ad65..34af86a395 100644 --- a/build/msw/makefile.vc +++ b/build/msw/makefile.vc @@ -1682,6 +1682,7 @@ ____CORE_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_sizer.obj \ $(OBJS)\monodll_srchcmn.obj \ $(OBJS)\monodll_statbar.obj \ + $(OBJS)\monodll_stattextcmn.obj \ $(OBJS)\monodll_stockitem.obj \ $(OBJS)\monodll_tbarbase.obj \ $(OBJS)\monodll_textcmn.obj \ @@ -1909,6 +1910,7 @@ ____CORE_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_sizer.obj \ $(OBJS)\monodll_srchcmn.obj \ $(OBJS)\monodll_statbar.obj \ + $(OBJS)\monodll_stattextcmn.obj \ $(OBJS)\monodll_stockitem.obj \ $(OBJS)\monodll_tbarbase.obj \ $(OBJS)\monodll_textcmn.obj \ @@ -2310,6 +2312,7 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_sizer.obj \ $(OBJS)\monolib_srchcmn.obj \ $(OBJS)\monolib_statbar.obj \ + $(OBJS)\monolib_stattextcmn.obj \ $(OBJS)\monolib_stockitem.obj \ $(OBJS)\monolib_tbarbase.obj \ $(OBJS)\monolib_textcmn.obj \ @@ -2537,6 +2540,7 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_sizer.obj \ $(OBJS)\monolib_srchcmn.obj \ $(OBJS)\monolib_statbar.obj \ + $(OBJS)\monolib_stattextcmn.obj \ $(OBJS)\monolib_stockitem.obj \ $(OBJS)\monolib_tbarbase.obj \ $(OBJS)\monolib_textcmn.obj \ @@ -2882,6 +2886,7 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\coredll_sizer.obj \ $(OBJS)\coredll_srchcmn.obj \ $(OBJS)\coredll_statbar.obj \ + $(OBJS)\coredll_stattextcmn.obj \ $(OBJS)\coredll_stockitem.obj \ $(OBJS)\coredll_tbarbase.obj \ $(OBJS)\coredll_textcmn.obj \ @@ -3109,6 +3114,7 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\coredll_sizer.obj \ $(OBJS)\coredll_srchcmn.obj \ $(OBJS)\coredll_statbar.obj \ + $(OBJS)\coredll_stattextcmn.obj \ $(OBJS)\coredll_stockitem.obj \ $(OBJS)\coredll_tbarbase.obj \ $(OBJS)\coredll_textcmn.obj \ @@ -3343,6 +3349,7 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\corelib_sizer.obj \ $(OBJS)\corelib_srchcmn.obj \ $(OBJS)\corelib_statbar.obj \ + $(OBJS)\corelib_stattextcmn.obj \ $(OBJS)\corelib_stockitem.obj \ $(OBJS)\corelib_tbarbase.obj \ $(OBJS)\corelib_textcmn.obj \ @@ -3570,6 +3577,7 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\corelib_sizer.obj \ $(OBJS)\corelib_srchcmn.obj \ $(OBJS)\corelib_statbar.obj \ + $(OBJS)\corelib_stattextcmn.obj \ $(OBJS)\corelib_stockitem.obj \ $(OBJS)\corelib_tbarbase.obj \ $(OBJS)\corelib_textcmn.obj \ @@ -6717,6 +6725,11 @@ $(OBJS)\monodll_statbar.obj: ..\..\src\common\statbar.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) $** !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\monodll_stattextcmn.obj: ..\..\src\common\stattextcmn.cpp + $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) $** +!endif + !if "$(USE_GUI)" == "1" $(OBJS)\monodll_stockitem.obj: ..\..\src\common\stockitem.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) $** @@ -8744,6 +8757,11 @@ $(OBJS)\monolib_statbar.obj: ..\..\src\common\statbar.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) $** !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\monolib_stattextcmn.obj: ..\..\src\common\stattextcmn.cpp + $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) $** +!endif + !if "$(USE_GUI)" == "1" $(OBJS)\monolib_stockitem.obj: ..\..\src\common\stockitem.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) $** @@ -10810,6 +10828,11 @@ $(OBJS)\coredll_statbar.obj: ..\..\src\common\statbar.cpp $(CXX) /c /nologo /TP /Fo$@ $(COREDLL_CXXFLAGS) $** !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\coredll_stattextcmn.obj: ..\..\src\common\stattextcmn.cpp + $(CXX) /c /nologo /TP /Fo$@ $(COREDLL_CXXFLAGS) $** +!endif + !if "$(USE_GUI)" == "1" $(OBJS)\coredll_stockitem.obj: ..\..\src\common\stockitem.cpp $(CXX) /c /nologo /TP /Fo$@ $(COREDLL_CXXFLAGS) $** @@ -12095,6 +12118,11 @@ $(OBJS)\corelib_statbar.obj: ..\..\src\common\statbar.cpp $(CXX) /c /nologo /TP /Fo$@ $(CORELIB_CXXFLAGS) $** !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\corelib_stattextcmn.obj: ..\..\src\common\stattextcmn.cpp + $(CXX) /c /nologo /TP /Fo$@ $(CORELIB_CXXFLAGS) $** +!endif + !if "$(USE_GUI)" == "1" $(OBJS)\corelib_stockitem.obj: ..\..\src\common\stockitem.cpp $(CXX) /c /nologo /TP /Fo$@ $(CORELIB_CXXFLAGS) $** diff --git a/build/msw/makefile.wat b/build/msw/makefile.wat index 9e7d63a0b9..4ffd314fa4 100644 --- a/build/msw/makefile.wat +++ b/build/msw/makefile.wat @@ -387,6 +387,7 @@ ____CORE_SRC_FILENAMES_OBJECTS = & $(OBJS)\monodll_sizer.obj & $(OBJS)\monodll_srchcmn.obj & $(OBJS)\monodll_statbar.obj & + $(OBJS)\monodll_stattextcmn.obj & $(OBJS)\monodll_stockitem.obj & $(OBJS)\monodll_tbarbase.obj & $(OBJS)\monodll_textcmn.obj & @@ -616,6 +617,7 @@ ____CORE_SRC_FILENAMES_OBJECTS = & $(OBJS)\monodll_sizer.obj & $(OBJS)\monodll_srchcmn.obj & $(OBJS)\monodll_statbar.obj & + $(OBJS)\monodll_stattextcmn.obj & $(OBJS)\monodll_stockitem.obj & $(OBJS)\monodll_tbarbase.obj & $(OBJS)\monodll_textcmn.obj & @@ -1019,6 +1021,7 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = & $(OBJS)\monolib_sizer.obj & $(OBJS)\monolib_srchcmn.obj & $(OBJS)\monolib_statbar.obj & + $(OBJS)\monolib_stattextcmn.obj & $(OBJS)\monolib_stockitem.obj & $(OBJS)\monolib_tbarbase.obj & $(OBJS)\monolib_textcmn.obj & @@ -1248,6 +1251,7 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = & $(OBJS)\monolib_sizer.obj & $(OBJS)\monolib_srchcmn.obj & $(OBJS)\monolib_statbar.obj & + $(OBJS)\monolib_stattextcmn.obj & $(OBJS)\monolib_stockitem.obj & $(OBJS)\monolib_tbarbase.obj & $(OBJS)\monolib_textcmn.obj & @@ -1588,6 +1592,7 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = & $(OBJS)\coredll_sizer.obj & $(OBJS)\coredll_srchcmn.obj & $(OBJS)\coredll_statbar.obj & + $(OBJS)\coredll_stattextcmn.obj & $(OBJS)\coredll_stockitem.obj & $(OBJS)\coredll_tbarbase.obj & $(OBJS)\coredll_textcmn.obj & @@ -1817,6 +1822,7 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = & $(OBJS)\coredll_sizer.obj & $(OBJS)\coredll_srchcmn.obj & $(OBJS)\coredll_statbar.obj & + $(OBJS)\coredll_stattextcmn.obj & $(OBJS)\coredll_stockitem.obj & $(OBJS)\coredll_tbarbase.obj & $(OBJS)\coredll_textcmn.obj & @@ -2053,6 +2059,7 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = & $(OBJS)\corelib_sizer.obj & $(OBJS)\corelib_srchcmn.obj & $(OBJS)\corelib_statbar.obj & + $(OBJS)\corelib_stattextcmn.obj & $(OBJS)\corelib_stockitem.obj & $(OBJS)\corelib_tbarbase.obj & $(OBJS)\corelib_textcmn.obj & @@ -2282,6 +2289,7 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = & $(OBJS)\corelib_sizer.obj & $(OBJS)\corelib_srchcmn.obj & $(OBJS)\corelib_statbar.obj & + $(OBJS)\corelib_stattextcmn.obj & $(OBJS)\corelib_stockitem.obj & $(OBJS)\corelib_tbarbase.obj & $(OBJS)\corelib_textcmn.obj & @@ -6889,6 +6897,11 @@ $(OBJS)\monodll_statbar.obj : .AUTODEPEND ..\..\src\common\statbar.cpp $(CXX) -bt=nt -zq -fo=$^@ $(MONODLL_CXXFLAGS) $< !endif +!ifeq USE_GUI 1 +$(OBJS)\monodll_stattextcmn.obj : .AUTODEPEND ..\..\src\common\stattextcmn.cpp + $(CXX) -bt=nt -zq -fo=$^@ $(MONODLL_CXXFLAGS) $< +!endif + !ifeq USE_GUI 1 $(OBJS)\monodll_stockitem.obj : .AUTODEPEND ..\..\src\common\stockitem.cpp $(CXX) -bt=nt -zq -fo=$^@ $(MONODLL_CXXFLAGS) $< @@ -9016,6 +9029,11 @@ $(OBJS)\monolib_statbar.obj : .AUTODEPEND ..\..\src\common\statbar.cpp $(CXX) -bt=nt -zq -fo=$^@ $(MONOLIB_CXXFLAGS) $< !endif +!ifeq USE_GUI 1 +$(OBJS)\monolib_stattextcmn.obj : .AUTODEPEND ..\..\src\common\stattextcmn.cpp + $(CXX) -bt=nt -zq -fo=$^@ $(MONOLIB_CXXFLAGS) $< +!endif + !ifeq USE_GUI 1 $(OBJS)\monolib_stockitem.obj : .AUTODEPEND ..\..\src\common\stockitem.cpp $(CXX) -bt=nt -zq -fo=$^@ $(MONOLIB_CXXFLAGS) $< @@ -11182,6 +11200,11 @@ $(OBJS)\coredll_statbar.obj : .AUTODEPEND ..\..\src\common\statbar.cpp $(CXX) -bt=nt -zq -fo=$^@ $(COREDLL_CXXFLAGS) $< !endif +!ifeq USE_GUI 1 +$(OBJS)\coredll_stattextcmn.obj : .AUTODEPEND ..\..\src\common\stattextcmn.cpp + $(CXX) -bt=nt -zq -fo=$^@ $(COREDLL_CXXFLAGS) $< +!endif + !ifeq USE_GUI 1 $(OBJS)\coredll_stockitem.obj : .AUTODEPEND ..\..\src\common\stockitem.cpp $(CXX) -bt=nt -zq -fo=$^@ $(COREDLL_CXXFLAGS) $< @@ -12567,6 +12590,11 @@ $(OBJS)\corelib_statbar.obj : .AUTODEPEND ..\..\src\common\statbar.cpp $(CXX) -bt=nt -zq -fo=$^@ $(CORELIB_CXXFLAGS) $< !endif +!ifeq USE_GUI 1 +$(OBJS)\corelib_stattextcmn.obj : .AUTODEPEND ..\..\src\common\stattextcmn.cpp + $(CXX) -bt=nt -zq -fo=$^@ $(CORELIB_CXXFLAGS) $< +!endif + !ifeq USE_GUI 1 $(OBJS)\corelib_stockitem.obj : .AUTODEPEND ..\..\src\common\stockitem.cpp $(CXX) -bt=nt -zq -fo=$^@ $(CORELIB_CXXFLAGS) $< diff --git a/build/msw/wx_core.dsp b/build/msw/wx_core.dsp index 6de40e0215..85b2d2941d 100644 --- a/build/msw/wx_core.dsp +++ b/build/msw/wx_core.dsp @@ -790,6 +790,10 @@ SOURCE=..\..\src\common\statbar.cpp # End Source File # Begin Source File +SOURCE=..\..\src\common\stattextcmn.cpp +# End Source File +# Begin Source File + SOURCE=..\..\src\common\stockitem.cpp # End Source File # Begin Source File diff --git a/docs/changes.txt b/docs/changes.txt index 2235a91d01..5d005bedf4 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -100,6 +100,7 @@ All (GUI): wxGTK: +- Support for markup and ellipsization in wxStaticText (Francesco Montorsi) - Native implementation for wxHyperlinkCtrl (Francesco Montorsi) - Native keyboard navigation implementation - Don't overwrite primary selection with clipboard and vice versa diff --git a/docs/latex/wx/stattext.tex b/docs/latex/wx/stattext.tex index 82ea780b8e..5db7a79b07 100644 --- a/docs/latex/wx/stattext.tex +++ b/docs/latex/wx/stattext.tex @@ -26,6 +26,14 @@ adjust its size to exactly fit to the size of the text when given, the control will not change its size (this style is especially useful with controls which also have wxALIGN\_RIGHT or CENTER style because otherwise they won't make sense any longer after a call to SetLabel)} +\twocolitem{\windowstyle{wxST\_ELLIPSIZE\_START}}{If the text width exceeds the +control width, replace the beginning of the text with an ellipsis} +\twocolitem{\windowstyle{wxST\_ELLIPSIZE\_MIDDLE}}{Same as above, but replace +the text in the middle of the control with an ellipsis} +\twocolitem{\windowstyle{wxST\_ELLIPSIZE\_END}}{Same as above, but replace the +end of the text with an ellipsis} +\twocolitem{\windowstyle{wxST_MARKUP}}{Support markup in the label; see +\helpref{SetLabel}{wxstatictextsetlabel} for more information} \end{twocollist} See also \helpref{window styles overview}{windowstyles}. @@ -85,6 +93,22 @@ Creation function, for two-step construction. For details see \helpref{wxStaticT Returns the contents of the control. +Note that the returned string contains both the mnemonics (\texttt{\&} characters), +if any, and markup tags, if any. + +Use \helpref{wxStaticText::GetLabelText}{wxstatictextgetlabeltext} if only the +label text is needed. + + +\membersection{wxStaticText::GetLabelText}\label{wxstatictextgetlabeltext} + +\constfunc{const wxString\&}{GetLabelText}{\void} + +Returns the control's label or the given \arg{label} string for the static +version without the mnemonics characters (if any) and without the markup +(if the control has \texttt{wxST_MARKUP} style). + + \membersection{wxStaticText::SetLabel}\label{wxstatictextsetlabel} @@ -93,12 +117,70 @@ Returns the contents of the control. Sets the static text label and updates the controls size to exactly fit the label unless the control has wxST\_NO\_AUTORESIZE flag. +This function allows to set decorated static label text on platforms which +support it (currently only GTK+ 2). For the other platforms, the markup is +ignored. + +The supported tags are: + +\twocolwidtha{5cm} +\begin{twocollist}\itemsep=0pt +\twocolitem{}{bold text} +\twocolitem{}{bigger text} +\twocolitem{}{italic text} +\twocolitem{}{strike-through text} +\twocolitem{}{subscript text} +\twocolitem{}{superscript text} +\twocolitem{}{smaller text} +\twocolitem{}{monospaced text} +\twocolitem{}{underlined text} +\twocolitem{}{generic formatter tag; see \urlref{Pango Markup}{http://developer.gnome.org/doc/API/2.0/pango/PangoMarkupFormat.html} for more information.} +\end{twocollist} + +Note that the string must be well-formed (e.g. all tags must be correctly closed) +otherwise it can be not shown correctly or at all. + +Also note that you need to escape the following special characters: + +\twocolwidtha{5cm} +\begin{twocollist}\itemsep=0pt +\twocolitem{\textbf{Special character}}{\textbf{Escape as}} +\twocolitem{\texttt{&}}{\texttt{&} or as \texttt{&&}} +\twocolitem{\texttt{'}}{\texttt{'}} +\twocolitem{\texttt{"}}{\texttt{"}} +\twocolitem{\texttt{<}}{\texttt{<}} +\twocolitem{\texttt{>}}{\texttt{>}} +\end{twocollist} + +The non-escaped ampersand \texttt{&} characters are interpreted as +mnemonics; see \helpref{wxControl::SetLabel}{wxcontrolsetlabel}. + + +Example: + +%% TEX NOTE: in the following block we need to write the (ugly) &&amp; +%% string in order to force Tex2rtf to show the && string +\begin{verbatim} + // this will set the wxStaticText to show the "Hello world!" string + // with the "Hello" world in bold on platforms which support markup + pStaticText->SetLabelWithMarkup(wxT("Hello world!")); + + // this will make wxStaticText show the string: + // + // Specials: & ' " < >" + // + // with "Specials" in smaller size font if markup is supported + pStaticText->SetLabelWithMarkup( + wxT("Specials: &amp; &apos; &quot;; &lt; &gt;")); +\end{verbatim} + \wxheading{Parameters} -\docparam{label}{The new label to set. It may contain newline characters.} +\docparam{label}{The new label to set. It may contain newline characters and the markup tags described above.} + -\membersection{wxStaticText::Wrap}\label{wxstatictextwrpa} +\membersection{wxStaticText::Wrap}\label{wxstatictextwrap} \func{void}{Wrap}{\param{int }{width}} diff --git a/include/wx/control.h b/include/wx/control.h index 560a476e05..cf939b5459 100644 --- a/include/wx/control.h +++ b/include/wx/control.h @@ -46,11 +46,36 @@ public: // get the control alignment (left/right/centre, top/bottom/centre) int GetAlignment() const { return m_windowStyle & wxALIGN_MASK; } + // get just the text of the label, without mnemonic characters ('&') + wxString GetLabelText() const { return GetLabelText(GetLabel()); } + + virtual void SetLabel(const wxString& label) + { + m_labelOrig = label; + + InvalidateBestSize(); + + wxWindow::SetLabel(label); + } + + virtual wxString GetLabel() const + { + // return the original string, as it was passed to SetLabel() + // (i.e. with wx-style mnemonics) + return m_labelOrig; + } + + // static utilities: + // get the string without mnemonic characters ('&') static wxString GetLabelText(const wxString& label); - // get just the text of the label, without mnemonic characters ('&') - wxString GetLabelText() const { return GetLabelText(GetLabel()); } + // removes the mnemonics characters + static wxString RemoveMnemonics(const wxString& str); + + // escapes the mnemonics characters ('&') by doubling them + static wxString EscapeMnemonics(const wxString& str); + // controls by default inherit the colours of their parents, if a // particular control class doesn't want to do it, it can override @@ -64,7 +89,6 @@ public: // if the button was clicked) virtual void Command(wxCommandEvent &event); - virtual void SetLabel( const wxString &label ); virtual bool SetFont(const wxFont& font); // wxControl-specific processing after processing the update event @@ -84,6 +108,9 @@ protected: // initialize the common fields of wxCommandEvent void InitCommandEvent(wxCommandEvent& event) const; + // this field contains the label in wx format, i.e. with '&' mnemonics + wxString m_labelOrig; + DECLARE_NO_COPY_CLASS(wxControlBase) }; diff --git a/include/wx/defs.h b/include/wx/defs.h index 117e8443be..bdf2293a34 100644 --- a/include/wx/defs.h +++ b/include/wx/defs.h @@ -1603,13 +1603,6 @@ enum wxBorder */ #define wxST_SIZEGRIP 0x0010 -/* - * wxStaticText flags - */ -#define wxST_NO_AUTORESIZE 0x0001 -#define wxST_DOTS_MIDDLE 0x0002 -#define wxST_DOTS_END 0x0004 - /* * wxStaticBitmap flags */ diff --git a/include/wx/gtk/control.h b/include/wx/gtk/control.h index 5c7ffcc4dc..cac29c261b 100644 --- a/include/wx/gtk/control.h +++ b/include/wx/gtk/control.h @@ -43,8 +43,6 @@ public: const wxValidator& validator = wxDefaultValidator, const wxString& name = wxControlNameStr); - virtual void SetLabel( const wxString &label ); - virtual wxString GetLabel() const; virtual wxVisualAttributes GetDefaultAttributes() const; @@ -56,6 +54,7 @@ protected: // sets the label to the given string and also sets it for the given widget void GTKSetLabelForLabel(GtkLabel *w, const wxString& label); + void GTKSetLabelWithMarkupForLabel(GtkLabel *w, const wxString& label); // GtkFrame helpers GtkWidget* GTKCreateFrame(const wxString& label); @@ -67,11 +66,11 @@ protected: static wxString GTKRemoveMnemonics(const wxString& label); // converts wx label to GTK+ label, i.e. basically replace "&"s with "_"s - // - // for GTK+ 1 (which doesn't support mnemonics) this is the same as - // GTKRemoveMnemonics() static wxString GTKConvertMnemonics(const wxString &label); + // converts wx label to GTK+ labels preserving Pango markup + static wxString GTKConvertMnemonicsWithMarkup(const wxString& label); + // These are used by GetDefaultAttributes static wxVisualAttributes GetDefaultAttributesFromGTKWidget(GtkWidget* widget, @@ -95,9 +94,6 @@ protected: // override this and return true. virtual bool UseGTKStyleBase() const { return false; } - // this field contains the label in wx format, i.e. with "&" mnemonics - wxString m_label; - private: DECLARE_DYNAMIC_CLASS(wxControl) }; diff --git a/include/wx/gtk/stattext.h b/include/wx/gtk/stattext.h index 42193ac8d1..949d2cbf9c 100644 --- a/include/wx/gtk/stattext.h +++ b/include/wx/gtk/stattext.h @@ -14,7 +14,7 @@ // wxStaticText //----------------------------------------------------------------------------- -class WXDLLIMPEXP_CORE wxStaticText : public wxControl +class WXDLLIMPEXP_CORE wxStaticText : public wxStaticTextBase { public: wxStaticText(); @@ -43,8 +43,7 @@ public: static wxVisualAttributes GetClassDefaultAttributes(wxWindowVariant variant = wxWINDOW_VARIANT_NORMAL); - // see wx/stattext.h - void Wrap(int width); + // implementation // -------------- @@ -59,6 +58,9 @@ protected: virtual wxSize DoGetBestSize() const; + virtual wxString DoGetLabel() const; + virtual void DoSetLabel(const wxString& str); + DECLARE_DYNAMIC_CLASS(wxStaticText) }; diff --git a/include/wx/mac/carbon/stattext.h b/include/wx/mac/carbon/stattext.h index 042d0d3f59..2935319c47 100644 --- a/include/wx/mac/carbon/stattext.h +++ b/include/wx/mac/carbon/stattext.h @@ -42,6 +42,9 @@ public: protected : + virtual wxString DoGetLabel() const; + virtual void DoSetLabel(const wxString& str); + virtual wxSize DoGetBestSize() const ; DECLARE_DYNAMIC_CLASS_NO_COPY(wxStaticText) diff --git a/include/wx/motif/stattext.h b/include/wx/motif/stattext.h index 28af0ff963..6b53e185d4 100644 --- a/include/wx/motif/stattext.h +++ b/include/wx/motif/stattext.h @@ -52,6 +52,9 @@ public: virtual WXWidget GetLabelWidget() const { return m_labelWidget; } + virtual void DoSetLabel(const wxString& str); + virtual wxString DoGetLabel() const; + protected: WXWidget m_labelWidget; }; diff --git a/include/wx/msw/stattext.h b/include/wx/msw/stattext.h index 284067079d..1c05fbf758 100644 --- a/include/wx/msw/stattext.h +++ b/include/wx/msw/stattext.h @@ -49,6 +49,9 @@ protected: int sizeFlags = wxSIZE_AUTO); virtual wxSize DoGetBestSize() const; + virtual wxString DoGetLabel() const; + virtual void DoSetLabel(const wxString& str); + DECLARE_DYNAMIC_CLASS_NO_COPY(wxStaticText) }; diff --git a/include/wx/os2/stattext.h b/include/wx/os2/stattext.h index 1399736537..7ef0e38879 100644 --- a/include/wx/os2/stattext.h +++ b/include/wx/os2/stattext.h @@ -67,6 +67,9 @@ protected: ); virtual wxSize DoGetBestSize(void) const; + virtual void DoSetLabel(const wxString& str); + virtual wxString DoGetLabel() const; + private: DECLARE_DYNAMIC_CLASS(wxStaticText) }; // end of CLASS wxStaticText diff --git a/include/wx/private/stattext.h b/include/wx/private/stattext.h new file mode 100644 index 0000000000..ac22a59269 --- /dev/null +++ b/include/wx/private/stattext.h @@ -0,0 +1,95 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: include/wx/private/stattext.h +// Purpose: Internal declarations for dlgcmn.cpp and stattextcmn.cpp +// Author: Francesco Montorsi +// Created: 2007-01-07 (extracted from dlgcmn.cpp) +// RCS-ID: $Id$ +// Copyright: (c) 1999 Vadim Zeitlin +// (c) 2007 wxWidgets team +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_PRIVATE_STATTEXT_H_ +#define _WX_PRIVATE_STATTEXT_H_ + +#if wxUSE_STATTEXT + +// ---------------------------------------------------------------------------- +// wxTextWrapper +// ---------------------------------------------------------------------------- + +// this class is used to wrap the text on word boundary: wrapping is done by +// calling OnStartLine() and OnOutputLine() functions +class wxTextWrapper +{ +public: + wxTextWrapper() { m_eol = false; } + + // win is used for getting the font, text is the text to wrap, width is the + // max line width or -1 to disable wrapping + void Wrap(wxWindow *win, const wxString& text, int widthMax); + + // we don't need it, but just to avoid compiler warnings + virtual ~wxTextWrapper() { } + +protected: + // line may be empty + virtual void OnOutputLine(const wxString& line) = 0; + + // called at the start of every new line (except the very first one) + virtual void OnNewLine() { } + +private: + // call OnOutputLine() and set m_eol to true + void DoOutputLine(const wxString& line) + { + OnOutputLine(line); + + m_eol = true; + } + + // this function is a destructive inspector: when it returns true it also + // resets the flag to false so calling it again woulnd't return true any + // more + bool IsStartOfNewLine() + { + if ( !m_eol ) + return false; + + m_eol = false; + + return true; + } + + + bool m_eol; +}; + +enum +{ + wxMARKUP_ENTITY_AMP, + wxMARKUP_ENTITY_LT, + wxMARKUP_ENTITY_GT, + wxMARKUP_ENTITY_APOS, + wxMARKUP_ENTITY_QUOT, + wxMARKUP_ENTITY_MAX +}; + +enum +{ + wxMARKUP_ELEMENT_NAME, + wxMARKUP_ELEMENT_VALUE, + wxMARKUP_ELEMENT_MAX +}; + +// these are the only entities treated in a special way by wxStaticText::SetLabel() +// when the wxST_MARKUP style is used; use as: +// +// wxMarkupEntities[wxMARKUP_ELEMENT_NAME][wxMARKUP_ENTITY_GT] == ">" +// wxMarkupEntities[wxMARKUP_ELEMENT_VALUE][wxMARKUP_ENTITY_GT] == ">" +// +extern const wxChar *wxMarkupEntities[wxMARKUP_ELEMENT_MAX][wxMARKUP_ENTITY_MAX]; + +#endif // wxUSE_STATTEXT + +#endif // _WX_PRIVATE_STATTEXT_H_ diff --git a/include/wx/stattext.h b/include/wx/stattext.h index 025ca8bb0f..8795777ea8 100644 --- a/include/wx/stattext.h +++ b/include/wx/stattext.h @@ -18,6 +18,17 @@ #include "wx/control.h" +/* + * wxStaticText flags + */ +#define wxST_NO_AUTORESIZE 0x0001 +#define wxST_MARKUP 0x0002 + +#define wxST_ELLIPSIZE_START 0x0004 +#define wxST_ELLIPSIZE_MIDDLE 0x0008 +#define wxST_ELLIPSIZE_END 0x0010 + + extern WXDLLEXPORT_DATA(const wxChar) wxStaticTextNameStr[]; class WXDLLEXPORT wxStaticTextBase : public wxControl @@ -25,20 +36,60 @@ class WXDLLEXPORT wxStaticTextBase : public wxControl public: wxStaticTextBase() { } - // in wxGTK wxStaticText doesn't derive from wxStaticTextBase so we have to - // declare this function directly in gtk header -#if !defined(__WXGTK__) || defined(__WXUNIVERSAL__) // wrap the text of the control so that no line is longer than the given // width (if possible: this function won't break words) - // - // NB: implemented in dlgcmn.cpp for now + // This function will modify the value returned by GetLabel()! void Wrap(int width); -#endif // ! native __WXGTK__ // overriden base virtuals virtual bool AcceptsFocus() const { return false; } virtual bool HasTransparentBackground() { return true; } + bool IsEllipsized() const + { + return HasFlag(wxST_ELLIPSIZE_START) || + HasFlag(wxST_ELLIPSIZE_MIDDLE) || + HasFlag(wxST_ELLIPSIZE_END); + } + + // get the string without mnemonic characters ('&') and without markup + // (if wxST_MARKUP is being used) + virtual wxString GetLabelText() const; + + // public utilities (symmetric to those in wxControl about mnemonics): + + // removes the markup accepted by wxStaticText when wxST_MARKUP is used, + // and then returns the cleaned string + static wxString RemoveMarkup(const wxString& str); + + // escapes the alls special symbols (<>"'&) present inside the given string + // using the corresponding entities (< > " ' &) + static wxString EscapeMarkup(const wxString& str); + + +protected: // functions required for wxST_ELLIPSIZE_* support + + // just calls RemoveMarkup & Ellipsize on the original label. + virtual wxString GetEllipsizedLabelWithoutMarkup() const; + + // replaces parts of the string with ellipsis if needed + wxString Ellipsize(const wxString& label) const; + + // to be called when updating the size of the static text: + // updates the label redoing ellipsization calculations + void UpdateLabel(); + + // These functions are platform-specific and must be overridden in ports + // which do not natively support ellipsization and they must be implemented + // in a way so that the m_label member of wxControl is not touched: + + // returns the real label currently displayed inside the control. + virtual wxString DoGetLabel() const { return wxEmptyString; } + + // sets the real label currently displayed inside the control, + // _without_ invalidating the size. The text passed is always markup-free. + virtual void DoSetLabel(const wxString& WXUNUSED(str)) { } + private: DECLARE_NO_COPY_CLASS(wxStaticTextBase) }; diff --git a/include/wx/univ/control.h b/include/wx/univ/control.h index 3a0217dfed..2c88bbe682 100644 --- a/include/wx/univ/control.h +++ b/include/wx/univ/control.h @@ -64,13 +64,15 @@ public: // this function will filter out '&' characters and will put the // accelerator char (the one immediately after '&') into m_chAccel - virtual void SetLabel(const wxString &label); - virtual wxString GetLabel() const; + virtual void SetLabel(const wxString& label); + + // return the current label + virtual wxString GetLabel() const { return m_label; } // wxUniversal-specific methods // return the accel index in the string or -1 if none and puts the modified - // string intosecond parameter if non NULL + // string into second parameter if non NULL static int FindAccelIndex(const wxString& label, wxString *labelOnly = NULL); @@ -89,6 +91,11 @@ protected: // common part of all ctors void Init(); + // set m_label and m_indexAccel and refresh the control to show the new + // label (but, unlike SetLabel(), don't call the base class SetLabel() thus + // avoiding to change wxControlBase::m_labelOrig) + void UnivDoSetLabel(const wxString& label); + private: // label and accel info wxString m_label; diff --git a/include/wx/univ/stattext.h b/include/wx/univ/stattext.h index 1ad12b5e39..401772e791 100644 --- a/include/wx/univ/stattext.h +++ b/include/wx/univ/stattext.h @@ -60,6 +60,9 @@ protected: // draw the control virtual void DoDraw(wxControlRenderer *renderer); + virtual void DoSetLabel(const wxString& str); + virtual wxString DoGetLabel() const; + DECLARE_ABSTRACT_CLASS(wxStaticText) }; diff --git a/samples/widgets/static.cpp b/samples/widgets/static.cpp index c40d3bccc0..8e4a24e0f6 100644 --- a/samples/widgets/static.cpp +++ b/samples/widgets/static.cpp @@ -53,7 +53,8 @@ enum { StaticPage_Reset = wxID_HIGHEST, StaticPage_BoxText, - StaticPage_LabelText + StaticPage_LabelText, + StaticPage_LabelTextWithMarkup }; // alignment radiobox values @@ -73,6 +74,13 @@ enum StaticVAlign_Max }; +enum +{ + StaticEllipsize_Start, + StaticEllipsize_Middle, + StaticEllipsize_End +}; + // ---------------------------------------------------------------------------- // MyStaticText and MyStaticBox // ---------------------------------------------------------------------------- @@ -155,6 +163,7 @@ protected: void OnButtonReset(wxCommandEvent& event); void OnButtonBoxText(wxCommandEvent& event); void OnButtonLabelText(wxCommandEvent& event); + void OnButtonLabelWithMarkupText(wxCommandEvent& event); // reset all parameters void Reset(); @@ -167,15 +176,19 @@ protected: // the check/radio boxes for styles wxCheckBox *m_chkVert, - *m_chkAutoResize; + *m_chkAutoResize, + *m_chkEllipsize, + *m_chkMarkup; wxRadioBox *m_radioHAlign, - *m_radioVAlign; + *m_radioVAlign, + *m_radioEllipsize; // the controls and the sizer containing them wxStaticBox *m_staticBox; wxStaticBoxSizer *m_sizerStatBox; - wxStaticText *m_statText; + wxStaticText *m_statText, + *m_statTextWithMarkup; #if wxUSE_STATLINE wxStaticLine *m_statLine; #endif // wxUSE_STATLINE @@ -183,7 +196,8 @@ protected: // the text entries for command parameters wxTextCtrl *m_textBox, - *m_textLabel; + *m_textLabel, + *m_textLabelWithMarkup; private: DECLARE_EVENT_TABLE() @@ -197,6 +211,7 @@ private: BEGIN_EVENT_TABLE(StaticWidgetsPage, WidgetsPage) EVT_BUTTON(StaticPage_Reset, StaticWidgetsPage::OnButtonReset) EVT_BUTTON(StaticPage_LabelText, StaticWidgetsPage::OnButtonLabelText) + EVT_BUTTON(StaticPage_LabelTextWithMarkup, StaticWidgetsPage::OnButtonLabelWithMarkupText) EVT_BUTTON(StaticPage_BoxText, StaticWidgetsPage::OnButtonBoxText) EVT_CHECKBOX(wxID_ANY, StaticWidgetsPage::OnCheckOrRadioBox) @@ -225,11 +240,13 @@ StaticWidgetsPage::StaticWidgetsPage(WidgetsBookCtrl *book, #if wxUSE_STATLINE m_statLine = (wxStaticLine *)NULL; #endif // wxUSE_STATLINE - m_statText = (wxStaticText *)NULL; + m_statText = m_statTextWithMarkup = (wxStaticText *)NULL; m_staticBox = (wxStaticBox *)NULL; m_sizerStatBox = (wxStaticBoxSizer *)NULL; m_sizerStatic = (wxSizer *)NULL; + + m_textBox = m_textLabel = m_textLabelWithMarkup = NULL; } void StaticWidgetsPage::CreateContent() @@ -241,6 +258,7 @@ void StaticWidgetsPage::CreateContent() wxSizer *sizerLeft = new wxStaticBoxSizer(box, wxVERTICAL); + m_chkMarkup = CreateCheckBoxAndAddToSizer(sizerLeft, _T("Support &markup")); m_chkVert = CreateCheckBoxAndAddToSizer(sizerLeft, _T("&Vertical line")); m_chkAutoResize = CreateCheckBoxAndAddToSizer(sizerLeft, _T("&Fit to text")); sizerLeft->Add(5, 5, 0, wxGROW | wxALL, 5); // spacer @@ -269,6 +287,24 @@ void StaticWidgetsPage::CreateContent() sizerLeft->Add(m_radioHAlign, 0, wxGROW | wxALL, 5); sizerLeft->Add(m_radioVAlign, 0, wxGROW | wxALL, 5); + + sizerLeft->Add(5, 5, 0, wxGROW | wxALL, 5); // spacer + + m_chkEllipsize = CreateCheckBoxAndAddToSizer(sizerLeft, _T("&Ellipsize")); + + static const wxString ellipsizeMode[] = + { + _T("&start"), + _T("&middle"), + _T("&end"), + }; + + m_radioEllipsize = new wxRadioBox(this, wxID_ANY, _T("&Ellipsize mode"), + wxDefaultPosition, wxDefaultSize, + WXSIZEOF(ellipsizeMode), ellipsizeMode); + + sizerLeft->Add(m_radioEllipsize, 0, wxGROW | wxALL, 5); + wxButton *btn = new wxButton(this, StaticPage_Reset, _T("&Reset")); sizerLeft->Add(btn, 0, wxALIGN_CENTRE_HORIZONTAL | wxALL, 15); @@ -288,8 +324,23 @@ void StaticWidgetsPage::CreateContent() wxID_ANY, &m_textLabel); sizerMiddle->Add(sizerRow, 0, wxGROW | wxALL, 5); + sizerRow = CreateSizerWithTextAndButton(StaticPage_LabelTextWithMarkup, + _T("Change decorated text label"), + wxID_ANY, &m_textLabelWithMarkup); + sizerMiddle->Add(sizerRow, 0, wxGROW | wxALL, 5); + + + // final initializations + // NB: must be done _before_ calling CreateStatic() + Reset(); + m_textBox->SetValue(_T("This is a box")); - m_textLabel->SetValue(_T("And this is a label\ninside the box")); + m_textLabel->SetValue(_T("And this is a\n\tlabel inside the box with a &mnemonic.\n") + _T("Only this text is affected by the ellipsize settings.")); + m_textLabelWithMarkup->SetValue(_T("Another label, this time decorated ") + _T("with markup; here you need entities ") + _T("for the symbols: < > & ' " ") + _T(" but you can still place &mnemonics...")); // right pane wxSizer *sizerRight = new wxBoxSizer(wxHORIZONTAL); @@ -303,9 +354,6 @@ void StaticWidgetsPage::CreateContent() sizerTop->Add(sizerMiddle, 0, wxGROW | wxALL, 10); sizerTop->Add(sizerRight, 1, wxGROW | (wxALL & ~wxRIGHT), 10); - // final initializations - Reset(); - SetSizer(sizerTop); } @@ -317,6 +365,8 @@ void StaticWidgetsPage::Reset() { m_chkVert->SetValue(false); m_chkAutoResize->SetValue(true); + m_chkEllipsize->SetValue(true); + m_chkMarkup->SetValue(true); m_radioHAlign->SetSelection(StaticHAlign_Left); m_radioVAlign->SetSelection(StaticVAlign_Top); @@ -332,17 +382,26 @@ void StaticWidgetsPage::CreateStatic() // delete m_sizerStatBox; -- deleted by Remove() m_sizerStatic->Remove(m_sizerStatBox); delete m_statText; + delete m_statTextWithMarkup; #if wxUSE_STATLINE delete m_statLine; #endif // wxUSE_STATLINE } int flagsBox = 0, - flagsText = ms_defaultFlags; + flagsText = ms_defaultFlags, + flagsDummyText = ms_defaultFlags; if ( !m_chkAutoResize->GetValue() ) { flagsText |= wxST_NO_AUTORESIZE; + flagsDummyText |= wxST_NO_AUTORESIZE; + } + + if ( m_chkMarkup->GetValue() ) + { + flagsText |= wxST_MARKUP; + flagsDummyText |= wxST_MARKUP; } int align = 0; @@ -384,6 +443,29 @@ void StaticWidgetsPage::CreateStatic() break; } + if ( m_chkEllipsize->GetValue() ) + { + switch ( m_radioEllipsize->GetSelection() ) + { + default: + wxFAIL_MSG(_T("unexpected radiobox selection")); + // fall through + + case StaticEllipsize_Start: + flagsDummyText |= wxST_ELLIPSIZE_START; + break; + + case StaticEllipsize_Middle: + flagsDummyText |= wxST_ELLIPSIZE_MIDDLE; + break; + + case StaticEllipsize_End: + flagsDummyText |= wxST_ELLIPSIZE_END; + break; + } + } + + flagsDummyText |= align; flagsText |= align; flagsBox |= align; @@ -395,7 +477,11 @@ void StaticWidgetsPage::CreateStatic() m_statText = new MyStaticText(this, wxID_ANY, m_textLabel->GetValue(), wxDefaultPosition, wxDefaultSize, - flagsText); + flagsDummyText); + m_statTextWithMarkup = new wxStaticText(this, wxID_ANY, + m_textLabelWithMarkup->GetValue(), + wxDefaultPosition, wxDefaultSize, + flagsText); #if wxUSE_STATLINE m_statLine = new wxStaticLine(this, wxID_ANY, @@ -407,7 +493,7 @@ void StaticWidgetsPage::CreateStatic() #if wxUSE_STATLINE m_sizerStatBox->Add(m_statLine, 0, wxGROW | wxALL, 5); #endif // wxUSE_STATLINE - m_sizerStatBox->Add(0, 0, 1); + m_sizerStatBox->Add(m_statTextWithMarkup, 1, wxGROW | wxALL, 5); m_sizerStatic->Add(m_sizerStatBox, 1, wxGROW); @@ -425,8 +511,13 @@ void StaticWidgetsPage::OnButtonReset(wxCommandEvent& WXUNUSED(event)) CreateStatic(); } -void StaticWidgetsPage::OnCheckOrRadioBox(wxCommandEvent& WXUNUSED(event)) +void StaticWidgetsPage::OnCheckOrRadioBox(wxCommandEvent& event) { + if (event.GetEventObject() == wx_static_cast(wxObject*, m_chkEllipsize)) + { + m_radioEllipsize->Enable(event.IsChecked()); + } + CreateStatic(); } @@ -435,8 +526,29 @@ void StaticWidgetsPage::OnButtonBoxText(wxCommandEvent& WXUNUSED(event)) m_sizerStatBox->GetStaticBox()->SetLabel(m_textBox->GetValue()); } +void StaticWidgetsPage::OnButtonLabelWithMarkupText(wxCommandEvent& WXUNUSED(event)) +{ + m_statTextWithMarkup->SetLabel(m_textLabelWithMarkup->GetValue()); + + // test GetLabel() and GetLabelText(); the first should return the + // label as it is written in the relative text control; the second should + // return the label as it's shown in the wxStaticText + wxLogMessage(wxT("The original label should be '%s'"), + m_statTextWithMarkup->GetLabel().c_str()); + wxLogMessage(wxT("The label text is '%s'"), + m_statTextWithMarkup->GetLabelText().c_str()); +} + void StaticWidgetsPage::OnButtonLabelText(wxCommandEvent& WXUNUSED(event)) { m_statText->SetLabel(m_textLabel->GetValue()); + + // test GetLabel() and GetLabelText(); the first should return the + // label as it is written in the relative text control; the second should + // return the label as it's shown in the wxStaticText + wxLogMessage(wxT("The original label should be '%s'"), + m_statText->GetLabel().c_str()); + wxLogMessage(wxT("The label text is '%s'"), + m_statText->GetLabelText().c_str()); } diff --git a/src/common/ctrlcmn.cpp b/src/common/ctrlcmn.cpp index 2bb9ab4520..1a026c4e39 100644 --- a/src/common/ctrlcmn.cpp +++ b/src/common/ctrlcmn.cpp @@ -120,13 +120,6 @@ void wxControlBase::InitCommandEvent(wxCommandEvent& event) const } } - -void wxControlBase::SetLabel( const wxString &label ) -{ - InvalidateBestSize(); - wxWindow::SetLabel(label); -} - bool wxControlBase::SetFont(const wxFont& font) { InvalidateBestSize(); @@ -159,6 +152,12 @@ void wxControlBase::DoUpdateWindowUI(wxUpdateUIEvent& event) #endif // wxUSE_RADIOBTN } +/* static */ +wxString wxControlBase::RemoveMnemonics(const wxString& str) +{ + return wxStripMenuCodes(str, wxStrip_Mnemonics); +} + // ---------------------------------------------------------------------------- // wxStaticBitmap // ---------------------------------------------------------------------------- diff --git a/src/common/dlgcmn.cpp b/src/common/dlgcmn.cpp index cf4557e883..67b0c89f10 100644 --- a/src/common/dlgcmn.cpp +++ b/src/common/dlgcmn.cpp @@ -38,61 +38,8 @@ #include "wx/statline.h" #include "wx/sysopt.h" +#include "wx/private/stattext.h" -#if wxUSE_STATTEXT - -// ---------------------------------------------------------------------------- -// wxTextWrapper -// ---------------------------------------------------------------------------- - -// this class is used to wrap the text on word boundary: wrapping is done by -// calling OnStartLine() and OnOutputLine() functions -class wxTextWrapper -{ -public: - wxTextWrapper() { m_eol = false; } - - // win is used for getting the font, text is the text to wrap, width is the - // max line width or -1 to disable wrapping - void Wrap(wxWindow *win, const wxString& text, int widthMax); - - // we don't need it, but just to avoid compiler warnings - virtual ~wxTextWrapper() { } - -protected: - // line may be empty - virtual void OnOutputLine(const wxString& line) = 0; - - // called at the start of every new line (except the very first one) - virtual void OnNewLine() { } - -private: - // call OnOutputLine() and set m_eol to true - void DoOutputLine(const wxString& line) - { - OnOutputLine(line); - - m_eol = true; - } - - // this function is a destructive inspector: when it returns true it also - // resets the flag to false so calling it again woulnd't return true any - // more - bool IsStartOfNewLine() - { - if ( !m_eol ) - return false; - - m_eol = false; - - return true; - } - - - bool m_eol; -}; - -#endif // wxUSE_STATTEXT // ---------------------------------------------------------------------------- // wxDialogBase @@ -126,58 +73,6 @@ void wxDialogBase::Init() #if wxUSE_STATTEXT -void wxTextWrapper::Wrap(wxWindow *win, const wxString& text, int widthMax) -{ - const wxChar *lastSpace = NULL; - wxString line; - - const wxChar *lineStart = text.c_str(); - for ( const wxChar *p = lineStart; ; p++ ) - { - if ( IsStartOfNewLine() ) - { - OnNewLine(); - - lastSpace = NULL; - line.clear(); - lineStart = p; - } - - if ( *p == _T('\n') || *p == _T('\0') ) - { - DoOutputLine(line); - - if ( *p == _T('\0') ) - break; - } - else // not EOL - { - if ( *p == _T(' ') ) - lastSpace = p; - - line += *p; - - if ( widthMax >= 0 && lastSpace ) - { - int width; - win->GetTextExtent(line, &width, NULL); - - if ( width > widthMax ) - { - // remove the last word from this line - line.erase(lastSpace - lineStart, p + 1 - lineStart); - DoOutputLine(line); - - // go back to the last word of this line which we didn't - // output yet - p = lastSpace; - } - } - //else: no wrapping at all or impossible to wrap - } - } -} - class wxTextSizerWrapper : public wxTextWrapper { public: @@ -238,45 +133,6 @@ wxSizer *wxDialogBase::CreateTextSizer(const wxString& message) return wrapper.CreateSizer(text, widthMax); } -class wxLabelWrapper : public wxTextWrapper -{ -public: - void WrapLabel(wxWindow *text, int widthMax) - { - m_text.clear(); - Wrap(text, text->GetLabel(), widthMax); - text->SetLabel(m_text); - } - -protected: - virtual void OnOutputLine(const wxString& line) - { - m_text += line; - } - - virtual void OnNewLine() - { - m_text += _T('\n'); - } - -private: - wxString m_text; -}; - -// NB: don't "factor out" the scope operator, SGI MIPSpro 7.3 (but not 7.4) -// gets confused if it doesn't immediately follow the class name -void -#if defined(__WXGTK__) && !defined(__WXUNIVERSAL__) -wxStaticText:: -#else -wxStaticTextBase:: -#endif -Wrap(int width) -{ - wxLabelWrapper wrapper; - wrapper.WrapLabel(this, width); -} - #endif // wxUSE_STATTEXT wxSizer *wxDialogBase::CreateButtonSizer(long flags) diff --git a/src/common/stattextcmn.cpp b/src/common/stattextcmn.cpp new file mode 100644 index 0000000000..184c9f1c98 --- /dev/null +++ b/src/common/stattextcmn.cpp @@ -0,0 +1,480 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: src/common/stattextcmn.cpp +// Purpose: common (to all ports) wxStaticText functions +// Author: Vadim Zeitlin, Francesco Montorsi +// Created: 2007-01-07 (extracted from dlgcmn.cpp) +// RCS-ID: $Id$ +// Copyright: (c) 1999-2006 Vadim Zeitlin +// (c) 2007 Francesco Montorsi +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#include "wx/private/stattext.h" + +#ifndef WX_PRECOMP + #include "wx/button.h" + #include "wx/dcclient.h" + #include "wx/intl.h" + #include "wx/settings.h" + #include "wx/stattext.h" + #include "wx/sizer.h" + #include "wx/containr.h" +#endif + +#if wxUSE_STATTEXT + +const wxChar *wxMarkupEntities[][wxMARKUP_ENTITY_MAX] = +{ + // the entities handled by SetLabel() when wxST_MARKUP is used and their referenced string + + { wxT("&"), wxT("<"), wxT(">"), wxT("'"), wxT(""") }, + { wxT("&"), wxT("<"), wxT(">"), wxT("'"), wxT("\"") } +}; + + +// ---------------------------------------------------------------------------- +// wxTextWrapper +// ---------------------------------------------------------------------------- + +void wxTextWrapper::Wrap(wxWindow *win, const wxString& text, int widthMax) +{ + const wxChar *lastSpace = NULL; + wxString line; + + const wxChar *lineStart = text.c_str(); + for ( const wxChar *p = lineStart; ; p++ ) + { + if ( IsStartOfNewLine() ) + { + OnNewLine(); + + lastSpace = NULL; + line.clear(); + lineStart = p; + } + + if ( *p == _T('\n') || *p == _T('\0') ) + { + DoOutputLine(line); + + if ( *p == _T('\0') ) + break; + } + else // not EOL + { + if ( *p == _T(' ') ) + lastSpace = p; + + line += *p; + + if ( widthMax >= 0 && lastSpace ) + { + int width; + win->GetTextExtent(line, &width, NULL); + + if ( width > widthMax ) + { + // remove the last word from this line + line.erase(lastSpace - lineStart, p + 1 - lineStart); + DoOutputLine(line); + + // go back to the last word of this line which we didn't + // output yet + p = lastSpace; + } + } + //else: no wrapping at all or impossible to wrap + } + } +} + + +// ---------------------------------------------------------------------------- +// wxLabelWrapper: helper class for wxStaticTextBase::Wrap() +// ---------------------------------------------------------------------------- + +class wxLabelWrapper : public wxTextWrapper +{ +public: + void WrapLabel(wxWindow *text, int widthMax) + { + m_text.clear(); + Wrap(text, text->GetLabel(), widthMax); + text->SetLabel(m_text); + } + +protected: + virtual void OnOutputLine(const wxString& line) + { + m_text += line; + } + + virtual void OnNewLine() + { + m_text += _T('\n'); + } + +private: + wxString m_text; +}; + + +// ---------------------------------------------------------------------------- +// wxStaticTextBase +// ---------------------------------------------------------------------------- + +void wxStaticTextBase::Wrap(int width) +{ + wxLabelWrapper wrapper; + wrapper.WrapLabel(this, width); +} + +wxString wxStaticTextBase::GetLabelText() const +{ + wxString ret(GetLabel()); + + if (HasFlag(wxST_MARKUP)) + ret = RemoveMarkup(ret); + return RemoveMnemonics(ret); +} + +/*static*/ +wxString wxStaticTextBase::RemoveMarkup(const wxString& text) +{ + // strip out of "text" the markup for platforms which don't support it natively + bool inside_tag = false; + + wxString label; + const wxChar *source = text; + for (size_t i=0, max=text.length(); i'): + if (!inside_tag) + { + wxLogDebug(wxT("Invalid markup !")); + return wxEmptyString; + } + inside_tag = false; + break; + + case wxT('&'): + { + if (i == max-1) + { + wxLogDebug(wxT("Cannot use & as last character of the string '%s'"), + text.c_str()); + return wxEmptyString; + } + + // is this ampersand introducing a mnemonic or rather an entity? + bool isMnemonic = true; + for (size_t j=0; j < wxMARKUP_ENTITY_MAX; j++) + { + const wxChar *entity = wxMarkupEntities[wxMARKUP_ELEMENT_NAME][j]; + size_t entityLen = wxStrlen(entity); + + if (max - i >= entityLen && + wxStrncmp(entity, &source[i], entityLen) == 0) + { + // replace the &entity; string with the entity reference + label << wxMarkupEntities[wxMARKUP_ELEMENT_VALUE][j]; + + // little exception: when the entity reference is "&" + // (i.e. when entity is "&"), substitute it with && + // instead of a single ampersand: + if (*wxMarkupEntities[wxMARKUP_ELEMENT_VALUE][j] == wxT('&')) + label << wxT('&'); + i += entityLen - 1; // the -1 is because main for() + // loop already increments i + isMnemonic = false; + break; + } + } + + if (isMnemonic) + label << text[i]; + } + break; + + + default: + if (!inside_tag) + label << text[i]; + } + } + + return label; +} + +/* static */ +wxString wxStaticTextBase::EscapeMarkup(const wxString& text) +{ + wxString ret; + + for (const wxChar *source = text; *source != wxT('\0'); source++) + { + bool isEntity = false; + + // search in the list of the entities and eventually escape this character + for (size_t j=0; j < wxMARKUP_ENTITY_MAX; j++) + { + if (*source == *wxMarkupEntities[wxMARKUP_ELEMENT_VALUE][j]) + { + ret << wxMarkupEntities[wxMARKUP_ELEMENT_NAME][j]; + isEntity = true; + break; + } + } + + if (!isEntity) + ret << *source; // this character does not need to be escaped + } + + return ret; +} + + + +// ---------------------------------------------------------------------------- +// wxStaticTextBase - generic implementation for wxST_ELLIPSIZE_* support +// ---------------------------------------------------------------------------- + +void wxStaticTextBase::UpdateLabel() +{ + if (!IsEllipsized()) + return; + + wxString newlabel = GetEllipsizedLabelWithoutMarkup(); + + // we need to touch the "real" label (i.e. the text set inside the control, + // using port-specific functions) instead of the string returned by GetLabel(). + // + // In fact, we must be careful not to touch the original label passed to + // SetLabel() otherwise GetLabel() will behave in a strange way to the user + // (e.g. returning a "Ver...ing" instead of "Very long string") ! + if (newlabel == DoGetLabel()) + return; + DoSetLabel(newlabel); +} + +wxString wxStaticTextBase::GetEllipsizedLabelWithoutMarkup() const +{ + // this function should be used only by ports which do not support + // ellipsis in static texts: we first remove markup (which cannot + // be handled safely by Ellipsize()) and then ellipsize the result. + + wxString ret(m_labelOrig); + + // the order of the following two blocks is important! + + if (HasFlag(wxST_MARKUP)) + ret = RemoveMarkup(ret); + + if (IsEllipsized()) + ret = Ellipsize(ret); + + return ret; +} + +#define wxELLIPSE_REPLACEMENT wxT("...") + +wxString wxStaticTextBase::Ellipsize(const wxString& label) const +{ + wxSize sz(GetSize()); + if (sz.GetWidth() < 2 || sz.GetHeight() < 2) + { + // the size of this window is not valid (yet) + return label; + } + + wxClientDC dc(wx_const_cast(wxStaticTextBase*, this)); + dc.SetFont(GetFont()); + + wxArrayInt charOffsets; + wxString ret; + + // these cannot be cached as they can change because of e.g. a font change + int replacementWidth = dc.GetTextExtent(wxELLIPSE_REPLACEMENT).GetWidth(); + int marginWidth = dc.GetCharWidth()*2; + + // handle correctly labels with newlines + wxString curLine; + wxSize reqsize; + size_t len; + for ( const wxChar *pc = label; ; pc++ ) + { + switch ( *pc ) + { + case _T('\n'): + case _T('\0'): + len = curLine.length(); + if (len > 0 && + dc.GetPartialTextExtents(curLine, charOffsets)) + { + wxASSERT(charOffsets.GetCount() == len); + + size_t totalWidth = charOffsets.Last(); + if ( totalWidth > (size_t)sz.GetWidth() ) + { + // we need to ellipsize this row + int excessPixels = totalWidth - sz.GetWidth() + + replacementWidth + + marginWidth; // security margin (NEEDED!) + + // remove characters in excess + size_t initialChar, // index of first char to erase + nChars; // how many chars do we need to erase? + if (HasFlag(wxST_ELLIPSIZE_START)) + { + initialChar = 0; + for (nChars=0; + nChars < len && charOffsets[nChars] < excessPixels; + nChars++) + ; + } + else if (HasFlag(wxST_ELLIPSIZE_MIDDLE)) + { + // the start & end of the removed span of chars + initialChar = len/2; + size_t endChar = len/2; + + int removed = 0; + for ( ; removed < excessPixels; ) + { + if (initialChar > 0) + { + // width of the initialChar-th character + int width = charOffsets[initialChar] - + charOffsets[initialChar-1]; + + // remove the initialChar-th character + removed += width; + initialChar--; + } + + if (endChar < len - 1 && + removed < excessPixels) + { + // width of the (endChar+1)-th character + int width = charOffsets[endChar+1] - + charOffsets[endChar]; + + // remove the endChar-th character + removed += width; + endChar++; + } + + if (initialChar == 0 && endChar == len-1) + { + nChars = len+1; + break; + } + } + + initialChar++; + nChars = endChar - initialChar + 1; + } + else + { + wxASSERT(HasFlag(wxST_ELLIPSIZE_END)); + wxASSERT(len > 0); + + int maxWidth = totalWidth - excessPixels; + for (initialChar=0; + initialChar < len && + charOffsets[initialChar] < maxWidth; + initialChar++) + ; + + if (initialChar == 0) + { + nChars = len; + } + else + { + initialChar--; // go back one character + nChars = len - initialChar; + } + } + + if (nChars > len) + { + // need to remove the entire row! + curLine.clear(); + } + else + { + // erase nChars characters after initialChar (included): + curLine.erase(initialChar, nChars+1); + + // if there is space for the replacement dots, add them + if (sz.GetWidth() > replacementWidth) + curLine.insert(initialChar, wxELLIPSE_REPLACEMENT); + } + + // if everything was ok, we should have shortened this line + // enough to make it fit in sz.GetWidth(): + wxASSERT(dc.GetTextExtent(curLine).GetWidth() < sz.GetWidth()); + } + } + + // add this (ellipsized) row to the rest of the label + ret << curLine << *pc; + curLine.clear(); + + if ( *pc == _T('\0') ) + return ret; + + break; + + // we need to remove mnemonics from the label for + // correct calculations + case _T('&'): + // pc+1 is safe: at worst we'll hit the \0 + if (*(pc+1) == _T('&')) + curLine += _T('&'); // && becomes & + //else: remove this ampersand + + break; + + // we need also to expand tabs to properly calc their size + case _T('\t'): + // Windows natively expands the TABs to 6 spaces. Do the same: + curLine += wxT(" "); + break; + + default: + curLine += *pc; + } + } + + //return ret; +} + +#endif // wxUSE_STATTEXT diff --git a/src/gtk/checkbox.cpp b/src/gtk/checkbox.cpp index f3352a1397..d984b94865 100644 --- a/src/gtk/checkbox.cpp +++ b/src/gtk/checkbox.cpp @@ -203,6 +203,9 @@ void wxCheckBox::SetLabel( const wxString& label ) { wxCHECK_RET( m_widgetLabel != NULL, wxT("invalid checkbox") ); + // save the label inside m_label in case user calls GetLabel() later + wxControl::SetLabel(label); + GTKSetLabelForLabel(GTK_LABEL(m_widgetLabel), label); } diff --git a/src/gtk/control.cpp b/src/gtk/control.cpp index 7af2a52fc8..9c81bcea8f 100644 --- a/src/gtk/control.cpp +++ b/src/gtk/control.cpp @@ -22,6 +22,9 @@ #include "wx/fontutil.h" #include "wx/gtk/private.h" +#include "wx/private/stattext.h" + + // ============================================================================ // wxControl implementation // ============================================================================ @@ -89,29 +92,21 @@ void wxControl::PostCreation(const wxSize& size) // wxControl dealing with labels // ---------------------------------------------------------------------------- -void wxControl::SetLabel( const wxString &label ) +void wxControl::GTKSetLabelForLabel(GtkLabel *w, const wxString& label) { - // keep the original string internally to be able to return it later (for - // consistency with the other ports) - m_label = label; + // save the original label + wxControlBase::SetLabel(label); - InvalidateBestSize(); + const wxString labelGTK = GTKConvertMnemonics(label); + gtk_label_set_text_with_mnemonic(w, wxGTK_CONV(labelGTK)); } -wxString wxControl::GetLabel() const +void wxControl::GTKSetLabelWithMarkupForLabel(GtkLabel *w, const wxString& label) { - return m_label; + const wxString labelGTK = GTKConvertMnemonicsWithMarkup(label); + gtk_label_set_markup_with_mnemonic(w, wxGTK_CONV(labelGTK)); } -void wxControl::GTKSetLabelForLabel(GtkLabel *w, const wxString& label) -{ - // don't call the virtual function which might call this one back again - wxControl::SetLabel(label); - - const wxString labelGTK = GTKConvertMnemonics(label); - - gtk_label_set_text_with_mnemonic(w, wxGTK_CONV(labelGTK)); -} // ---------------------------------------------------------------------------- // GtkFrame helpers @@ -130,8 +125,8 @@ GtkWidget* wxControl::GTKCreateFrame(const wxString& label) GtkWidget* framewidget = gtk_frame_new(NULL); gtk_frame_set_label_widget(GTK_FRAME(framewidget), labelwidget); - return framewidget; //note that the label is already set so you'll - //only need to call wxControl::SetLabel afterwards + return framewidget; // note that the label is already set so you'll + // only need to call wxControl::SetLabel afterwards } void wxControl::GTKSetLabelForFrame(GtkFrame *w, const wxString& label) @@ -154,22 +149,19 @@ void wxControl::GTKFrameSetMnemonicWidget(GtkFrame* w, GtkWidget* widget) } // ---------------------------------------------------------------------------- -// worker function implementing both GTKConvert/RemoveMnemonics() -// -// notice that under GTK+ 1 we only really need to support MNEMONICS_REMOVE as -// it doesn't support mnemonics anyhow but this would make the code so ugly -// that we do the same thing for GKT+ 1 and 2 +// worker function implementing GTK*Mnemonics() functions // ---------------------------------------------------------------------------- enum MnemonicsFlag { MNEMONICS_REMOVE, - MNEMONICS_CONVERT + MNEMONICS_CONVERT, + MNEMONICS_CONVERT_MARKUP }; -static wxString GTKProcessMnemonics(const wxString& label, MnemonicsFlag flag) +static wxString GTKProcessMnemonics(const wxChar* label, MnemonicsFlag flag) { - const size_t len = label.length(); + const size_t len = wxStrlen(label); wxString labelGTK; labelGTK.reserve(len); for ( size_t i = 0; i < len; i++ ) @@ -182,21 +174,50 @@ static wxString GTKProcessMnemonics(const wxString& label, MnemonicsFlag flag) if ( i == len - 1 ) { // "&" at the end of string is an error - wxLogDebug(wxT("Invalid label \"%s\"."), label.c_str()); + wxLogDebug(wxT("Invalid label \"%s\"."), label); break; } + if ( flag == MNEMONICS_CONVERT_MARKUP ) + { + bool isMnemonic = true; + + // is this ampersand introducing a mnemonic or rather an entity? + for (size_t j=0; j < wxMARKUP_ENTITY_MAX; j++) + { + const wxChar *entity = wxMarkupEntities[wxMARKUP_ELEMENT_NAME][j]; + size_t entityLen = wxStrlen(entity); + + if (len - i >= entityLen && + wxStrncmp(entity, &label[i], entityLen) == 0) + { + labelGTK << entity; + i += entityLen - 1; // the -1 is because main for() + // loop already increments i + isMnemonic = false; + + break; + } + } + + if (!isMnemonic) + continue; + } + ch = label[++i]; // skip '&' itself switch ( ch ) { case wxT('&'): // special case: "&&" is not a mnemonic at all but just // an escaped "&" - labelGTK += wxT('&'); + if ( flag == MNEMONICS_CONVERT_MARKUP ) + labelGTK += wxT("&"); + else + labelGTK += wxT('&'); break; case wxT('_'): - if ( flag == MNEMONICS_CONVERT ) + if ( flag != MNEMONICS_REMOVE ) { // '_' can't be a GTK mnemonic apparently so // replace it with something similar @@ -206,14 +227,14 @@ static wxString GTKProcessMnemonics(const wxString& label, MnemonicsFlag flag) //else: fall through default: - if ( flag == MNEMONICS_CONVERT ) + if ( flag != MNEMONICS_REMOVE ) labelGTK += wxT('_'); labelGTK += ch; } break; case wxT('_'): - if ( flag == MNEMONICS_CONVERT ) + if ( flag != MNEMONICS_REMOVE ) { // escape any existing underlines in the string so that // they don't become mnemonics accidentally @@ -242,6 +263,12 @@ wxString wxControl::GTKConvertMnemonics(const wxString& label) return GTKProcessMnemonics(label, MNEMONICS_CONVERT); } +/* static */ +wxString wxControl::GTKConvertMnemonicsWithMarkup(const wxString& label) +{ + return GTKProcessMnemonics(label, MNEMONICS_CONVERT_MARKUP); +} + // ---------------------------------------------------------------------------- // wxControl styles (a.k.a. attributes) // ---------------------------------------------------------------------------- diff --git a/src/gtk/stattext.cpp b/src/gtk/stattext.cpp index 67eec8eef5..c60fcf3f11 100644 --- a/src/gtk/stattext.cpp +++ b/src/gtk/stattext.cpp @@ -41,7 +41,7 @@ wxStaticText::wxStaticText(wxWindow *parent, long style, const wxString &name) { - Create( parent, id, label, pos, size, style, name ); + Create( parent, id, label, pos, size, style, name ); } bool wxStaticText::Create(wxWindow *parent, @@ -61,9 +61,7 @@ bool wxStaticText::Create(wxWindow *parent, return FALSE; } - const wxString labelGTK = GTKConvertMnemonics(label); - m_label = label; - m_widget = gtk_label_new_with_mnemonic(wxGTK_CONV(labelGTK)); + m_widget = gtk_label_new(NULL); GtkJustification justify; if ( style & wxALIGN_CENTER ) @@ -89,6 +87,24 @@ bool wxStaticText::Create(wxWindow *parent, gtk_label_set_line_wrap( GTK_LABEL(m_widget), TRUE ); +#ifdef __WXGTK26__ + if (!gtk_check_version(2,6,0)) + { + // set ellipsize mode + PangoEllipsizeMode ellipsizeMode = PANGO_ELLIPSIZE_NONE; + if ( style & wxST_ELLIPSIZE_START ) + ellipsizeMode = PANGO_ELLIPSIZE_START; + else if ( style & wxST_ELLIPSIZE_MIDDLE ) + ellipsizeMode = PANGO_ELLIPSIZE_MIDDLE; + else if ( style & wxST_ELLIPSIZE_END ) + ellipsizeMode = PANGO_ELLIPSIZE_END; + + gtk_label_set_ellipsize( GTK_LABEL(m_widget), ellipsizeMode ); + } +#endif // __WXGTK26__ + + SetLabel(label); + m_parent->DoAddChild( this ); PostCreation(size); @@ -110,20 +126,39 @@ bool wxStaticText::Create(wxWindow *parent, wxString wxStaticText::GetLabel() const { - GtkLabel *label = GTK_LABEL(m_widget); - wxString str = wxGTK_CONV_BACK( gtk_label_get_text( label ) ); - - return wxString(str); + // we need to return the label just like it was passed to the last call + // to SetLabel(): i.e. with wx-style mnemonics and with markup + return wxControl::GetLabel(); } -void wxStaticText::SetLabel( const wxString &label ) +void wxStaticText::SetLabel( const wxString& str ) { wxCHECK_RET( m_widget != NULL, wxT("invalid static text") ); - GTKSetLabelForLabel(GTK_LABEL(m_widget), label); + // save the label inside m_labelOrig in case user calls GetLabel() later + m_labelOrig = str; + + wxString label(str); + if (gtk_check_version(2,6,0) && + IsEllipsized()) + { + // GTK+ < 2.6 does not support ellipsization: + // since we need to use our generic code for ellipsization (which does not + // behaves well in conjunction with markup; i.e. it may break the markup + // validity erasing portions of the string), we also need to strip out + // the markup (if present) from the label. + + label = GetEllipsizedLabelWithoutMarkup(); + } + + if ( HasFlag(wxST_MARKUP) ) + GTKSetLabelWithMarkupForLabel(GTK_LABEL(m_widget), label); + else + GTKSetLabelForLabel(GTK_LABEL(m_widget), label); // adjust the label size to the new label unless disabled - if ( !HasFlag(wxST_NO_AUTORESIZE) ) + if ( !HasFlag(wxST_NO_AUTORESIZE) && + !IsEllipsized() ) // if ellipsize is ON, then we don't want to get resized! SetSize( GetBestSize() ); } @@ -171,6 +206,13 @@ void wxStaticText::DoSetSize(int x, int y, int sizeFlags ) { wxControl::DoSetSize( x, y, width, height, sizeFlags ); + + if (gtk_check_version(2,6,0)) + { + // GTK+ < 2.6 does not support ellipsization - we need to run our + // generic code (actually it will be run only if IsEllipsized() == true) + UpdateLabel(); + } } wxSize wxStaticText::DoGetBestSize() const @@ -215,6 +257,20 @@ void wxStaticText::GTKWidgetDoSetMnemonic(GtkWidget* w) gtk_label_set_mnemonic_widget(GTK_LABEL(m_widget), w); } + +// These functions should be used only when GTK+ < 2.6 by wxStaticTextBase::UpdateLabel() + +wxString wxStaticText::DoGetLabel() const +{ + GtkLabel *label = GTK_LABEL(m_widget); + return wxGTK_CONV_BACK( gtk_label_get_text( label ) ); +} + +void wxStaticText::DoSetLabel(const wxString& str) +{ + GTKSetLabelForLabel(GTK_LABEL(m_widget), str); +} + // static wxVisualAttributes wxStaticText::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant)) diff --git a/src/mac/carbon/stattext.cpp b/src/mac/carbon/stattext.cpp index 7610d13c8c..236c88000e 100644 --- a/src/mac/carbon/stattext.cpp +++ b/src/mac/carbon/stattext.cpp @@ -43,24 +43,21 @@ bool wxStaticText::Create( wxWindow *parent, { m_macIsUserPane = false; - m_label = GetLabelText( label ); - if ( !wxControl::Create( parent, id, pos, size, style, wxDefaultValidator, name ) ) return false; Rect bounds = wxMacGetBoundsForControl( this, pos, size ); - wxMacCFStringHolder str( m_label, m_font.GetEncoding() ); m_peer = new wxMacControl( this ); OSStatus err = CreateStaticTextControl( MAC_WXHWND(parent->MacGetTopLevelWindowRef()), - &bounds, str, NULL, m_peer->GetControlRefAddr() ); + &bounds, NULL, NULL, m_peer->GetControlRefAddr() ); verify_noerr( err ); - if ( ( style & wxST_DOTS_END ) || ( style & wxST_DOTS_MIDDLE ) ) + if ( ( style & wxST_ELLIPSIZE_END ) || ( style & wxST_ELLIPSIZE_MIDDLE ) ) { TruncCode tCode = truncEnd; - if ( style & wxST_DOTS_MIDDLE ) + if ( style & wxST_ELLIPSIZE_MIDDLE ) tCode = truncMiddle; err = m_peer->SetData( kControlStaticTextTruncTag, tCode ); @@ -69,6 +66,8 @@ bool wxStaticText::Create( wxWindow *parent, MacPostControlCreate( pos, size ); + SetLabel(label); + return true; } @@ -133,16 +132,28 @@ wxSize wxStaticText::DoGetBestSize() const return wxSize( bounds.h, bounds.v ); } -void wxStaticText::SetLabel( const wxString& st ) +void wxStaticText::SetLabel(const wxString& label) { - m_label = GetLabelText( st ); + m_labelOrig = label; - wxMacCFStringHolder str( m_label, m_font.GetEncoding() ); - CFStringRef ref = str; - OSStatus err = m_peer->SetData(kControlEntireControl, kControlStaticTextCFStringTag, ref ); - verify_noerr( err ); + // middle/end ellipsization is handled by the OS: + if ( HasFlag(wxST_ELLIPSIZE_END) || HasFlag(wxST_ELLIPSIZE_MIDDLE) ) + { + // remove markup + wxString str(label); + if (HasFlag(wxST_MARKUP)) + str = RemoveMarkup(label); - if ( !(GetWindowStyle() & wxST_NO_AUTORESIZE) ) + // and leave ellipsization to the OS + DoSetLabel(str); + } + else // not supported natively + { + DoSetLabel(GetEllipsizedLabelWithoutMarkup()); + } + + if ( !(GetWindowStyle() & wxST_NO_AUTORESIZE) && + !IsEllipsized() ) // don't resize if we adjust to current size { InvalidateBestSize(); SetSize( GetBestSize() ); @@ -170,4 +181,26 @@ bool wxStaticText::SetFont(const wxFont& font) return ret; } + +// for wxST_ELLIPSIZE_* support: + +void wxStaticText::DoSetLabel(const wxString& label) +{ + m_label = RemoveMnemonics(label); + + wxMacCFStringHolder str( m_label, m_font.GetEncoding() ); + OSStatus err = m_peer->SetData(kControlEntireControl, kControlStaticTextCFStringTag, str); + verify_noerr( err ); +} + +wxString wxStaticText::DoGetLabel() const +{ + return m_label; +} + +/* + FIXME: UpdateLabel() should be called on size events when wxST_ELLIPSIZE_START is set + to allow correct dynamic ellipsizing of the label +*/ + #endif //if wxUSE_STATTEXT diff --git a/src/motif/stattext.cpp b/src/motif/stattext.cpp index 38b95a5538..fce5aaf4f0 100644 --- a/src/motif/stattext.cpp +++ b/src/motif/stattext.cpp @@ -47,14 +47,12 @@ bool wxStaticText::Create(wxWindow *parent, wxWindowID id, Widget borderWidget = (Widget) wxCreateBorderWidget( (WXWidget)parentWidget, style ); - wxXmString text( GetLabelText( label ) ); m_labelWidget = XtVaCreateManagedWidget (wxConstCast(name.mb_str(), char), xmLabelWidgetClass, borderWidget ? borderWidget : parentWidget, wxFont::GetFontTag(), m_font.GetFontTypeC(XtDisplay(parentWidget)), - XmNlabelString, text(), XmNalignment, ((style & wxALIGN_RIGHT) ? XmALIGNMENT_END : ((style & wxALIGN_CENTRE) ? XmALIGNMENT_CENTER : XmALIGNMENT_BEGINNING)), @@ -68,12 +66,33 @@ bool wxStaticText::Create(wxWindow *parent, wxWindowID id, ChangeBackgroundColour (); + SetLabel(label); + return true; } void wxStaticText::SetLabel(const wxString& label) { - wxXmString label_str(GetLabelText(label)); + m_labelOrig = label; // save original label + + // Motif does not support neither ellipsize nor markup in static text: + DoSetLabel(GetEllipsizedLabelWithoutMarkup()); +} + +// for wxST_ELLIPSIZE_* support: + +wxString wxStaticText::DoGetLabel() const +{ + XmString label = NULL; + XtVaGetValues((Widget)m_labelWidget, XmNlabelString, &label, NULL); + + return wxXmStringToString(label); +} + +void wxStaticText::DoSetLabel(const wxString& str) +{ + // build our own cleaned label + wxXmString label_str(RemoveMnemonics(str)); // This variable means we don't need so many casts later. Widget widget = (Widget) m_labelWidget; @@ -84,4 +103,9 @@ void wxStaticText::SetLabel(const wxString& label) NULL); } +/* + FIXME: UpdateLabel() should be called on size events to allow correct + dynamic ellipsizing of the label +*/ + #endif // wxUSE_STATTEXT diff --git a/src/msw/control.cpp b/src/msw/control.cpp index bd6c3cff17..54fd80129e 100644 --- a/src/msw/control.cpp +++ b/src/msw/control.cpp @@ -162,6 +162,10 @@ bool wxControl::MSWCreateControl(const wxChar *classname, return false; } + // saving the label in m_labelOrig to return it verbatim + // later in GetLabel() + m_labelOrig = label; + // install wxWidgets window proc for this window SubclassWin(m_hWnd); diff --git a/src/msw/stattext.cpp b/src/msw/stattext.cpp index 20ae8b9c92..f0252e1fc4 100644 --- a/src/msw/stattext.cpp +++ b/src/msw/stattext.cpp @@ -121,6 +121,16 @@ WXDWORD wxStaticText::MSWGetStyle(long style, WXDWORD *exstyle) const msStyle |= SS_LEFT; // this style is necessary to receive mouse events + // Win NT and later have the SS_ENDELLIPSIS style which is useful to us: + if (wxGetOsVersion() == wxOS_WINDOWS_NT) + { + // for now, add the SS_ENDELLIPSIS style if wxST_ELLIPSIZE_END is given; + // we may need to remove it later in ::SetLabel() if the given label + // has newlines + if ( style & wxST_ELLIPSIZE_END ) + msStyle |= SS_ENDELLIPSIS; + } + msStyle |= SS_NOTIFY; return msStyle; @@ -181,20 +191,60 @@ wxSize wxStaticText::DoGetBestSize() const void wxStaticText::DoSetSize(int x, int y, int w, int h, int sizeFlags) { - // we need to refresh the window after changing its size as the standard - // control doesn't always update itself properly + // note: we first need to set the size and _then_ call UpdateLabel wxStaticTextBase::DoSetSize(x, y, w, h, sizeFlags); + // do we need to ellipsize the contents? + long styleReal = ::GetWindowLong(GetHwnd(), GWL_STYLE); + if ( !(styleReal & SS_ENDELLIPSIS) ) + { + // we don't have SS_ENDELLIPSIS style: + // we need to (eventually) do ellipsization ourselves + UpdateLabel(); + } + //else: we don't or the OS will do it for us + + // we need to refresh the window after changing its size as the standard + // control doesn't always update itself properly Refresh(); } void wxStaticText::SetLabel(const wxString& label) { - wxStaticTextBase::SetLabel(label); + long styleReal = ::GetWindowLong(GetHwnd(), GWL_STYLE); + if ( HasFlag(wxST_ELLIPSIZE_END) && + wxGetOsVersion() == wxOS_WINDOWS_NT ) + { + // adding SS_ENDELLIPSIS or SS_ENDELLIPSIS "disables" the correct + // newline handling in static texts: the newlines in the labels are + // shown as square. Thus we don't use it even on newer OS when + // the static label contains a newline. + if ( label.Contains(wxT('\n')) ) + styleReal &= ~SS_ENDELLIPSIS; + else + styleReal |= SS_ENDELLIPSIS; + + ::SetWindowLong(GetHwnd(), GWL_STYLE, styleReal); + } + else // style not supported natively + { + styleReal &= ~SS_ENDELLIPSIS; + ::SetWindowLong(GetHwnd(), GWL_STYLE, styleReal); + } + + // this call will save the label in m_labelOrig and set it into this window + // (through wxWindow::SetLabel) + m_labelOrig = label; + + if ((styleReal & SS_ENDELLIPSIS) == 0) + DoSetLabel(GetEllipsizedLabelWithoutMarkup()); + else + DoSetLabel(RemoveMarkup(label)); // adjust the size of the window to fit to the label unless autoresizing is // disabled - if ( !(GetWindowStyle() & wxST_NO_AUTORESIZE) ) + if ( !HasFlag(wxST_NO_AUTORESIZE) && + !IsEllipsized() ) // if ellipsize is ON, then we don't want to get resized! { InvalidateBestSize(); DoSetSize(wxDefaultCoord, wxDefaultCoord, wxDefaultCoord, wxDefaultCoord, @@ -202,14 +252,13 @@ void wxStaticText::SetLabel(const wxString& label) } } - bool wxStaticText::SetFont(const wxFont& font) { bool ret = wxControl::SetFont(font); // adjust the size of the window to fit to the label unless autoresizing is // disabled - if ( !(GetWindowStyle() & wxST_NO_AUTORESIZE) ) + if ( !HasFlag(wxST_NO_AUTORESIZE) ) { InvalidateBestSize(); DoSetSize(wxDefaultCoord, wxDefaultCoord, wxDefaultCoord, wxDefaultCoord, @@ -219,4 +268,17 @@ bool wxStaticText::SetFont(const wxFont& font) return ret; } +// for wxST_ELLIPSIZE_* support: + +wxString wxStaticText::DoGetLabel() const +{ + return wxGetWindowText(GetHwnd()); +} + +void wxStaticText::DoSetLabel(const wxString& str) +{ + SetWindowText(GetHwnd(), str.c_str()); +} + + #endif // wxUSE_STATTEXT diff --git a/src/os2/stattext.cpp b/src/os2/stattext.cpp index b636f26e3d..6d641a4417 100644 --- a/src/os2/stattext.cpp +++ b/src/os2/stattext.cpp @@ -66,11 +66,9 @@ bool wxStaticText::Create( wxWindow* pParent, else lSstyle |= DT_LEFT; - wxString sLabel = ::wxPMTextToLabel(rsLabel); - m_hWnd = (WXHWND)::WinCreateWindow( (HWND)GetHwndOf(pParent) // Parent window handle ,WC_STATIC // Window class - ,(PSZ)sLabel.c_str() // Initial Text + ,NULL // Initial Text ,(ULONG)lSstyle // Style flags ,0L, 0L, 0L, 0L // Origin -- 0 size ,(HWND)GetHwndOf(pParent) // owner window handle (same as parent @@ -103,12 +101,14 @@ bool wxStaticText::Create( wxWindow* pParent, SetYComp(0); SetSize( nX, nY, nWidth, nHeight ); + SetLabel(rsLabel); + return true; } // end of wxStaticText::Create wxSize wxStaticText::DoGetBestSize() const { - wxString sText(wxGetWindowText(GetHWND())); + wxString sText(GetLabel()); int nWidthTextMax = 0; int nWidthLine = 0; int nHeightTextTotal = 0; @@ -205,6 +205,10 @@ void wxStaticText::DoSetSize( ,nHeight ,nSizeFlags ); + + // eventually update label (if ellipsizing is on): + UpdateLabel(); + Refresh(); } // end of wxStaticText::DoSetSize @@ -229,14 +233,17 @@ void wxStaticText::SetLabel( const wxString& rsLabel ) { - wxString sLabel = ::wxPMTextToLabel(rsLabel); - ::WinSetWindowText(GetHwnd(), (PSZ)sLabel.c_str()); + m_labelOrig = rsLabel; // save original label + + // OS/2 does not support neither ellipsize nor markup in static text: + DoSetLabel(GetEllipsizedLabelWithoutMarkup(label)); // // Adjust the size of the window to fit to the label unless autoresizing is // disabled // - if (!(GetWindowStyle() & wxST_NO_AUTORESIZE)) + if (!(GetWindowStyle() & wxST_NO_AUTORESIZE) && + !IsEllipsized()) { wxCoord vX; wxCoord vY; @@ -263,3 +270,19 @@ MRESULT wxStaticText::OS2WindowProc( ,lParam ); } // end of wxStaticText::OS2WindowProc + + +// for wxST_ELLIPSIZE_* support: + +void wxStaticText::DoSetLabel(const wxString& str) +{ + wxString sLabel = ::wxPMTextToLabel(str); + ::WinSetWindowText(GetHwnd(), (PSZ)sLabel.c_str()); +} + +wxString wxStaticText::DoGetLabel() const +{ + // FIXME: how to retrieve the text? + //return wxGetWindowText(GetHWND()); +} + diff --git a/src/univ/control.cpp b/src/univ/control.cpp index 67cadcb96f..8a692bf840 100644 --- a/src/univ/control.cpp +++ b/src/univ/control.cpp @@ -122,6 +122,14 @@ int wxControl::FindAccelIndex(const wxString& label, wxString *labelOnly) } void wxControl::SetLabel(const wxString& label) +{ + // save original label + wxControlBase::SetLabel(label); + + UnivDoSetLabel(label); +} + +void wxControl::UnivDoSetLabel(const wxString& label) { wxString labelOld = m_label; m_indexAccel = FindAccelIndex(label, &m_label); @@ -132,9 +140,4 @@ void wxControl::SetLabel(const wxString& label) } } -wxString wxControl::GetLabel() const -{ - return m_label; -} - #endif // wxUSE_CONTROLS diff --git a/src/univ/stattext.cpp b/src/univ/stattext.cpp index 83ebf31eaf..ea5d42a206 100644 --- a/src/univ/stattext.cpp +++ b/src/univ/stattext.cpp @@ -66,11 +66,6 @@ bool wxStaticText::Create(wxWindow *parent, // size management // ---------------------------------------------------------------------------- -void wxStaticText::SetLabel(const wxString& label) -{ - wxControl::SetLabel(label); -} - wxSize wxStaticText::DoGetBestClientSize() const { wxStaticText *self = wxConstCast(this, wxStaticText); @@ -99,4 +94,28 @@ void wxStaticText::DoDraw(wxControlRenderer *renderer) renderer->DrawLabel(); } +void wxStaticText::SetLabel(const wxString& str) +{ + // save original label + m_labelOrig = str; + + // draw as real label the result of GetEllipsizedLabelWithoutMarkup: + DoSetLabel(GetEllipsizedLabelWithoutMarkup()); +} + +void wxStaticText::DoSetLabel(const wxString& str) +{ + UnivDoSetLabel(str); +} + +wxString wxStaticText::DoGetLabel() const +{ + return wxControl::GetLabel(); +} + +/* + FIXME: UpdateLabel() should be called on size events to allow correct + dynamic ellipsizing of the label +*/ + #endif // wxUSE_STATTEXT -- 2.45.2