diff --git a/Makefile.in b/Makefile.in
index fd4fa5affb..c5c79ff9f8 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -3625,6 +3625,11 @@ COND_USE_GUI_1_ALL_GUI_HEADERS = \
wx/notebook.h \
wx/ownerdrw.h \
wx/paper.h \
+ wx/persist.h \
+ wx/persist/bookctrl.h \
+ wx/persist/toplevel.h \
+ wx/persist/treebook.h \
+ wx/persist/window.h \
wx/pickerbase.h \
wx/popupwin.h \
wx/print.h \
@@ -4104,6 +4109,7 @@ COND_USE_GUI_1_WXUNIV_0___CORE_SRC_OBJECTS = \
monodll_nbkbase.o \
monodll_overlaycmn.o \
monodll_paper.o \
+ monodll_persist.o \
monodll_pickerbase.o \
monodll_popupcmn.o \
monodll_prntbase.o \
@@ -4295,6 +4301,7 @@ COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS = \
monodll_nbkbase.o \
monodll_overlaycmn.o \
monodll_paper.o \
+ monodll_persist.o \
monodll_pickerbase.o \
monodll_popupcmn.o \
monodll_prntbase.o \
@@ -5915,6 +5922,7 @@ COND_USE_GUI_1_WXUNIV_0___CORE_SRC_OBJECTS_1 = \
monolib_nbkbase.o \
monolib_overlaycmn.o \
monolib_paper.o \
+ monolib_persist.o \
monolib_pickerbase.o \
monolib_popupcmn.o \
monolib_prntbase.o \
@@ -6106,6 +6114,7 @@ COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS_1 = \
monolib_nbkbase.o \
monolib_overlaycmn.o \
monolib_paper.o \
+ monolib_persist.o \
monolib_pickerbase.o \
monolib_popupcmn.o \
monolib_prntbase.o \
@@ -7872,6 +7881,7 @@ COND_USE_GUI_1_WXUNIV_0___CORE_SRC_OBJECTS_2 = \
coredll_nbkbase.o \
coredll_overlaycmn.o \
coredll_paper.o \
+ coredll_persist.o \
coredll_pickerbase.o \
coredll_popupcmn.o \
coredll_prntbase.o \
@@ -8063,6 +8073,7 @@ COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS_2 = \
coredll_nbkbase.o \
coredll_overlaycmn.o \
coredll_paper.o \
+ coredll_persist.o \
coredll_pickerbase.o \
coredll_popupcmn.o \
coredll_prntbase.o \
@@ -9381,6 +9392,7 @@ COND_USE_GUI_1_WXUNIV_0___CORE_SRC_OBJECTS_3 = \
corelib_nbkbase.o \
corelib_overlaycmn.o \
corelib_paper.o \
+ corelib_persist.o \
corelib_pickerbase.o \
corelib_popupcmn.o \
corelib_prntbase.o \
@@ -9572,6 +9584,7 @@ COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS_3 = \
corelib_nbkbase.o \
corelib_overlaycmn.o \
corelib_paper.o \
+ corelib_persist.o \
corelib_pickerbase.o \
corelib_popupcmn.o \
corelib_prntbase.o \
@@ -18139,6 +18152,9 @@ monodll_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(MONODLL_ODEP)
@COND_USE_GUI_1@monodll_paper.o: $(srcdir)/src/common/paper.cpp $(MONODLL_ODEP)
@COND_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/common/paper.cpp
+@COND_USE_GUI_1@monodll_persist.o: $(srcdir)/src/common/persist.cpp $(MONODLL_ODEP)
+@COND_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/common/persist.cpp
+
@COND_USE_GUI_1@monodll_pickerbase.o: $(srcdir)/src/common/pickerbase.cpp $(MONODLL_ODEP)
@COND_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/common/pickerbase.cpp
@@ -22807,6 +22823,9 @@ monolib_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(MONOLIB_ODEP)
@COND_USE_GUI_1@monolib_paper.o: $(srcdir)/src/common/paper.cpp $(MONOLIB_ODEP)
@COND_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/common/paper.cpp
+@COND_USE_GUI_1@monolib_persist.o: $(srcdir)/src/common/persist.cpp $(MONOLIB_ODEP)
+@COND_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/common/persist.cpp
+
@COND_USE_GUI_1@monolib_pickerbase.o: $(srcdir)/src/common/pickerbase.cpp $(MONOLIB_ODEP)
@COND_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/common/pickerbase.cpp
@@ -27658,6 +27677,9 @@ coredll_win32.o: $(srcdir)/src/univ/themes/win32.cpp $(COREDLL_ODEP)
@COND_USE_GUI_1@coredll_paper.o: $(srcdir)/src/common/paper.cpp $(COREDLL_ODEP)
@COND_USE_GUI_1@ $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/common/paper.cpp
+@COND_USE_GUI_1@coredll_persist.o: $(srcdir)/src/common/persist.cpp $(COREDLL_ODEP)
+@COND_USE_GUI_1@ $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/common/persist.cpp
+
@COND_USE_GUI_1@coredll_pickerbase.o: $(srcdir)/src/common/pickerbase.cpp $(COREDLL_ODEP)
@COND_USE_GUI_1@ $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/common/pickerbase.cpp
@@ -31156,6 +31178,9 @@ corelib_win32.o: $(srcdir)/src/univ/themes/win32.cpp $(CORELIB_ODEP)
@COND_USE_GUI_1@corelib_paper.o: $(srcdir)/src/common/paper.cpp $(CORELIB_ODEP)
@COND_USE_GUI_1@ $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/common/paper.cpp
+@COND_USE_GUI_1@corelib_persist.o: $(srcdir)/src/common/persist.cpp $(CORELIB_ODEP)
+@COND_USE_GUI_1@ $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/common/persist.cpp
+
@COND_USE_GUI_1@corelib_pickerbase.o: $(srcdir)/src/common/pickerbase.cpp $(CORELIB_ODEP)
@COND_USE_GUI_1@ $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/common/pickerbase.cpp
diff --git a/build/bakefiles/files.bkl b/build/bakefiles/files.bkl
index 9db7573006..ce89734eec 100644
--- a/build/bakefiles/files.bkl
+++ b/build/bakefiles/files.bkl
@@ -678,6 +678,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file!
src/common/nbkbase.cpp
src/common/overlaycmn.cpp
src/common/paper.cpp
+ src/common/persist.cpp
src/common/pickerbase.cpp
src/common/popupcmn.cpp
src/common/prntbase.cpp
@@ -906,6 +907,11 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file!
wx/notebook.h
wx/ownerdrw.h
wx/paper.h
+ wx/persist.h
+ wx/persist/bookctrl.h
+ wx/persist/toplevel.h
+ wx/persist/treebook.h
+ wx/persist/window.h
wx/pickerbase.h
wx/popupwin.h
wx/print.h
diff --git a/build/msw/makefile.bcc b/build/msw/makefile.bcc
index ebda828d89..51e1c44a7c 100644
--- a/build/msw/makefile.bcc
+++ b/build/msw/makefile.bcc
@@ -1704,6 +1704,7 @@ ____CORE_SRC_FILENAMES_OBJECTS = \
$(OBJS)\monodll_nbkbase.obj \
$(OBJS)\monodll_overlaycmn.obj \
$(OBJS)\monodll_paper.obj \
+ $(OBJS)\monodll_persist.obj \
$(OBJS)\monodll_pickerbase.obj \
$(OBJS)\monodll_popupcmn.obj \
$(OBJS)\monodll_prntbase.obj \
@@ -1942,6 +1943,7 @@ ____CORE_SRC_FILENAMES_OBJECTS = \
$(OBJS)\monodll_nbkbase.obj \
$(OBJS)\monodll_overlaycmn.obj \
$(OBJS)\monodll_paper.obj \
+ $(OBJS)\monodll_persist.obj \
$(OBJS)\monodll_pickerbase.obj \
$(OBJS)\monodll_popupcmn.obj \
$(OBJS)\monodll_prntbase.obj \
@@ -2384,6 +2386,7 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \
$(OBJS)\monolib_nbkbase.obj \
$(OBJS)\monolib_overlaycmn.obj \
$(OBJS)\monolib_paper.obj \
+ $(OBJS)\monolib_persist.obj \
$(OBJS)\monolib_pickerbase.obj \
$(OBJS)\monolib_popupcmn.obj \
$(OBJS)\monolib_prntbase.obj \
@@ -2622,6 +2625,7 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \
$(OBJS)\monolib_nbkbase.obj \
$(OBJS)\monolib_overlaycmn.obj \
$(OBJS)\monolib_paper.obj \
+ $(OBJS)\monolib_persist.obj \
$(OBJS)\monolib_pickerbase.obj \
$(OBJS)\monolib_popupcmn.obj \
$(OBJS)\monolib_prntbase.obj \
@@ -2969,6 +2973,7 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \
$(OBJS)\coredll_nbkbase.obj \
$(OBJS)\coredll_overlaycmn.obj \
$(OBJS)\coredll_paper.obj \
+ $(OBJS)\coredll_persist.obj \
$(OBJS)\coredll_pickerbase.obj \
$(OBJS)\coredll_popupcmn.obj \
$(OBJS)\coredll_prntbase.obj \
@@ -3207,6 +3212,7 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \
$(OBJS)\coredll_nbkbase.obj \
$(OBJS)\coredll_overlaycmn.obj \
$(OBJS)\coredll_paper.obj \
+ $(OBJS)\coredll_persist.obj \
$(OBJS)\coredll_pickerbase.obj \
$(OBJS)\coredll_popupcmn.obj \
$(OBJS)\coredll_prntbase.obj \
@@ -3451,6 +3457,7 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \
$(OBJS)\corelib_nbkbase.obj \
$(OBJS)\corelib_overlaycmn.obj \
$(OBJS)\corelib_paper.obj \
+ $(OBJS)\corelib_persist.obj \
$(OBJS)\corelib_pickerbase.obj \
$(OBJS)\corelib_popupcmn.obj \
$(OBJS)\corelib_prntbase.obj \
@@ -3689,6 +3696,7 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \
$(OBJS)\corelib_nbkbase.obj \
$(OBJS)\corelib_overlaycmn.obj \
$(OBJS)\corelib_paper.obj \
+ $(OBJS)\corelib_persist.obj \
$(OBJS)\corelib_pickerbase.obj \
$(OBJS)\corelib_popupcmn.obj \
$(OBJS)\corelib_prntbase.obj \
@@ -7146,6 +7154,11 @@ $(OBJS)\monodll_paper.obj: ..\..\src\common\paper.cpp
$(CXX) -q -c -P -o$@ $(MONODLL_CXXFLAGS) ..\..\src\common\paper.cpp
!endif
+!if "$(USE_GUI)" == "1"
+$(OBJS)\monodll_persist.obj: ..\..\src\common\persist.cpp
+ $(CXX) -q -c -P -o$@ $(MONODLL_CXXFLAGS) ..\..\src\common\persist.cpp
+!endif
+
!if "$(USE_GUI)" == "1"
$(OBJS)\monodll_pickerbase.obj: ..\..\src\common\pickerbase.cpp
$(CXX) -q -c -P -o$@ $(MONODLL_CXXFLAGS) ..\..\src\common\pickerbase.cpp
@@ -9364,6 +9377,11 @@ $(OBJS)\monolib_paper.obj: ..\..\src\common\paper.cpp
$(CXX) -q -c -P -o$@ $(MONOLIB_CXXFLAGS) ..\..\src\common\paper.cpp
!endif
+!if "$(USE_GUI)" == "1"
+$(OBJS)\monolib_persist.obj: ..\..\src\common\persist.cpp
+ $(CXX) -q -c -P -o$@ $(MONOLIB_CXXFLAGS) ..\..\src\common\persist.cpp
+!endif
+
!if "$(USE_GUI)" == "1"
$(OBJS)\monolib_pickerbase.obj: ..\..\src\common\pickerbase.cpp
$(CXX) -q -c -P -o$@ $(MONOLIB_CXXFLAGS) ..\..\src\common\pickerbase.cpp
@@ -11603,6 +11621,11 @@ $(OBJS)\coredll_paper.obj: ..\..\src\common\paper.cpp
$(CXX) -q -c -P -o$@ $(COREDLL_CXXFLAGS) ..\..\src\common\paper.cpp
!endif
+!if "$(USE_GUI)" == "1"
+$(OBJS)\coredll_persist.obj: ..\..\src\common\persist.cpp
+ $(CXX) -q -c -P -o$@ $(COREDLL_CXXFLAGS) ..\..\src\common\persist.cpp
+!endif
+
!if "$(USE_GUI)" == "1"
$(OBJS)\coredll_pickerbase.obj: ..\..\src\common\pickerbase.cpp
$(CXX) -q -c -P -o$@ $(COREDLL_CXXFLAGS) ..\..\src\common\pickerbase.cpp
@@ -12972,6 +12995,11 @@ $(OBJS)\corelib_paper.obj: ..\..\src\common\paper.cpp
$(CXX) -q -c -P -o$@ $(CORELIB_CXXFLAGS) ..\..\src\common\paper.cpp
!endif
+!if "$(USE_GUI)" == "1"
+$(OBJS)\corelib_persist.obj: ..\..\src\common\persist.cpp
+ $(CXX) -q -c -P -o$@ $(CORELIB_CXXFLAGS) ..\..\src\common\persist.cpp
+!endif
+
!if "$(USE_GUI)" == "1"
$(OBJS)\corelib_pickerbase.obj: ..\..\src\common\pickerbase.cpp
$(CXX) -q -c -P -o$@ $(CORELIB_CXXFLAGS) ..\..\src\common\pickerbase.cpp
diff --git a/build/msw/makefile.gcc b/build/msw/makefile.gcc
index e23b144a54..e13fc07a71 100644
--- a/build/msw/makefile.gcc
+++ b/build/msw/makefile.gcc
@@ -1722,6 +1722,7 @@ ____CORE_SRC_FILENAMES_OBJECTS = \
$(OBJS)\monodll_nbkbase.o \
$(OBJS)\monodll_overlaycmn.o \
$(OBJS)\monodll_paper.o \
+ $(OBJS)\monodll_persist.o \
$(OBJS)\monodll_pickerbase.o \
$(OBJS)\monodll_popupcmn.o \
$(OBJS)\monodll_prntbase.o \
@@ -1962,6 +1963,7 @@ ____CORE_SRC_FILENAMES_OBJECTS = \
$(OBJS)\monodll_nbkbase.o \
$(OBJS)\monodll_overlaycmn.o \
$(OBJS)\monodll_paper.o \
+ $(OBJS)\monodll_persist.o \
$(OBJS)\monodll_pickerbase.o \
$(OBJS)\monodll_popupcmn.o \
$(OBJS)\monodll_prntbase.o \
@@ -2408,6 +2410,7 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \
$(OBJS)\monolib_nbkbase.o \
$(OBJS)\monolib_overlaycmn.o \
$(OBJS)\monolib_paper.o \
+ $(OBJS)\monolib_persist.o \
$(OBJS)\monolib_pickerbase.o \
$(OBJS)\monolib_popupcmn.o \
$(OBJS)\monolib_prntbase.o \
@@ -2648,6 +2651,7 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \
$(OBJS)\monolib_nbkbase.o \
$(OBJS)\monolib_overlaycmn.o \
$(OBJS)\monolib_paper.o \
+ $(OBJS)\monolib_persist.o \
$(OBJS)\monolib_pickerbase.o \
$(OBJS)\monolib_popupcmn.o \
$(OBJS)\monolib_prntbase.o \
@@ -3009,6 +3013,7 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \
$(OBJS)\coredll_nbkbase.o \
$(OBJS)\coredll_overlaycmn.o \
$(OBJS)\coredll_paper.o \
+ $(OBJS)\coredll_persist.o \
$(OBJS)\coredll_pickerbase.o \
$(OBJS)\coredll_popupcmn.o \
$(OBJS)\coredll_prntbase.o \
@@ -3249,6 +3254,7 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \
$(OBJS)\coredll_nbkbase.o \
$(OBJS)\coredll_overlaycmn.o \
$(OBJS)\coredll_paper.o \
+ $(OBJS)\coredll_persist.o \
$(OBJS)\coredll_pickerbase.o \
$(OBJS)\coredll_popupcmn.o \
$(OBJS)\coredll_prntbase.o \
@@ -3499,6 +3505,7 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \
$(OBJS)\corelib_nbkbase.o \
$(OBJS)\corelib_overlaycmn.o \
$(OBJS)\corelib_paper.o \
+ $(OBJS)\corelib_persist.o \
$(OBJS)\corelib_pickerbase.o \
$(OBJS)\corelib_popupcmn.o \
$(OBJS)\corelib_prntbase.o \
@@ -3739,6 +3746,7 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \
$(OBJS)\corelib_nbkbase.o \
$(OBJS)\corelib_overlaycmn.o \
$(OBJS)\corelib_paper.o \
+ $(OBJS)\corelib_persist.o \
$(OBJS)\corelib_pickerbase.o \
$(OBJS)\corelib_popupcmn.o \
$(OBJS)\corelib_prntbase.o \
@@ -7410,6 +7418,11 @@ $(OBJS)\monodll_paper.o: ../../src/common/paper.cpp
$(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $<
endif
+ifeq ($(USE_GUI),1)
+$(OBJS)\monodll_persist.o: ../../src/common/persist.cpp
+ $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $<
+endif
+
ifeq ($(USE_GUI),1)
$(OBJS)\monodll_pickerbase.o: ../../src/common/pickerbase.cpp
$(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $<
@@ -9742,6 +9755,11 @@ $(OBJS)\monolib_paper.o: ../../src/common/paper.cpp
$(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $<
endif
+ifeq ($(USE_GUI),1)
+$(OBJS)\monolib_persist.o: ../../src/common/persist.cpp
+ $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $<
+endif
+
ifeq ($(USE_GUI),1)
$(OBJS)\monolib_pickerbase.o: ../../src/common/pickerbase.cpp
$(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $<
@@ -12095,6 +12113,11 @@ $(OBJS)\coredll_paper.o: ../../src/common/paper.cpp
$(CXX) -c -o $@ $(COREDLL_CXXFLAGS) $(CPPDEPS) $<
endif
+ifeq ($(USE_GUI),1)
+$(OBJS)\coredll_persist.o: ../../src/common/persist.cpp
+ $(CXX) -c -o $@ $(COREDLL_CXXFLAGS) $(CPPDEPS) $<
+endif
+
ifeq ($(USE_GUI),1)
$(OBJS)\coredll_pickerbase.o: ../../src/common/pickerbase.cpp
$(CXX) -c -o $@ $(COREDLL_CXXFLAGS) $(CPPDEPS) $<
@@ -13576,6 +13599,11 @@ $(OBJS)\corelib_paper.o: ../../src/common/paper.cpp
$(CXX) -c -o $@ $(CORELIB_CXXFLAGS) $(CPPDEPS) $<
endif
+ifeq ($(USE_GUI),1)
+$(OBJS)\corelib_persist.o: ../../src/common/persist.cpp
+ $(CXX) -c -o $@ $(CORELIB_CXXFLAGS) $(CPPDEPS) $<
+endif
+
ifeq ($(USE_GUI),1)
$(OBJS)\corelib_pickerbase.o: ../../src/common/pickerbase.cpp
$(CXX) -c -o $@ $(CORELIB_CXXFLAGS) $(CPPDEPS) $<
diff --git a/build/msw/makefile.vc b/build/msw/makefile.vc
index 4da5672d5c..d51a4fbd0c 100644
--- a/build/msw/makefile.vc
+++ b/build/msw/makefile.vc
@@ -1884,6 +1884,7 @@ ____CORE_SRC_FILENAMES_OBJECTS = \
$(OBJS)\monodll_nbkbase.obj \
$(OBJS)\monodll_overlaycmn.obj \
$(OBJS)\monodll_paper.obj \
+ $(OBJS)\monodll_persist.obj \
$(OBJS)\monodll_pickerbase.obj \
$(OBJS)\monodll_popupcmn.obj \
$(OBJS)\monodll_prntbase.obj \
@@ -2122,6 +2123,7 @@ ____CORE_SRC_FILENAMES_OBJECTS = \
$(OBJS)\monodll_nbkbase.obj \
$(OBJS)\monodll_overlaycmn.obj \
$(OBJS)\monodll_paper.obj \
+ $(OBJS)\monodll_persist.obj \
$(OBJS)\monodll_pickerbase.obj \
$(OBJS)\monodll_popupcmn.obj \
$(OBJS)\monodll_prntbase.obj \
@@ -2570,6 +2572,7 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \
$(OBJS)\monolib_nbkbase.obj \
$(OBJS)\monolib_overlaycmn.obj \
$(OBJS)\monolib_paper.obj \
+ $(OBJS)\monolib_persist.obj \
$(OBJS)\monolib_pickerbase.obj \
$(OBJS)\monolib_popupcmn.obj \
$(OBJS)\monolib_prntbase.obj \
@@ -2808,6 +2811,7 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \
$(OBJS)\monolib_nbkbase.obj \
$(OBJS)\monolib_overlaycmn.obj \
$(OBJS)\monolib_paper.obj \
+ $(OBJS)\monolib_persist.obj \
$(OBJS)\monolib_pickerbase.obj \
$(OBJS)\monolib_popupcmn.obj \
$(OBJS)\monolib_prntbase.obj \
@@ -3185,6 +3189,7 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \
$(OBJS)\coredll_nbkbase.obj \
$(OBJS)\coredll_overlaycmn.obj \
$(OBJS)\coredll_paper.obj \
+ $(OBJS)\coredll_persist.obj \
$(OBJS)\coredll_pickerbase.obj \
$(OBJS)\coredll_popupcmn.obj \
$(OBJS)\coredll_prntbase.obj \
@@ -3423,6 +3428,7 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \
$(OBJS)\coredll_nbkbase.obj \
$(OBJS)\coredll_overlaycmn.obj \
$(OBJS)\coredll_paper.obj \
+ $(OBJS)\coredll_persist.obj \
$(OBJS)\coredll_pickerbase.obj \
$(OBJS)\coredll_popupcmn.obj \
$(OBJS)\coredll_prntbase.obj \
@@ -3673,6 +3679,7 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \
$(OBJS)\corelib_nbkbase.obj \
$(OBJS)\corelib_overlaycmn.obj \
$(OBJS)\corelib_paper.obj \
+ $(OBJS)\corelib_persist.obj \
$(OBJS)\corelib_pickerbase.obj \
$(OBJS)\corelib_popupcmn.obj \
$(OBJS)\corelib_prntbase.obj \
@@ -3911,6 +3918,7 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \
$(OBJS)\corelib_nbkbase.obj \
$(OBJS)\corelib_overlaycmn.obj \
$(OBJS)\corelib_paper.obj \
+ $(OBJS)\corelib_persist.obj \
$(OBJS)\corelib_pickerbase.obj \
$(OBJS)\corelib_popupcmn.obj \
$(OBJS)\corelib_prntbase.obj \
@@ -7492,6 +7500,11 @@ $(OBJS)\monodll_paper.obj: ..\..\src\common\paper.cpp
$(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\common\paper.cpp
!endif
+!if "$(USE_GUI)" == "1"
+$(OBJS)\monodll_persist.obj: ..\..\src\common\persist.cpp
+ $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\common\persist.cpp
+!endif
+
!if "$(USE_GUI)" == "1"
$(OBJS)\monodll_pickerbase.obj: ..\..\src\common\pickerbase.cpp
$(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\common\pickerbase.cpp
@@ -9710,6 +9723,11 @@ $(OBJS)\monolib_paper.obj: ..\..\src\common\paper.cpp
$(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\common\paper.cpp
!endif
+!if "$(USE_GUI)" == "1"
+$(OBJS)\monolib_persist.obj: ..\..\src\common\persist.cpp
+ $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\common\persist.cpp
+!endif
+
!if "$(USE_GUI)" == "1"
$(OBJS)\monolib_pickerbase.obj: ..\..\src\common\pickerbase.cpp
$(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\common\pickerbase.cpp
@@ -11949,6 +11967,11 @@ $(OBJS)\coredll_paper.obj: ..\..\src\common\paper.cpp
$(CXX) /c /nologo /TP /Fo$@ $(COREDLL_CXXFLAGS) ..\..\src\common\paper.cpp
!endif
+!if "$(USE_GUI)" == "1"
+$(OBJS)\coredll_persist.obj: ..\..\src\common\persist.cpp
+ $(CXX) /c /nologo /TP /Fo$@ $(COREDLL_CXXFLAGS) ..\..\src\common\persist.cpp
+!endif
+
!if "$(USE_GUI)" == "1"
$(OBJS)\coredll_pickerbase.obj: ..\..\src\common\pickerbase.cpp
$(CXX) /c /nologo /TP /Fo$@ $(COREDLL_CXXFLAGS) ..\..\src\common\pickerbase.cpp
@@ -13318,6 +13341,11 @@ $(OBJS)\corelib_paper.obj: ..\..\src\common\paper.cpp
$(CXX) /c /nologo /TP /Fo$@ $(CORELIB_CXXFLAGS) ..\..\src\common\paper.cpp
!endif
+!if "$(USE_GUI)" == "1"
+$(OBJS)\corelib_persist.obj: ..\..\src\common\persist.cpp
+ $(CXX) /c /nologo /TP /Fo$@ $(CORELIB_CXXFLAGS) ..\..\src\common\persist.cpp
+!endif
+
!if "$(USE_GUI)" == "1"
$(OBJS)\corelib_pickerbase.obj: ..\..\src\common\pickerbase.cpp
$(CXX) /c /nologo /TP /Fo$@ $(CORELIB_CXXFLAGS) ..\..\src\common\pickerbase.cpp
diff --git a/build/msw/makefile.wat b/build/msw/makefile.wat
index 082784a063..6527a430d9 100644
--- a/build/msw/makefile.wat
+++ b/build/msw/makefile.wat
@@ -399,6 +399,7 @@ ____CORE_SRC_FILENAMES_OBJECTS = &
$(OBJS)\monodll_nbkbase.obj &
$(OBJS)\monodll_overlaycmn.obj &
$(OBJS)\monodll_paper.obj &
+ $(OBJS)\monodll_persist.obj &
$(OBJS)\monodll_pickerbase.obj &
$(OBJS)\monodll_popupcmn.obj &
$(OBJS)\monodll_prntbase.obj &
@@ -639,6 +640,7 @@ ____CORE_SRC_FILENAMES_OBJECTS = &
$(OBJS)\monodll_nbkbase.obj &
$(OBJS)\monodll_overlaycmn.obj &
$(OBJS)\monodll_paper.obj &
+ $(OBJS)\monodll_persist.obj &
$(OBJS)\monodll_pickerbase.obj &
$(OBJS)\monodll_popupcmn.obj &
$(OBJS)\monodll_prntbase.obj &
@@ -1090,6 +1092,7 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = &
$(OBJS)\monolib_nbkbase.obj &
$(OBJS)\monolib_overlaycmn.obj &
$(OBJS)\monolib_paper.obj &
+ $(OBJS)\monolib_persist.obj &
$(OBJS)\monolib_pickerbase.obj &
$(OBJS)\monolib_popupcmn.obj &
$(OBJS)\monolib_prntbase.obj &
@@ -1330,6 +1333,7 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = &
$(OBJS)\monolib_nbkbase.obj &
$(OBJS)\monolib_overlaycmn.obj &
$(OBJS)\monolib_paper.obj &
+ $(OBJS)\monolib_persist.obj &
$(OBJS)\monolib_pickerbase.obj &
$(OBJS)\monolib_popupcmn.obj &
$(OBJS)\monolib_prntbase.obj &
@@ -1702,6 +1706,7 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = &
$(OBJS)\coredll_nbkbase.obj &
$(OBJS)\coredll_overlaycmn.obj &
$(OBJS)\coredll_paper.obj &
+ $(OBJS)\coredll_persist.obj &
$(OBJS)\coredll_pickerbase.obj &
$(OBJS)\coredll_popupcmn.obj &
$(OBJS)\coredll_prntbase.obj &
@@ -1942,6 +1947,7 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = &
$(OBJS)\coredll_nbkbase.obj &
$(OBJS)\coredll_overlaycmn.obj &
$(OBJS)\coredll_paper.obj &
+ $(OBJS)\coredll_persist.obj &
$(OBJS)\coredll_pickerbase.obj &
$(OBJS)\coredll_popupcmn.obj &
$(OBJS)\coredll_prntbase.obj &
@@ -2194,6 +2200,7 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = &
$(OBJS)\corelib_nbkbase.obj &
$(OBJS)\corelib_overlaycmn.obj &
$(OBJS)\corelib_paper.obj &
+ $(OBJS)\corelib_persist.obj &
$(OBJS)\corelib_pickerbase.obj &
$(OBJS)\corelib_popupcmn.obj &
$(OBJS)\corelib_prntbase.obj &
@@ -2434,6 +2441,7 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = &
$(OBJS)\corelib_nbkbase.obj &
$(OBJS)\corelib_overlaycmn.obj &
$(OBJS)\corelib_paper.obj &
+ $(OBJS)\corelib_persist.obj &
$(OBJS)\corelib_pickerbase.obj &
$(OBJS)\corelib_popupcmn.obj &
$(OBJS)\corelib_prntbase.obj &
@@ -7655,6 +7663,11 @@ $(OBJS)\monodll_paper.obj : .AUTODEPEND ..\..\src\common\paper.cpp
$(CXX) -bt=nt -zq -fo=$^@ $(MONODLL_CXXFLAGS) $<
!endif
+!ifeq USE_GUI 1
+$(OBJS)\monodll_persist.obj : .AUTODEPEND ..\..\src\common\persist.cpp
+ $(CXX) -bt=nt -zq -fo=$^@ $(MONODLL_CXXFLAGS) $<
+!endif
+
!ifeq USE_GUI 1
$(OBJS)\monodll_pickerbase.obj : .AUTODEPEND ..\..\src\common\pickerbase.cpp
$(CXX) -bt=nt -zq -fo=$^@ $(MONODLL_CXXFLAGS) $<
@@ -9987,6 +10000,11 @@ $(OBJS)\monolib_paper.obj : .AUTODEPEND ..\..\src\common\paper.cpp
$(CXX) -bt=nt -zq -fo=$^@ $(MONOLIB_CXXFLAGS) $<
!endif
+!ifeq USE_GUI 1
+$(OBJS)\monolib_persist.obj : .AUTODEPEND ..\..\src\common\persist.cpp
+ $(CXX) -bt=nt -zq -fo=$^@ $(MONOLIB_CXXFLAGS) $<
+!endif
+
!ifeq USE_GUI 1
$(OBJS)\monolib_pickerbase.obj : .AUTODEPEND ..\..\src\common\pickerbase.cpp
$(CXX) -bt=nt -zq -fo=$^@ $(MONOLIB_CXXFLAGS) $<
@@ -12340,6 +12358,11 @@ $(OBJS)\coredll_paper.obj : .AUTODEPEND ..\..\src\common\paper.cpp
$(CXX) -bt=nt -zq -fo=$^@ $(COREDLL_CXXFLAGS) $<
!endif
+!ifeq USE_GUI 1
+$(OBJS)\coredll_persist.obj : .AUTODEPEND ..\..\src\common\persist.cpp
+ $(CXX) -bt=nt -zq -fo=$^@ $(COREDLL_CXXFLAGS) $<
+!endif
+
!ifeq USE_GUI 1
$(OBJS)\coredll_pickerbase.obj : .AUTODEPEND ..\..\src\common\pickerbase.cpp
$(CXX) -bt=nt -zq -fo=$^@ $(COREDLL_CXXFLAGS) $<
@@ -13821,6 +13844,11 @@ $(OBJS)\corelib_paper.obj : .AUTODEPEND ..\..\src\common\paper.cpp
$(CXX) -bt=nt -zq -fo=$^@ $(CORELIB_CXXFLAGS) $<
!endif
+!ifeq USE_GUI 1
+$(OBJS)\corelib_persist.obj : .AUTODEPEND ..\..\src\common\persist.cpp
+ $(CXX) -bt=nt -zq -fo=$^@ $(CORELIB_CXXFLAGS) $<
+!endif
+
!ifeq USE_GUI 1
$(OBJS)\corelib_pickerbase.obj : .AUTODEPEND ..\..\src\common\pickerbase.cpp
$(CXX) -bt=nt -zq -fo=$^@ $(CORELIB_CXXFLAGS) $<
diff --git a/build/msw/wx_core.dsp b/build/msw/wx_core.dsp
index 3701568184..245918092e 100644
--- a/build/msw/wx_core.dsp
+++ b/build/msw/wx_core.dsp
@@ -562,6 +562,10 @@ SOURCE=..\..\src\common\paper.cpp
# End Source File
# Begin Source File
+SOURCE=..\..\src\common\persist.cpp
+# End Source File
+# Begin Source File
+
SOURCE=..\..\src\common\pickerbase.cpp
# End Source File
# Begin Source File
@@ -5742,6 +5746,10 @@ SOURCE=..\..\include\wx\bmpcbox.h
# End Source File
# Begin Source File
+SOURCE=..\..\include\wx\persist\bookctrl.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\include\wx\bookctrl.h
# End Source File
# Begin Source File
@@ -6254,6 +6262,10 @@ SOURCE=..\..\include\wx\pen.h
# End Source File
# Begin Source File
+SOURCE=..\..\include\wx\persist.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\include\wx\pickerbase.h
# End Source File
# Begin Source File
@@ -6506,6 +6518,10 @@ SOURCE=..\..\include\wx\toplevel.h
# End Source File
# Begin Source File
+SOURCE=..\..\include\wx\persist\toplevel.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\include\wx\treebase.h
# End Source File
# Begin Source File
@@ -6514,6 +6530,10 @@ SOURCE=..\..\include\wx\treebook.h
# End Source File
# Begin Source File
+SOURCE=..\..\include\wx\persist\treebook.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\include\wx\treectrl.h
# End Source File
# Begin Source File
@@ -6550,6 +6570,10 @@ SOURCE=..\..\include\wx\window.h
# End Source File
# Begin Source File
+SOURCE=..\..\include\wx\persist\window.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\include\wx\windowid.h
# End Source File
# Begin Source File
diff --git a/build/msw/wx_vc7_core.vcproj b/build/msw/wx_vc7_core.vcproj
index 6c145c93b0..786f4ec1e5 100644
--- a/build/msw/wx_vc7_core.vcproj
+++ b/build/msw/wx_vc7_core.vcproj
@@ -801,6 +801,9 @@
+
+
@@ -3556,6 +3559,9 @@
+
+
@@ -3940,6 +3946,9 @@
+
+
@@ -4129,12 +4138,18 @@
+
+
+
+
@@ -4162,6 +4177,9 @@
+
+
diff --git a/build/msw/wx_vc8_core.vcproj b/build/msw/wx_vc8_core.vcproj
index 1ce1d73732..9d142e47de 100644
--- a/build/msw/wx_vc8_core.vcproj
+++ b/build/msw/wx_vc8_core.vcproj
@@ -1106,6 +1106,10 @@
RelativePath="..\..\src\common\paper.cpp"
>
+
+
@@ -4763,6 +4767,10 @@
RelativePath="..\..\include\wx\bmpcbox.h"
>
+
+
@@ -5275,6 +5283,10 @@
RelativePath="..\..\include\wx\pen.h"
>
+
+
@@ -5527,6 +5539,10 @@
RelativePath="..\..\include\wx\toplevel.h"
>
+
+
@@ -5535,6 +5551,10 @@
RelativePath="..\..\include\wx\treebook.h"
>
+
+
@@ -5571,6 +5591,10 @@
RelativePath="..\..\include\wx\window.h"
>
+
+
diff --git a/build/msw/wx_vc9_core.vcproj b/build/msw/wx_vc9_core.vcproj
index 37fbe587a3..d8b4318214 100644
--- a/build/msw/wx_vc9_core.vcproj
+++ b/build/msw/wx_vc9_core.vcproj
@@ -1102,6 +1102,10 @@
RelativePath="..\..\src\common\paper.cpp"
>
+
+
@@ -4759,6 +4763,10 @@
RelativePath="..\..\include\wx\bmpcbox.h"
>
+
+
@@ -5271,6 +5279,10 @@
RelativePath="..\..\include\wx\pen.h"
>
+
+
@@ -5523,6 +5535,10 @@
RelativePath="..\..\include\wx\toplevel.h"
>
+
+
@@ -5531,6 +5547,10 @@
RelativePath="..\..\include\wx\treebook.h"
>
+
+
@@ -5567,6 +5587,10 @@
RelativePath="..\..\include\wx\window.h"
>
+
+
diff --git a/docs/changes.txt b/docs/changes.txt
index 9bfdfdc586..62aa60f58c 100644
--- a/docs/changes.txt
+++ b/docs/changes.txt
@@ -280,6 +280,9 @@ Major new features in this release
welcome (and due to using the simple Doxygen syntax it is now easier than
ever to submit patches correcting them! :-)
+- Support for persistent objects automatically saving and restoring their state
+ was added.
+
2.9.0
-----
diff --git a/docs/doxygen/mainpages/topics.h b/docs/doxygen/mainpages/topics.h
index 4fc700a58a..f4b83b22a1 100644
--- a/docs/doxygen/mainpages/topics.h
+++ b/docs/doxygen/mainpages/topics.h
@@ -63,6 +63,7 @@ The following is a basic categorization of them:
@li @subpage overview_stream
@li @subpage overview_thread
@li @subpage overview_config
+@li @subpage overview_persistence
@li @subpage overview_fs
@li @subpage overview_resyntax
@li @subpage overview_archive
diff --git a/docs/doxygen/overviews/persistence.h b/docs/doxygen/overviews/persistence.h
new file mode 100644
index 0000000000..3b018a59eb
--- /dev/null
+++ b/docs/doxygen/overviews/persistence.h
@@ -0,0 +1,115 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name: docs/doxygen/overviews/persistence.h
+// Purpose: overview of persistent objects
+// Author: Vadim Zeitlin
+// Created: 2009-01-23
+// RCS-ID: $Id$
+// Copyright: (c) 2009 Vadim Zeitlin
+// Licence: wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+/**
+
+@page overview_persistence Persistent Objects Overview
+
+Persistent objects are simply the objects which automatically save their state
+when they are destroyed and restore it when they are recreated, even during
+another program invocation.
+
+Most often, persistent objects are, in fact, persistent windows as it is
+especially convenient to automatically restore the UI state when the program is
+restarted but an object of any class can be made persistent. Moreover,
+persistence is implemented in a non-intrusive way so that the original object
+class doesn't need to be modified at all in order to add support for saving and
+restoring its properties.
+
+The persistence framework involves
+ - wxPersistenceManager which all persistent objects register themselves with.
+ This class handles actual saving and restoring of persistent data as well as
+ various global aspects of persistence, e.g. it can be used to disable
+ restoring the saved data.
+ - wxPersistentObject is the base class for all persistent objects or, rather,
+ adaptors for the persistent objects as this class main purpose is to provide
+ the bridge between the original class -- which has no special persistence
+ support -- and wxPersistenceManager,
+ - wxPersistentWindow<> which derives from wxPersistentObject and implements some
+ of its methods using wxWindow-specific functionality. Notably,
+ wxPersistenceManager handles the destruction of persistent windows
+ automatically implicitly while it has to be done explicitly for the
+ arbitrary persistent objects.
+ - wxCreatePersistentObject() function which is used to create the
+ appropriate persistence adapter for the object.
+
+
+@section persistence_using Using Persistent Windows
+
+wxWidgets has built-in support for a (constantly growing) number of controls.
+Currently the following classes are supported:
+ - wxTopLevelWindow (and hence wxFrame and wxDialog)
+ - wxBookCtrlBase, i.e. wxNotebook, wxListbook, wxToolbook and wxChoicebook
+ - wxTreebook
+
+To automatically save and restore the properties of the windows of classes
+listed above you need to
+
+ -# Set a unique name for the window using wxWindow::SetName(): this step is
+ important as the name is used in the configuration file and so must be
+ unique among all windows of the same class.
+
+ -# Call wxPersistenceManager::Register() at any moment after creating the
+ window and then wxPersistenceManager::Restore() when the settings may be
+ restored (which can't be always done immediately, e.g. often the window
+ needs to be populated first). If settings can be restored immediately after
+ the window creation, as is often the case for wxTopLevelWindow, for
+ example, then wxPersistenceManager::RegisterAndRestore() can be used to do
+ both at once.
+
+ -# If you do not want the settings for the window to be saved (for example
+ the changes to the dialog size are usually not saved if the dialog was
+ cancelled), you need to call wxPersistenceManager::Unregister() manually.
+ Otherwise the settings will be automatically saved when the control itself
+ is destroyed.
+
+Example of using a notebook control which automatically remembers the last open
+page:
+@code
+ wxNotebook *book = new wxNotebook(parent, wxID_ANY);
+ book->SetName("MyBook"); // do not use the default name
+ book->AddPage(...);
+ book->AddPage(...);
+ book->AddPage(...);
+ if ( !wxPersistenceManager::RegisterAndRestore(book) )
+ {
+ // nothing was restored, so choose the default page ourselves
+ book->SetSelection(0);
+ }
+@endcode
+
+
+@section persistence_defining Defining Custom Persistent Windows
+
+User-defined classes can be easily integrated with wxPersistenceManager. To add
+support for your custom class @c MyWidget you just need to:
+
+ -# Define a new @c MyPersistentWidget class inheriting from
+ wxPersistentWindow.
+
+ -# Implement its pure virtual GetKind() method returning a unique string
+ identifying all @c MyWidget objects, typically something like @c "widget"
+
+ -# Implement its pure virtual Save() and Restore() methods to actually save
+ and restore the widget settings using wxPersistentObject::SaveValue() and
+ wxPersistentObject::RestoreValue() methods.
+
+ -# Define wxCreatePersistentObject() overload taking @c MyWidget * and
+ returning a new @c MyPersistentWidget object.
+
+If you want to add persistence support for a class not deriving from wxWindow,
+you need to derive @c MyPersistentWidget directly from wxPersistentObject and
+so implement its pure virtual wxPersistentObject::GetName() method too.
+Additionally, you must ensure that wxPersistenceManager::SaveAndUnregister() is
+called when your object is destroyed as this can be only done automatically for
+windows.
+
+ */
+
diff --git a/include/wx/persist.h b/include/wx/persist.h
new file mode 100644
index 0000000000..7e331b6480
--- /dev/null
+++ b/include/wx/persist.h
@@ -0,0 +1,222 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name: wx/persist.h
+// Purpose: common classes for persistence support
+// Author: Vadim Zeitlin
+// Created: 2009-01-18
+// RCS-ID: $Id: wxhead.h,v 1.10 2008-04-15 23:34:19 zeitlin Exp $
+// Copyright: (c) 2009 Vadim Zeitlin
+// Licence: wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _WX_PERSIST_H_
+#define _WX_PERSIST_H_
+
+#include "wx/string.h"
+#include "wx/hashmap.h"
+#include "wx/confbase.h"
+
+class wxPersistentObject;
+
+WX_DECLARE_VOIDPTR_HASH_MAP(wxPersistentObject *, wxPersistentObjectsMap);
+
+// ----------------------------------------------------------------------------
+// global functions
+// ----------------------------------------------------------------------------
+
+/*
+ We do _not_ declare this function as doing this would force us to specialize
+ it for the user classes deriving from the standard persistent classes.
+ However we do define overloads of wxCreatePersistentObject() for all the wx
+ classes which means that template wxPersistentObject::Restore() picks up the
+ right overload to use provided that the header defining the correct overload
+ is included before calling it. And a compilation error happens if this is
+ not done.
+
+template
+wxPersistentObject *wxCreatePersistentObject(T *obj);
+
+ */
+
+// ----------------------------------------------------------------------------
+// wxPersistenceManager: global aspects of persistent windows
+// ----------------------------------------------------------------------------
+
+class WXDLLIMPEXP_CORE wxPersistenceManager
+{
+public:
+ // accessor to the unique persistence manager object
+ static wxPersistenceManager& Get();
+
+
+ // globally disable restoring or saving the persistent properties (both are
+ // enabled by default)
+ bool DisableSaving() { m_doSave = false; }
+ bool DisableRestoring() { m_doRestore = false; }
+
+
+ // register an object with the manager: when using the first overload,
+ // wxCreatePersistentObject() must be specialized for this object class;
+ // with the second one the persistent adapter is created by the caller
+ //
+ // the object shouldn't be already registered with us
+ template
+ wxPersistentObject *Register(T *obj)
+ {
+ return Register(obj, wxCreatePersistentObject(obj));
+ }
+
+ wxPersistentObject *Register(void *obj, wxPersistentObject *po);
+
+ // check if the object is registered and return the associated
+ // wxPersistentObject if it is or NULL otherwise
+ wxPersistentObject *Find(void *obj) const;
+
+ // unregister the object, this is called by wxPersistentObject itself so
+ // there is usually no need to do it explicitly
+ //
+ // deletes the associated wxPersistentObject
+ void Unregister(void *obj);
+
+
+ // save/restore the state of an object
+ //
+ // these methods do nothing if DisableSaving/Restoring() was called
+ //
+ // Restore() returns true if the object state was really restored
+ void Save(void *obj);
+ bool Restore(void *obj);
+
+ // combines both Save() and Unregister() calls
+ void SaveAndUnregister(void *obj)
+ {
+ Save(obj);
+ Unregister(obj);
+ }
+
+ // combines both Register() and Restore() calls
+ template
+ bool RegisterAndRestore(T *obj)
+ {
+ return Register(obj) && Restore(obj);
+ }
+
+ bool RegisterAndRestore(void *obj, wxPersistentObject *po)
+ {
+ return Register(obj, po) && Restore(obj);
+ }
+
+
+ // methods used by the persistent objects to save and restore the data
+ //
+ // currently these methods simply use wxConfig::Get()
+ //
+ // TODO: make this customizable by allowing
+ // (a) specifying custom wxConfig object to use
+ // (b) allowing to use something else entirely
+ template
+ bool
+ SaveValue(const wxPersistentObject& who, const wxString& name, T value)
+ {
+ wxConfigBase * const conf = GetConfig();
+ if ( !conf )
+ return false;
+
+ return conf->Write(GetKey(who, name), value);
+ }
+
+ template
+ bool
+ RestoreValue(const wxPersistentObject& who, const wxString& name, T *value)
+ {
+ wxConfigBase * const conf = GetConfig();
+ if ( !conf )
+ return false;
+
+ return conf->Read(GetKey(who, name), value);
+ }
+
+private:
+ // ctor is private, use Get()
+ wxPersistenceManager()
+ {
+ m_doSave =
+ m_doRestore = true;
+ }
+
+ // helpers of Save/Restore(), will be customized later
+ wxConfigBase *GetConfig() const { return wxConfigBase::Get(); }
+ wxString GetKey(const wxPersistentObject& who, const wxString& name) const;
+
+
+ // map with the registered objects as keys and associated
+ // wxPersistentObjects as values
+ wxPersistentObjectsMap m_persistentObjects;
+
+ // true if we should restore/save the settings (it doesn't make much sense
+ // to use this class when both of them are false but setting one of them to
+ // false may make sense in some situations)
+ bool m_doSave,
+ m_doRestore;
+
+ DECLARE_NO_COPY_CLASS(wxPersistenceManager);
+};
+
+// ----------------------------------------------------------------------------
+// wxPersistentObject: ABC for anything persistent
+// ----------------------------------------------------------------------------
+
+class wxPersistentObject
+{
+public:
+ // ctor associates us with the object whose options we save/restore
+ wxPersistentObject(void *obj) : m_obj(obj) { }
+
+ // trivial but virtual dtor
+ virtual ~wxPersistentObject() { }
+
+
+ // methods used by wxPersistenceManager
+ // ------------------------------------
+
+ // save/restore the corresponding objects settings
+ //
+ // these methods shouldn't be used directly as they don't respect the
+ // global wxPersistenceManager::DisableSaving/Restoring() settings, use
+ // wxPersistenceManager methods with the same name instead
+ virtual void Save() const = 0;
+ virtual bool Restore() = 0;
+
+
+ // get the kind of the objects we correspond to, e.g. "Frame"
+ virtual wxString GetKind() const = 0;
+
+ // get the name of the object we correspond to, e.g. "Main"
+ virtual wxString GetName() const = 0;
+
+
+ // return the associated object
+ void *GetObject() const { return m_obj; }
+
+protected:
+ // wrappers for wxPersistenceManager methods which don't require passing
+ // "this" as the first parameter all the time
+ template
+ bool SaveValue(const wxString& name, T value) const
+ {
+ return wxPersistenceManager::Get().SaveValue(*this, name, value);
+ }
+
+ template
+ bool RestoreValue(const wxString& name, T *value)
+ {
+ return wxPersistenceManager::Get().RestoreValue(*this, name, value);
+ }
+
+private:
+ void * const m_obj;
+
+ DECLARE_NO_COPY_CLASS(wxPersistentObject)
+};
+
+#endif // _WX_PERSIST_H_
+
diff --git a/include/wx/persist/bookctrl.h b/include/wx/persist/bookctrl.h
new file mode 100644
index 0000000000..a7930486a8
--- /dev/null
+++ b/include/wx/persist/bookctrl.h
@@ -0,0 +1,67 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name: wx/persist/bookctrl.h
+// Purpose: persistence support for wxBookCtrl
+// Author: Vadim Zeitlin
+// Created: 2009-01-19
+// RCS-ID: $Id$
+// Copyright: (c) 2009 Vadim Zeitlin
+// Licence: wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _WX_PERSIST_BOOKCTRL_H_
+#define _WX_PERSIST_BOOKCTRL_H_
+
+#include "wx/persist/window.h"
+
+#include "wx/bookctrl.h"
+
+// ----------------------------------------------------------------------------
+// string constants used by wxPersistentBookCtrl
+// ----------------------------------------------------------------------------
+
+#define wxPERSIST_BOOK_KIND "Book"
+
+#define wxPERSIST_BOOK_SELECTION "Selection"
+
+// ----------------------------------------------------------------------------
+// wxPersistentBookCtrl: supports saving/restoring book control selection
+// ----------------------------------------------------------------------------
+
+class wxPersistentBookCtrl : public wxPersistentWindow
+{
+public:
+ wxPersistentBookCtrl(wxBookCtrlBase *book)
+ : wxPersistentWindow(book)
+ {
+ }
+
+ virtual void Save() const
+ {
+ SaveValue(wxPERSIST_BOOK_SELECTION, Get()->GetSelection());
+ }
+
+ virtual bool Restore()
+ {
+ long sel;
+ if ( RestoreValue(wxPERSIST_BOOK_SELECTION, &sel) )
+ {
+ wxBookCtrlBase * const book = Get();
+ if ( sel >= 0 && (unsigned)sel < book->GetPageCount() )
+ {
+ book->SetSelection(sel);
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ virtual wxString GetKind() const { return wxPERSIST_BOOK_KIND; }
+};
+
+inline wxPersistentObject *wxCreatePersistentObject(wxBookCtrlBase *book)
+{
+ return new wxPersistentBookCtrl(book);
+}
+
+#endif // _WX_PERSIST_BOOKCTRL_H_
diff --git a/include/wx/persist/toplevel.h b/include/wx/persist/toplevel.h
new file mode 100644
index 0000000000..9d6edda5d0
--- /dev/null
+++ b/include/wx/persist/toplevel.h
@@ -0,0 +1,129 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name: wx/persist/toplevel.h
+// Purpose: persistence support for wxTLW
+// Author: Vadim Zeitlin
+// Created: 2009-01-19
+// RCS-ID: $Id$
+// Copyright: (c) 2009 Vadim Zeitlin
+// Licence: wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _WX_PERSIST_TOPLEVEL_H_
+#define _WX_PERSIST_TOPLEVEL_H_
+
+#include "wx/persist/window.h"
+
+#include "wx/toplevel.h"
+#include "wx/display.h"
+
+// ----------------------------------------------------------------------------
+// string constants used by wxPersistentTLW
+// ----------------------------------------------------------------------------
+
+// we use just "Window" to keep configuration files and such short, there
+// should be no confusion with wxWindow itself as we don't have persistent
+// windows, just persistent controls which have their own specific kind strings
+#define wxPERSIST_TLW_KIND "Window"
+
+// names for various persistent options
+#define wxPERSIST_TLW_X "x"
+#define wxPERSIST_TLW_Y "y"
+#define wxPERSIST_TLW_W "w"
+#define wxPERSIST_TLW_H "h"
+
+#define wxPERSIST_TLW_MAXIMIZED "Maximized"
+#define wxPERSIST_TLW_ICONIZED "Iconized"
+
+// ----------------------------------------------------------------------------
+// wxPersistentTLW: supports saving/restoring window position and size as well
+// as maximized/iconized/restore state
+// ----------------------------------------------------------------------------
+
+class wxPersistentTLW : public wxPersistentWindow
+{
+public:
+ wxPersistentTLW(wxTopLevelWindow *tlw)
+ : wxPersistentWindow(tlw)
+ {
+ }
+
+ virtual void Save() const
+ {
+ const wxTopLevelWindow * const tlw = Get();
+
+ const wxPoint pos = tlw->GetScreenPosition();
+ SaveValue(wxPERSIST_TLW_X, pos.x);
+ SaveValue(wxPERSIST_TLW_Y, pos.y);
+
+ // notice that we use GetSize() here and not GetClientSize() because
+ // the latter doesn't return correct results for the minimized windows
+ // (at least not under Windows)
+ //
+ // of course, it shouldn't matter anyhow usually, the client size
+ // should be preserved as well unless the size of the decorations
+ // changed between the runs
+ const wxSize size = tlw->GetSize();
+ SaveValue(wxPERSIST_TLW_W, size.x);
+ SaveValue(wxPERSIST_TLW_H, size.y);
+
+ SaveValue(wxPERSIST_TLW_MAXIMIZED, tlw->IsMaximized());
+ SaveValue(wxPERSIST_TLW_ICONIZED, tlw->IsIconized());
+ }
+
+ virtual bool Restore()
+ {
+ wxTopLevelWindow * const tlw = Get();
+
+ long x wxDUMMY_INITIALIZE(-1),
+ y wxDUMMY_INITIALIZE(-1),
+ w wxDUMMY_INITIALIZE(-1),
+ h wxDUMMY_INITIALIZE(-1);
+ const bool hasPos = RestoreValue(wxPERSIST_TLW_X, &x) &&
+ RestoreValue(wxPERSIST_TLW_Y, &y);
+ const bool hasSize = RestoreValue(wxPERSIST_TLW_W, &w) &&
+ RestoreValue(wxPERSIST_TLW_H, &h);
+
+ if ( hasPos )
+ {
+ // to avoid making the window completely invisible if it had been
+ // shown on a monitor which was disconnected since the last run
+ // (this is pretty common for notebook with external displays)
+ //
+ // NB: we should allow window position to be (slightly) off screen,
+ // it's not uncommon to position the window so that its upper
+ // left corner has slightly negative coordinate
+ if ( wxDisplay::GetFromPoint(wxPoint(x, y)) != wxNOT_FOUND ||
+ (hasSize && wxDisplay::GetFromPoint(
+ wxPoint(x + w, y + h)) != wxNOT_FOUND) )
+ {
+ tlw->Move(x, y, wxSIZE_ALLOW_MINUS_ONE);
+ }
+ //else: should we try to adjust position/size somehow?
+ }
+
+ if ( hasSize )
+ tlw->SetSize(w, h);
+
+ // note that the window can be both maximized and iconized
+ bool maximized;
+ if ( RestoreValue(wxPERSIST_TLW_MAXIMIZED, &maximized) && maximized )
+ tlw->Maximize();
+
+ bool iconized;
+ if ( RestoreValue(wxPERSIST_TLW_ICONIZED, &iconized) && iconized )
+ tlw->Iconize();
+
+ // the most important property of the window that we restore is its
+ // size, so disregard the value of hasPos here
+ return hasSize;
+ }
+
+ virtual wxString GetKind() const { return wxPERSIST_TLW_KIND; }
+};
+
+inline wxPersistentObject *wxCreatePersistentObject(wxTopLevelWindow *tlw)
+{
+ return new wxPersistentTLW(tlw);
+}
+
+#endif // _WX_PERSIST_TOPLEVEL_H_
diff --git a/include/wx/persist/treebook.h b/include/wx/persist/treebook.h
new file mode 100644
index 0000000000..0d2fddb3a1
--- /dev/null
+++ b/include/wx/persist/treebook.h
@@ -0,0 +1,97 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name: wx/persist/treebook.h
+// Purpose: persistence support for wxBookCtrl
+// Author: Vadim Zeitlin
+// Created: 2009-01-19
+// RCS-ID: $Id$
+// Copyright: (c) 2009 Vadim Zeitlin
+// Licence: wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _WX_PERSIST_TREEBOOK_H_
+#define _WX_PERSIST_TREEBOOK_H_
+
+#include "wx/persist/bookctrl.h"
+
+#include "wx/arrstr.h"
+#include "wx/treebook.h"
+
+// ----------------------------------------------------------------------------
+// string constants used by wxPersistentTreeBookCtrl
+// ----------------------------------------------------------------------------
+
+#define wxPERSIST_TREEBOOK_KIND "TreeBook"
+
+// this key contains the indices of all expanded nodes in the tree book
+// separated by wxPERSIST_TREEBOOK_EXPANDED_SEP
+#define wxPERSIST_TREEBOOK_EXPANDED_BRANCHES "Expanded"
+#define wxPERSIST_TREEBOOK_EXPANDED_SEP ','
+
+// ----------------------------------------------------------------------------
+// wxPersistentTreeBookCtrl: supports saving/restoring open tree branches
+// ----------------------------------------------------------------------------
+
+class wxPersistentTreeBookCtrl : public wxPersistentBookCtrl
+{
+public:
+ wxPersistentTreeBookCtrl(wxTreebook *book)
+ : wxPersistentBookCtrl(book)
+ {
+ }
+
+ virtual void Save() const
+ {
+ const wxTreebook * const book = GetTreeBook();
+
+ wxString expanded;
+ const size_t count = book->GetPageCount();
+ for ( size_t n = 0; n < count; n++ )
+ {
+ if ( book->IsNodeExpanded(n) )
+ {
+ if ( !expanded.empty() )
+ expanded += wxPERSIST_TREEBOOK_EXPANDED_SEP;
+
+ expanded += wxString::Format("%u", static_cast(n));
+ }
+ }
+
+ SaveValue(wxPERSIST_TREEBOOK_EXPANDED_BRANCHES, expanded);
+
+ wxPersistentBookCtrl::Save();
+ }
+
+ virtual bool Restore()
+ {
+ wxTreebook * const book = GetTreeBook();
+
+ wxString expanded;
+ if ( RestoreValue(wxPERSIST_TREEBOOK_EXPANDED_BRANCHES, &expanded) )
+ {
+ const wxArrayString
+ indices(wxSplit(expanded, wxPERSIST_TREEBOOK_EXPANDED_SEP));
+
+ const size_t pageCount = book->GetPageCount();
+ const size_t count = indices.size();
+ for ( size_t n = 0; n < count; n++ )
+ {
+ unsigned long idx;
+ if ( indices[n].ToULong(&idx) && idx < pageCount )
+ book->ExpandNode(idx);
+ }
+ }
+
+ return wxPersistentBookCtrl::Restore();
+ }
+
+ virtual wxString GetKind() const { return wxPERSIST_TREEBOOK_KIND; }
+
+ wxTreebook *GetTreeBook() const { return static_cast(Get()); }
+};
+
+inline wxPersistentObject *wxCreatePersistentObject(wxTreebook *book)
+{
+ return new wxPersistentTreeBookCtrl(book);
+}
+
+#endif // _WX_PERSIST_TREEBOOK_H_
diff --git a/include/wx/persist/window.h b/include/wx/persist/window.h
new file mode 100644
index 0000000000..692e143a13
--- /dev/null
+++ b/include/wx/persist/window.h
@@ -0,0 +1,85 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name: wx/persist/window.h
+// Purpose: wxPersistentWindow declaration
+// Author: Vadim Zeitlin
+// Created: 2009-01-23
+// RCS-ID: $Id$
+// Copyright: (c) 2009 Vadim Zeitlin
+// Licence: wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _WX_PERSIST_WINDOW_H_
+#define _WX_PERSIST_WINDOW_H_
+
+#include "wx/persist.h"
+
+#include "wx/window.h"
+
+// ----------------------------------------------------------------------------
+// wxPersistentWindow: base class for persistent windows, uses the window name
+// as persistent name by default and automatically reacts
+// to the window destruction
+// ----------------------------------------------------------------------------
+
+// type-independent part of wxPersistentWindow
+class wxPersistentWindowBase :
+#if wxEVENTS_COMPATIBILITY_2_8
+ // in compatibility mode we need to derive from wxEvtHandler to be able to
+ // handle events
+ public wxEvtHandler ,
+#endif
+ public wxPersistentObject
+{
+public:
+ wxPersistentWindowBase(wxWindow *win)
+ : wxPersistentObject(win)
+ {
+ win->Connect
+ (
+ wxEVT_DESTROY,
+ wxWindowDestroyEventHandler(
+ wxPersistentWindowBase::HandleDestroy),
+ NULL,
+ this
+ );
+ }
+
+ virtual wxString GetName() const
+ {
+ const wxString name = GetWindow()->GetName();
+ wxASSERT_MSG( !name.empty(), "persistent windows should be named!" );
+
+ return name;
+ }
+
+protected:
+ wxWindow *GetWindow() const { return static_cast(GetObject()); }
+
+private:
+ void HandleDestroy(wxWindowDestroyEvent& event)
+ {
+ event.Skip();
+
+ // this will delete this object itself
+ wxPersistenceManager::Get().SaveAndUnregister(GetWindow());
+ }
+
+ DECLARE_NO_COPY_CLASS(wxPersistentWindowBase)
+};
+
+template
+class wxPersistentWindow : public wxPersistentWindowBase
+{
+public:
+ typedef T WindowType;
+
+ wxPersistentWindow(WindowType *win)
+ : wxPersistentWindowBase(win)
+ {
+ }
+
+ WindowType *Get() const { return static_cast(GetWindow()); }
+};
+
+#endif // _WX_PERSIST_WINDOW_H_
+
diff --git a/interface/wx/persist.h b/interface/wx/persist.h
new file mode 100644
index 0000000000..beae4c785f
--- /dev/null
+++ b/interface/wx/persist.h
@@ -0,0 +1,273 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name: wx/persist.h
+// Purpose: interface of wxPersistenceManager and related classes
+// Author: Vadim Zeitlin
+// RCS-ID: $Id$
+// Copyright: (c) 2009 Vadim Zeitlin
+// Licence: wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+/**
+ Provides support for automatically saving and restoring object properties
+ to persistent storage.
+
+ This class is the central element of wxWidgets persistence framework, see
+ @ref overview_persistence for its overview.
+
+ This is a singleton class and its unique instance can be retrieved using
+ Get() method.
+
+ @library{wxcore}
+ */
+class wxPersistenceManager
+{
+public:
+ /**
+ Returns the unique persistence manager object.
+ */
+ static wxPersistenceManager& Get();
+
+ /**
+ Globally disable saving the persistence object properties.
+
+ By default, saving properties in Save() is enabled but the program may
+ wish to disable if, for example, it detects that it is running on a
+ system which shouldn't be modified in any way and so configuration
+ file (or Windows registry) shouldn't be written to.
+
+ @see DisableRestoring()
+ */
+ bool DisableSaving();
+
+ /**
+ Globally disable restoring the persistence object properties.
+
+ By default, restoring properties in Restore() is enabled but this
+ function allows to disable it. This is mostly useful for testing.
+
+ @see DisableSaving()
+ */
+ bool DisableRestoring();
+
+
+ /**
+ Register an object with the manager automatically creating a
+ persistence adapter for it.
+
+ This is equivalent to calling Register(void *, wxPersistentObject *)
+ with wxCreatePersistentObject(obj) as the second argument.
+
+ @param obj
+ The object to register. wxCreatePersistentObject() overload must be
+ defined for the objects of this class.
+ */
+ template
+ wxPersistentObject *Register(T *obj)
+ {
+ return Register(obj, wxCreatePersistentObject(obj));
+ }
+
+ /**
+ Register an object with the manager.
+
+ Note that registering the object doesn't do anything except allowing to
+ call Restore() for it later. If you want to register the object and
+ restore its properties, use RegisterAndRestore().
+
+ The manager takes ownership of @a po and will delete it when it is
+ unregistered.
+
+ @param obj
+ The object to register.
+ @param po
+ The wxPersistentObject to use for saving and restoring this object
+ properties.
+ */
+ wxPersistentObject *Register(void *obj, wxPersistentObject *po);
+
+ /**
+ Check if the object is registered and return the associated
+ wxPersistentObject if it is or @NULL otherwise.
+ */
+ wxPersistentObject *Find(void *obj) const;
+
+ /**
+ Unregister the object and delete the associated wxPersistentObject.
+
+ For the persistent windows this is done automatically (via
+ SaveAndUnregister()) when the window is destroyed so you only need to
+ call this function explicitly if you are using custom persistent
+ objects or if you want to prevent the object properties from being
+ saved.
+
+ @param obj
+ An object previously registered with Register().
+ */
+ void Unregister(void *obj);
+
+
+ /**
+ Save the object properties to persistent storage.
+
+ This method does nothing if DisableSaving() had been called.
+
+ @param obj
+ An object previously registered with Register().
+
+ @see SaveAndUnregister()
+ */
+ void Save(void *obj);
+
+ /**
+ Restore the object properties previously saved by Save().
+
+ This method does nothing if DisableRestoring() had been called.
+
+ @param obj
+ An object previously registered with Register().
+ @return
+ @true if the object properties were restored or @false if nothing
+ was found to restore or the saved settings were invalid.
+
+ @see RegisterAndRestore()
+ */
+ bool Restore(void *obj);
+
+ /// Combines both Save() and Unregister() calls.
+ void SaveAndUnregister(void *obj);
+
+ /// Combines both Register() and Restore() calls.
+ //@{
+ template
+ bool RegisterAndRestore(T *obj);
+
+ bool RegisterAndRestore(void *obj, wxPersistentObject *po);
+ //@}
+};
+
+/**
+ Base class for persistent object adapters.
+
+ wxWidgets persistence framework is non-intrusive, i.e. can work with the
+ classes which have no relationship to nor knowledge of it. To allow this,
+ an intermediate persistence adapter is used: this is just a simple object
+ which provides the methods used by wxPersistenceManager to save and restore
+ the object properties and implements them using the concrete class methods.
+
+ You may derive your own classes from wxPersistentObject to implement
+ persistence support for your common classes, see @ref persistence_defining.
+
+ @see wxPersistentWindow<>
+ */
+class wxPersistentObject
+{
+public:
+ /**
+ Constructor takes the object which we're associated with.
+
+ This object must have life-time greater than ours as we keep a pointer
+ to it.
+ */
+ wxPersistentObject(void *obj);
+
+ /// Trivial but virtual destructor.
+ virtual ~wxPersistentObject();
+
+
+ /**
+ @name Methods to be implemented in the derived classes.
+
+ Notice that these methods are only used by wxPersistenceManager
+ normally and shouldn't be called directly.
+ */
+ //@{
+
+ /**
+ Save the object properties.
+
+ The implementation of this method should use SaveValue().
+ */
+ virtual void Save() const = 0;
+
+ /**
+ Restore the object properties.
+
+ The implementation of this method should use RestoreValue().
+ */
+ virtual bool Restore() = 0;
+
+
+ /**
+ Returns the string uniquely identifying the objects supported by this
+ adapter.
+
+ This method is called from SaveValue() and RestoreValue() and normally
+ returns some short (but not too cryptic) strings, e.g. @c "Checkbox".
+ */
+ virtual wxString GetKind() const = 0;
+
+ /**
+ Returns the string uniquely identifying the object we're associated
+ with among all the other objects of the same type.
+
+ This method is used together with GetKind() to construct the unique
+ full name of the object in e.g. a configuration file.
+ */
+ virtual wxString GetName() const = 0;
+
+ //@}
+
+
+ /// Return the associated object.
+ void *GetObject() const;
+
+protected:
+ /**
+ Save the specified value using the given name.
+
+ @param name
+ The name of the value in the configuration file.
+ @param value
+ The value to save, currently must be a type supported by wxConfig.
+ @return
+ @true if the value was saved or @false if an error occurred.
+ */
+ template
+ bool SaveValue(const wxString& name, T value) const
+ {
+ return wxPersistenceManager::Get().SaveValue(*this, name, value);
+ }
+
+ /**
+ Restore the value saved by Save().
+
+ @param name
+ The same name as was used by Save().
+ @param value
+ Non-@NULL pointer which will be filled with the value if it was
+ read successfully or not modified if it wasn't.
+ @return
+ @true if the value was successfully read or @false if it was not
+ found or an error occurred.
+ */
+ template
+ bool RestoreValue(const wxString& name, T *value)
+ {
+ return wxPersistenceManager::Get().RestoreValue(*this, name, value);
+ }
+};
+
+/**
+ Function used to create the correct persistent adapter for the given type
+ of objects.
+
+ To be precise, there is no such template function definition but there are
+ overloads of wxCreatePersistentObject() taking different object types for
+ all wxWidgets classes supporting persistence. And you may also define your
+ own overloads to integrate your custom classes with wxWidgets persistence
+ framework.
+
+ @see @ref persistence_defining
+ */
+template
+wxPersistentObject *wxCreatePersistentObject(T *obj);
diff --git a/interface/wx/persist/bookctrl.h b/interface/wx/persist/bookctrl.h
new file mode 100644
index 0000000000..b6fe21268c
--- /dev/null
+++ b/interface/wx/persist/bookctrl.h
@@ -0,0 +1,47 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name: wx/persist/bookctrl.h
+// Purpose: interface of wxPersistentBookCtrl
+// Author: Vadim Zeitlin
+// RCS-ID: $Id$
+// Copyright: (c) 2009 Vadim Zeitlin
+// Licence: wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+/**
+ Persistence adapter for wxBookCtrlBase.
+
+ This adapter handles the selected page of wxBookCtrlBase, i.e. it saves its
+ value when the associated book control is destroyed and restores it when it
+ is recreated.
+
+ @see wxPersistentTreeBookCtrl
+ */
+class wxPersistentBookCtrl : public wxPersistentWindow
+{
+public:
+ /**
+ Constructor.
+
+ @param book
+ The associated book control.
+ */
+ wxPersistentBookCtrl(wxBookCtrlBase *book);
+
+ /**
+ Save the currently selected page index.
+ */
+ virtual void Save() const;
+
+ /**
+ Restore the selected page index.
+
+ The book control must be initialized before calling this function, i.e.
+ all of its pages should be already added to it -- otherwise restoring
+ the selection has no effect.
+ */
+ virtual bool Restore();
+};
+
+/// Overload allowing persistence adapter creation for wxBookCtrlBase-derived
+/// objects.
+wxPersistentObject *wxCreatePersistentObject(wxBookCtrlBase *book);
diff --git a/interface/wx/persist/toplevel.h b/interface/wx/persist/toplevel.h
new file mode 100644
index 0000000000..eaffd2470e
--- /dev/null
+++ b/interface/wx/persist/toplevel.h
@@ -0,0 +1,43 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name: wx/persist/toplevel.h
+// Purpose: interface of wxPersistentTLW
+// Author: Vadim Zeitlin
+// RCS-ID: $Id$
+// Copyright: (c) 2009 Vadim Zeitlin
+// Licence: wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+/**
+ Persistence adapter for wxTopLevelWindow.
+
+ This adapter saves and restores the geometry (i.e. position and size) and
+ the state (iconized, maximized or normal) of top level windows. It can be
+ used with both wxFrame and wxDialog.
+
+ Note that it does @em not save nor restore the window visibility.
+ */
+class wxPersistentTLW : public wxPersistentWindow
+{
+public:
+ /**
+ Constructor.
+
+ @param book
+ The associated window.
+ */
+ wxPersistentTLW(wxTopLevelWindow *book);
+
+ /**
+ Save the current window geometry.
+ */
+ virtual void Save() const;
+
+ /**
+ Restore the window geometry.
+ */
+ virtual bool Restore();
+};
+
+/// Overload allowing persistence adapter creation for wxTopLevelWindow-derived
+/// objects.
+wxPersistentObject *wxCreatePersistentObject(wxTopLevelWindow *book);
diff --git a/interface/wx/persist/treebook.h b/interface/wx/persist/treebook.h
new file mode 100644
index 0000000000..28be96024e
--- /dev/null
+++ b/interface/wx/persist/treebook.h
@@ -0,0 +1,43 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name: wx/persist/treebook.h
+// Purpose: interface of wxPersistentTreeBook
+// Author: Vadim Zeitlin
+// RCS-ID: $Id$
+// Copyright: (c) 2009 Vadim Zeitlin
+// Licence: wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+/**
+ Persistence adapter for wxTreebook.
+
+ This adapter saves and restores the expanded branches of the wxTreeCtrl
+ used by wxTreebook, in addition to saving and restoring the selection as
+ implemented by the base wxPersistentBookCtrl class.
+ */
+class wxPersistentTreeBook : public wxPersistentBookCtrl
+{
+public:
+ /**
+ Constructor.
+
+ @param book
+ The associated tree book control.
+ */
+ wxPersistentTreeBook(wxTreebook *book);
+
+ /**
+ Save the currently opened branches.
+ */
+ virtual void Save() const;
+
+ /**
+ Restore the opened branches.
+
+ The book control must be initialized before calling this function, i.e.
+ all of its pages should be already added to it.
+ */
+ virtual bool Restore();
+};
+
+/// Overload allowing persistence adapter creation for wxTreebook objects.
+wxPersistentObject *wxCreatePersistentObject(wxTreebook *book);
diff --git a/interface/wx/persist/window.h b/interface/wx/persist/window.h
new file mode 100644
index 0000000000..6219c59d4f
--- /dev/null
+++ b/interface/wx/persist/window.h
@@ -0,0 +1,51 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name: wx/persist/window.h
+// Purpose: interface of wxPersistentWindow<>
+// Author: Vadim Zeitlin
+// RCS-ID: $Id$
+// Copyright: (c) 2009 Vadim Zeitlin
+// Licence: wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+/**
+ Base class for persistent windows.
+
+ Compared to wxPersistentObject this class does three things:
+ - Most importantly, wxPersistentWindow catches wxWindowDestroyEvent
+ generated when the window is destroyed and saves its properties
+ automatically when it happens.
+ - It implements GetName() using wxWindow::GetName() so that the derived
+ classes don't need to do it.
+ - It adds a convenient wxPersistentWindow::Get() accessor returning the
+ window object of the correct type.
+ */
+template
+class wxPersistentWindow : public wxPersistentObject
+{
+public:
+ /// The type of the associated window.
+ typedef T WindowType;
+
+ /**
+ Constructor for a persistent window object.
+
+ The constructor uses wxEvtHandler::Connect() to catch
+ wxWindowDestroyEvent generated when the window is destroyed and call
+ wxPersistenceManager::SaveAndUnregister() when this happens. This
+ ensures that the window properties are saved and that this object
+ itself is deleted when the window is.
+ */
+ wxPersistentWindow(WindowType *win);
+
+ WindowType *Get() const { return static_cast(GetWindow()); }
+ /**
+ Implements the base class pure virtual method using wxWindow::GetName().
+
+ Notice that window names are usually not unique while this function
+ must return a unique (at least among the objects of this type) string.
+ Because of this you need to specify a non-default window name in its
+ constructor when creating it or explicitly call wxWindow::SetName()
+ before saving or restoring persistent properties.
+ */
+ virtual wxString GetName() const;
+};
diff --git a/samples/widgets/widgets.cpp b/samples/widgets/widgets.cpp
index 71b3fb8872..a808a3a87f 100644
--- a/samples/widgets/widgets.cpp
+++ b/samples/widgets/widgets.cpp
@@ -51,6 +51,9 @@
#include "wx/imaglist.h"
#include "wx/wupdlock.h"
+#include "wx/persist/toplevel.h"
+#include "wx/persist/treebook.h"
+
#include "widgets.h"
#include "../sample.xpm"
@@ -325,6 +328,8 @@ bool WidgetsApp::OnInit()
if ( !wxApp::OnInit() )
return false;
+ SetVendorName("wxWidgets_Samples");
+
// the reason for having these ifdef's is that I often run two copies of
// this sample side by side and it is useful to see which one is which
wxString title;
@@ -351,10 +356,6 @@ bool WidgetsApp::OnInit()
wxFrame *frame = new WidgetsFrame(title + _T(" widgets demo"));
frame->Show();
- //wxLog::AddTraceMask(_T("listbox"));
- //wxLog::AddTraceMask(_T("scrollbar"));
- //wxLog::AddTraceMask(_T("focus"));
-
return true;
}
@@ -365,15 +366,18 @@ bool WidgetsApp::OnInit()
WidgetsFrame::WidgetsFrame(const wxString& title)
: wxFrame(NULL, wxID_ANY, title)
{
+ SetName("Main");
+ const bool sizeSet = wxPersistenceManager::Get().RegisterAndRestore(this);
+
// set the frame icon
SetIcon(wxICON(sample));
// init everything
#if USE_LOG
- m_lboxLog = (wxListBox *)NULL;
- m_logTarget = (wxLog *)NULL;
+ m_lboxLog = NULL;
+ m_logTarget = NULL;
#endif // USE_LOG
- m_book = (WidgetsBookCtrl *)NULL;
+ m_book = NULL;
#if wxUSE_MENUS
// create the menubar
@@ -435,13 +439,10 @@ WidgetsFrame::WidgetsFrame(const wxString& title)
// Uncomment to suppress page theme (draw in solid colour)
//style |= wxNB_NOPAGETHEME;
- m_book = new WidgetsBookCtrl(m_panel, Widgets_BookCtrl, wxDefaultPosition,
-#ifdef __WXMOTIF__
- wxSize(500, wxDefaultCoord), // under Motif, height is a function of the width...
-#else
- wxDefaultSize,
-#endif
- style);
+ m_book = new WidgetsBookCtrl(m_panel, Widgets_BookCtrl,
+ wxDefaultPosition, wxDefaultSize,
+ style, "Widgets");
+
InitBook();
#ifndef __WXHANDHELD__
@@ -482,7 +483,10 @@ WidgetsFrame::WidgetsFrame(const wxString& title)
m_panel->SetSizer(sizerTop);
- sizerTop->SetSizeHints(this);
+ const wxSize sizeMin = m_panel->GetBestSize();
+ if ( !sizeSet )
+ SetClientSize(sizeMin);
+ SetMinClientSize(sizeMin);
#if USE_LOG && !defined(__WXCOCOA__)
// wxCocoa's listbox is too flakey to use for logging right now
@@ -613,10 +617,13 @@ void WidgetsFrame::InitBook()
wxEVT_COMMAND_WIDGETS_PAGE_CHANGED,
wxWidgetsbookEventHandler(WidgetsFrame::OnPageChanged) );
+ const bool pageSet = wxPersistenceManager::Get().RegisterAndRestore(m_book);
+
#if USE_TREEBOOK
// for treebook page #0 is empty parent page only so select the first page
// with some contents
- m_book->SetSelection(1);
+ if ( !pageSet )
+ m_book->SetSelection(1);
// but ensure that the top of the tree is shown nevertheless
wxTreeCtrl * const tree = m_book->GetTreeCtrl();
@@ -624,10 +631,13 @@ void WidgetsFrame::InitBook()
wxTreeItemIdValue cookie;
tree->EnsureVisible(tree->GetFirstChild(tree->GetRootItem(), cookie));
#else
- // for other books set selection twice to force connected event handler
- // to force lazy creation of initial visible content
- m_book->SetSelection(1);
- m_book->SetSelection(0);
+ if ( !pageSet )
+ {
+ // for other books set selection twice to force connected event handler
+ // to force lazy creation of initial visible content
+ m_book->SetSelection(1);
+ m_book->SetSelection(0);
+ }
#endif // USE_TREEBOOK
}
diff --git a/src/common/persist.cpp b/src/common/persist.cpp
new file mode 100644
index 0000000000..80df492e5e
--- /dev/null
+++ b/src/common/persist.cpp
@@ -0,0 +1,109 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name: src/common/persist.cpp
+// Purpose: common persistence support classes
+// Author: Vadim Zeitlin
+// Created: 2009-01-20
+// RCS-ID: $Id$
+// Copyright: (c) 2009 Vadim Zeitlin
+// Licence: wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+// for compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+ #pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#endif // WX_PRECOMP
+
+#include "wx/persist.h"
+
+// ============================================================================
+// wxPersistenceManager implementation
+// ============================================================================
+
+/* static */
+wxPersistenceManager& wxPersistenceManager::Get()
+{
+ static wxPersistenceManager s_manager;
+
+ return s_manager;
+}
+
+wxString
+wxPersistenceManager::GetKey(const wxPersistentObject& who,
+ const wxString& name) const
+{
+ wxString key("Persistent_Options"); // TODO: make this configurable
+ key << wxCONFIG_PATH_SEPARATOR << who.GetKind()
+ << wxCONFIG_PATH_SEPARATOR << who.GetName()
+ << wxCONFIG_PATH_SEPARATOR << name;
+
+ return key;
+}
+
+wxPersistentObject *wxPersistenceManager::Find(void *obj) const
+{
+ const wxPersistentObjectsMap::const_iterator
+ it = m_persistentObjects.find(obj);
+ return it == m_persistentObjects.end() ? NULL : it->second;
+}
+
+wxPersistentObject *
+wxPersistenceManager::Register(void *obj, wxPersistentObject *po)
+{
+ if ( wxPersistentObject *old = Find(obj) )
+ {
+ wxFAIL_MSG( "object is already registered" );
+
+ delete po; // still avoid the memory leaks
+ return old;
+ }
+
+ m_persistentObjects[obj] = po;
+
+ return po;
+}
+
+void wxPersistenceManager::Unregister(void *obj)
+{
+ wxPersistentObjectsMap::iterator it = m_persistentObjects.find(obj);
+ wxCHECK_RET( it != m_persistentObjects.end(), "not registered" );
+
+ wxPersistentObject * const po = it->second;
+ m_persistentObjects.erase(it);
+ delete po;
+}
+
+void wxPersistenceManager::Save(void *obj)
+{
+ if ( !m_doSave )
+ return;
+
+ wxPersistentObjectsMap::iterator it = m_persistentObjects.find(obj);
+ wxCHECK_RET( it != m_persistentObjects.end(), "not registered" );
+
+ it->second->Save();
+}
+
+bool wxPersistenceManager::Restore(void *obj)
+{
+ if ( !m_doRestore )
+ return false;
+
+ wxPersistentObjectsMap::iterator it = m_persistentObjects.find(obj);
+ wxCHECK_MSG( it != m_persistentObjects.end(), false, "not registered" );
+
+ return it->second->Restore();
+}
+