diff --git a/Makefile.in b/Makefile.in
index 07e50b8ac3..3a49998522 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -3964,6 +3964,7 @@ COND_USE_GUI_1_ALL_GUI_HEADERS = \
wx/paper.h \
wx/persist.h \
wx/persist/bookctrl.h \
+ wx/persist/dataview.h \
wx/persist/splitter.h \
wx/persist/toplevel.h \
wx/persist/treebook.h \
diff --git a/build/bakefiles/files.bkl b/build/bakefiles/files.bkl
index bd05d5a1dd..850ba226f1 100644
--- a/build/bakefiles/files.bkl
+++ b/build/bakefiles/files.bkl
@@ -1145,6 +1145,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file!
wx/paper.h
wx/persist.h
wx/persist/bookctrl.h
+ wx/persist/dataview.h
wx/persist/splitter.h
wx/persist/toplevel.h
wx/persist/treebook.h
diff --git a/build/files b/build/files
index 7f2afb53cd..757ffab063 100644
--- a/build/files
+++ b/build/files
@@ -1066,6 +1066,7 @@ GUI_CMN_HDR =
wx/paper.h
wx/persist.h
wx/persist/bookctrl.h
+ wx/persist/dataview.h
wx/persist/splitter.h
wx/persist/toplevel.h
wx/persist/treebook.h
diff --git a/build/msw/wx_core.vcxproj b/build/msw/wx_core.vcxproj
index d530592aae..40cf55da63 100644
--- a/build/msw/wx_core.vcxproj
+++ b/build/msw/wx_core.vcxproj
@@ -1383,6 +1383,7 @@
+
diff --git a/build/msw/wx_core.vcxproj.filters b/build/msw/wx_core.vcxproj.filters
index eecc9366e6..d8057768a5 100644
--- a/build/msw/wx_core.vcxproj.filters
+++ b/build/msw/wx_core.vcxproj.filters
@@ -1723,6 +1723,9 @@
Common Headers
+
+ Common Headers
+
Common Headers
diff --git a/build/msw/wx_vc7_core.vcproj b/build/msw/wx_vc7_core.vcproj
index 9c9bfb0294..2427c2944c 100644
--- a/build/msw/wx_vc7_core.vcproj
+++ b/build/msw/wx_vc7_core.vcproj
@@ -2054,6 +2054,9 @@
+
+
diff --git a/build/msw/wx_vc8_core.vcproj b/build/msw/wx_vc8_core.vcproj
index bbfe94eaf8..ec5944ffc8 100644
--- a/build/msw/wx_vc8_core.vcproj
+++ b/build/msw/wx_vc8_core.vcproj
@@ -3240,6 +3240,10 @@
RelativePath="..\..\include\wx\dataview.h"
>
+
+
diff --git a/build/msw/wx_vc9_core.vcproj b/build/msw/wx_vc9_core.vcproj
index 3a399a7c42..09e025ae63 100644
--- a/build/msw/wx_vc9_core.vcproj
+++ b/build/msw/wx_vc9_core.vcproj
@@ -3236,6 +3236,10 @@
RelativePath="..\..\include\wx\dataview.h"
>
+
+
diff --git a/docs/changes.txt b/docs/changes.txt
index 2b982c304a..71416ec6f5 100644
--- a/docs/changes.txt
+++ b/docs/changes.txt
@@ -148,6 +148,7 @@ All (GUI):
- Fix position of the rectangle returned by wxDataViewCtrl::GetItemRect().
- Add wxDataViewRenderer::GetAccessibleDescription().
- Add wxDataViewCheckIconTextRenderer class.
+- Implement persistence support for wxDataViewCtrl (iwbnwif).
- Improve wxImage::Scale() handling of pixels with alpha channel (Tim Kosse).
- Fix parsing of RGBA strings in wxColour (Laurent Poujoulat).
- Refactor code in wxQuantize() for MSVC to avoid crash.
diff --git a/docs/doxygen/overviews/persistence.h b/docs/doxygen/overviews/persistence.h
index 396dddd587..c055ccfc27 100644
--- a/docs/doxygen/overviews/persistence.h
+++ b/docs/doxygen/overviews/persistence.h
@@ -50,6 +50,7 @@ Currently the following classes are supported:
- wxTopLevelWindow (and hence wxFrame and wxDialog)
- wxBookCtrlBase (i.e. wxNotebook, wxListbook, wxToolbook and wxChoicebook)
+- wxDataViewCtrl (and derivatives such as wxDataViewListCtrl)
- wxTreebook
To automatically save and restore the properties of the windows of classes
diff --git a/include/wx/persist/dataview.h b/include/wx/persist/dataview.h
new file mode 100644
index 0000000000..c5f212b2ee
--- /dev/null
+++ b/include/wx/persist/dataview.h
@@ -0,0 +1,163 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name: wx/persist/dataview.h
+// Purpose: Persistence support for wxDataViewCtrl and its derivatives
+// Author: wxWidgets Team
+// Created: 2017-08-21
+// Copyright: (c) 2017 wxWidgets.org
+// Licence: wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _WX_PERSIST_DATAVIEW_H_
+#define _WX_PERSIST_DATAVIEW_H_
+
+#include "wx/persist/window.h"
+
+#include "wx/dataview.h"
+
+// ----------------------------------------------------------------------------
+// String constants used by wxPersistentDataViewCtrl.
+// ----------------------------------------------------------------------------
+
+#define wxPERSIST_DVC_KIND "DataView"
+
+#define wxPERSIST_DVC_HIDDEN "Hidden"
+#define wxPERSIST_DVC_POS "Position"
+#define wxPERSIST_DVC_TITLE "Title"
+#define wxPERSIST_DVC_WIDTH "Width"
+
+#define wxPERSIST_DVC_SORT_KEY "Sorting/Column"
+#define wxPERSIST_DVC_SORT_ASC "Sorting/Asc"
+
+// ----------------------------------------------------------------------------
+// wxPersistentDataViewCtrl: Saves and restores user modified column widths
+// and single column sort order.
+//
+// Future improvements could be to save and restore column order if the user
+// has changed it and multicolumn sorts.
+// ----------------------------------------------------------------------------
+
+class wxPersistentDataViewCtrl : public wxPersistentWindow
+{
+public:
+ wxPersistentDataViewCtrl(wxDataViewCtrl* control)
+ : wxPersistentWindow(control)
+ {
+ }
+
+ virtual void Save() const wxOVERRIDE
+ {
+ wxDataViewCtrl* const control = Get();
+
+ const wxDataViewColumn* sortColumn = NULL;
+
+ for ( unsigned int col = 0; col < control->GetColumnCount(); col++ )
+ {
+ const wxDataViewColumn* const column = control->GetColumn(col);
+
+ // Create a prefix string to identify each column.
+ const wxString columnPrefix = MakeColumnPrefix(column);
+
+ // Save the column attributes.
+ SaveValue(columnPrefix + wxPERSIST_DVC_HIDDEN, column->IsHidden());
+ SaveValue(columnPrefix + wxPERSIST_DVC_POS,
+ control->GetColumnPosition(column));
+ SaveValue(columnPrefix + wxPERSIST_DVC_WIDTH, column->GetWidth());
+
+ // Check if this column is the current sort key.
+ if ( column->IsSortKey() )
+ sortColumn = column;
+ }
+
+ // Note: The current implementation does not save and restore multi-
+ // column sort keys.
+ if ( control->IsMultiColumnSortAllowed() )
+ return;
+
+ // Save the sort key and direction if there is a valid sort.
+ if ( sortColumn )
+ {
+ SaveValue(wxPERSIST_DVC_SORT_KEY, sortColumn->GetTitle());
+ SaveValue(wxPERSIST_DVC_SORT_ASC,
+ sortColumn->IsSortOrderAscending());
+ }
+ }
+
+ virtual bool Restore() wxOVERRIDE
+ {
+ wxDataViewCtrl* const control = Get();
+
+ for ( unsigned int col = 0; col < control->GetColumnCount(); col++ )
+ {
+ wxDataViewColumn* const column = control->GetColumn(col);
+
+ // Create a prefix string to identify each column within the
+ // persistence store (columns are stored by title). The persistence
+ // store benignly handles cases where the title is not found.
+ const wxString columnPrefix = MakeColumnPrefix(column);
+
+ // Restore column hidden status.
+ bool hidden;
+ if ( RestoreValue(columnPrefix + wxPERSIST_DVC_HIDDEN, &hidden) )
+ column->SetHidden(hidden);
+
+ // Restore the column width.
+ int width;
+ if ( RestoreValue(columnPrefix + wxPERSIST_DVC_WIDTH, &width) )
+ column->SetWidth(width);
+
+ // TODO: Set the column's view position.
+ }
+
+ // Restore the sort key and order if there is a valid model and sort
+ // criteria.
+ wxString sortColumn;
+ if ( control->GetModel() &&
+ RestoreValue(wxPERSIST_DVC_SORT_KEY, &sortColumn) &&
+ !sortColumn.empty() )
+ {
+ bool sortAsc = true;
+ if ( wxDataViewColumn* column = GetColumnByTitle(control, sortColumn) )
+ {
+ RestoreValue(wxPERSIST_DVC_SORT_ASC, &sortAsc);
+ column->SetSortOrder(sortAsc);
+
+ // Resort the control based on the new sort criteria.
+ control->GetModel()->Resort();
+ }
+ }
+
+ return true;
+ }
+
+ virtual wxString GetKind() const wxOVERRIDE
+ {
+ return wxPERSIST_DVC_KIND;
+ }
+
+private:
+ // Return a (slash-terminated) prefix for the column-specific entries.
+ static wxString MakeColumnPrefix(const wxDataViewColumn* column)
+ {
+ return wxString::Format("/Columns/%s/", column->GetTitle());
+ }
+
+ // Return the column with the given title or NULL.
+ static wxDataViewColumn*
+ GetColumnByTitle(wxDataViewCtrl* control, const wxString& title)
+ {
+ for ( unsigned int col = 0; col < control->GetColumnCount(); col++ )
+ {
+ if ( control->GetColumn(col)->GetTitle() == title )
+ return control->GetColumn(col);
+ }
+
+ return NULL;
+ }
+};
+
+inline wxPersistentObject *wxCreatePersistentObject(wxDataViewCtrl* control)
+{
+ return new wxPersistentDataViewCtrl(control);
+}
+
+#endif // _WX_PERSIST_DATAVIEW_H_
diff --git a/interface/wx/persist.h b/interface/wx/persist.h
index a60fd1f42c..f9c75920fe 100644
--- a/interface/wx/persist.h
+++ b/interface/wx/persist.h
@@ -204,6 +204,9 @@ protected:
/**
Base class for persistent object adapters.
+ See @ref overview_persistence for an overview of persistent objects within
+ wxWidgets.
+
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
@@ -292,13 +295,14 @@ protected:
bool SaveValue(const wxString& name, T value) const;
/**
- Restore the value saved by Save().
+ Restore a value saved by SaveValue().
@param name
- The same name as was used by Save().
+ The same name as was used by SaveValue().
@param value
- Non-@NULL pointer which will be filled with the value if it was
- read successfully or not modified if it wasn't.
+ Non-@NULL pointer to the same type that was passed to SaveValue().
+ The pointed to object will be filled with the saved value if it
+ was read successfully or not modified otherwise.
@return
@true if the value was successfully read or @false if it was not
found or an error occurred.
diff --git a/interface/wx/persist/dataview.h b/interface/wx/persist/dataview.h
new file mode 100644
index 0000000000..b98896879b
--- /dev/null
+++ b/interface/wx/persist/dataview.h
@@ -0,0 +1,42 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name: wx/persist/dataview.h
+// Purpose: interface of wxPersistentDataViewCtrl
+// Author: Vadim Zeitlin
+// Copyright: (c) 2009 Vadim Zeitlin
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+/**
+ Persistence adapter for wxDataViewCtrl.
+
+ This adapter handles wxDataViewCtrl column widths and sort order.
+
+ @since 3.1.1
+ */
+class wxPersistentDataViewCtrl : public wxPersistentWindow
+{
+public:
+ /**
+ Constructor.
+
+ @param control The associated control.
+ */
+ wxPersistentDataViewCtrl(wxDataViewCtrl* control);
+
+ /**
+ Save the current column widths and sort order.
+ */
+ void Save() const override;
+
+ /**
+ Restore the column widths and sort order.
+
+ The wxDataViewCtrl must be initialized before calling this function, i.e.
+ all of its columns should be already added to it -- otherwise restoring
+ their width would have no effect.
+ */
+ bool Restore() override;
+};
+
+/// Overload allowing persistence adapter creation for wxDataViewCtrl objects.
+wxPersistentObject *wxCreatePersistentObject(wxDataViewCtrl *book);
diff --git a/tests/Makefile.in b/tests/Makefile.in
index 09456fcfb3..f8a086d08b 100644
--- a/tests/Makefile.in
+++ b/tests/Makefile.in
@@ -250,6 +250,8 @@ TEST_GUI_OBJECTS = \
test_gui_safearrayconverttest.o \
test_gui_settings.o \
test_gui_socket.o \
+ test_gui_tlw.o \
+ test_gui_dataview.o \
test_gui_boxsizer.o \
test_gui_gridsizer.o \
test_gui_wrapsizer.o \
@@ -1015,6 +1017,12 @@ test_gui_settings.o: $(srcdir)/misc/settings.cpp $(TEST_GUI_ODEP)
test_gui_socket.o: $(srcdir)/net/socket.cpp $(TEST_GUI_ODEP)
$(CXXC) -c -o $@ $(TEST_GUI_CXXFLAGS) $(srcdir)/net/socket.cpp
+test_gui_tlw.o: $(srcdir)/persistence/tlw.cpp $(TEST_GUI_ODEP)
+ $(CXXC) -c -o $@ $(TEST_GUI_CXXFLAGS) $(srcdir)/persistence/tlw.cpp
+
+test_gui_dataview.o: $(srcdir)/persistence/dataview.cpp $(TEST_GUI_ODEP)
+ $(CXXC) -c -o $@ $(TEST_GUI_CXXFLAGS) $(srcdir)/persistence/dataview.cpp
+
test_gui_boxsizer.o: $(srcdir)/sizers/boxsizer.cpp $(TEST_GUI_ODEP)
$(CXXC) -c -o $@ $(TEST_GUI_CXXFLAGS) $(srcdir)/sizers/boxsizer.cpp
diff --git a/tests/makefile.bcc b/tests/makefile.bcc
index d09d849d64..2466423dad 100644
--- a/tests/makefile.bcc
+++ b/tests/makefile.bcc
@@ -236,6 +236,8 @@ TEST_GUI_OBJECTS = \
$(OBJS)\test_gui_safearrayconverttest.obj \
$(OBJS)\test_gui_settings.obj \
$(OBJS)\test_gui_socket.obj \
+ $(OBJS)\test_gui_tlw.obj \
+ $(OBJS)\test_gui_dataview.obj \
$(OBJS)\test_gui_boxsizer.obj \
$(OBJS)\test_gui_gridsizer.obj \
$(OBJS)\test_gui_wrapsizer.obj \
@@ -1068,6 +1070,12 @@ $(OBJS)\test_gui_settings.obj: .\misc\settings.cpp
$(OBJS)\test_gui_socket.obj: .\net\socket.cpp
$(CXX) -q -c -P -o$@ $(TEST_GUI_CXXFLAGS) .\net\socket.cpp
+$(OBJS)\test_gui_tlw.obj: .\persistence\tlw.cpp
+ $(CXX) -q -c -P -o$@ $(TEST_GUI_CXXFLAGS) .\persistence\tlw.cpp
+
+$(OBJS)\test_gui_dataview.obj: .\persistence\dataview.cpp
+ $(CXX) -q -c -P -o$@ $(TEST_GUI_CXXFLAGS) .\persistence\dataview.cpp
+
$(OBJS)\test_gui_boxsizer.obj: .\sizers\boxsizer.cpp
$(CXX) -q -c -P -o$@ $(TEST_GUI_CXXFLAGS) .\sizers\boxsizer.cpp
diff --git a/tests/makefile.gcc b/tests/makefile.gcc
index 15b7c210c4..6ff71503e1 100644
--- a/tests/makefile.gcc
+++ b/tests/makefile.gcc
@@ -231,6 +231,8 @@ TEST_GUI_OBJECTS = \
$(OBJS)\test_gui_safearrayconverttest.o \
$(OBJS)\test_gui_settings.o \
$(OBJS)\test_gui_socket.o \
+ $(OBJS)\test_gui_tlw.o \
+ $(OBJS)\test_gui_dataview.o \
$(OBJS)\test_gui_boxsizer.o \
$(OBJS)\test_gui_gridsizer.o \
$(OBJS)\test_gui_wrapsizer.o \
@@ -1045,6 +1047,12 @@ $(OBJS)\test_gui_settings.o: ./misc/settings.cpp
$(OBJS)\test_gui_socket.o: ./net/socket.cpp
$(CXX) -c -o $@ $(TEST_GUI_CXXFLAGS) $(CPPDEPS) $<
+$(OBJS)\test_gui_tlw.o: ./persistence/tlw.cpp
+ $(CXX) -c -o $@ $(TEST_GUI_CXXFLAGS) $(CPPDEPS) $<
+
+$(OBJS)\test_gui_dataview.o: ./persistence/dataview.cpp
+ $(CXX) -c -o $@ $(TEST_GUI_CXXFLAGS) $(CPPDEPS) $<
+
$(OBJS)\test_gui_boxsizer.o: ./sizers/boxsizer.cpp
$(CXX) -c -o $@ $(TEST_GUI_CXXFLAGS) $(CPPDEPS) $<
diff --git a/tests/makefile.vc b/tests/makefile.vc
index e4aa4a03bb..9ccebcdd66 100644
--- a/tests/makefile.vc
+++ b/tests/makefile.vc
@@ -242,6 +242,8 @@ TEST_GUI_OBJECTS = \
$(OBJS)\test_gui_safearrayconverttest.obj \
$(OBJS)\test_gui_settings.obj \
$(OBJS)\test_gui_socket.obj \
+ $(OBJS)\test_gui_tlw.obj \
+ $(OBJS)\test_gui_dataview.obj \
$(OBJS)\test_gui_boxsizer.obj \
$(OBJS)\test_gui_gridsizer.obj \
$(OBJS)\test_gui_wrapsizer.obj \
@@ -1247,6 +1249,12 @@ $(OBJS)\test_gui_settings.obj: .\misc\settings.cpp
$(OBJS)\test_gui_socket.obj: .\net\socket.cpp
$(CXX) /c /nologo /TP /Fo$@ $(TEST_GUI_CXXFLAGS) .\net\socket.cpp
+$(OBJS)\test_gui_tlw.obj: .\persistence\tlw.cpp
+ $(CXX) /c /nologo /TP /Fo$@ $(TEST_GUI_CXXFLAGS) .\persistence\tlw.cpp
+
+$(OBJS)\test_gui_dataview.obj: .\persistence\dataview.cpp
+ $(CXX) /c /nologo /TP /Fo$@ $(TEST_GUI_CXXFLAGS) .\persistence\dataview.cpp
+
$(OBJS)\test_gui_boxsizer.obj: .\sizers\boxsizer.cpp
$(CXX) /c /nologo /TP /Fo$@ $(TEST_GUI_CXXFLAGS) .\sizers\boxsizer.cpp
diff --git a/tests/persistence/dataview.cpp b/tests/persistence/dataview.cpp
new file mode 100644
index 0000000000..9701bef6c8
--- /dev/null
+++ b/tests/persistence/dataview.cpp
@@ -0,0 +1,136 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name: tests/persistence/dataview.cpp
+// Purpose: wxDataViewCtrl persistence support unit tests
+// Author: wxWidgets Team
+// Created: 2017-08-23
+// Copyright: (c) 2017 wxWidgets Team
+///////////////////////////////////////////////////////////////////////////////
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+#include "testprec.h"
+
+#ifdef __BORLANDC__
+ #pragma hdrstop
+#endif
+
+#include "testpersistence.h"
+
+#ifndef WX_PRECOMP
+ #include "wx/dataview.h"
+#endif // WX_PRECOMP
+
+#include "wx/persist/dataview.h"
+
+// ----------------------------------------------------------------------------
+// constants
+// ----------------------------------------------------------------------------
+
+#define DVC_PREFIX PO_PREFIX "/DataView/dvc"
+#define DVC_COL "Column #"
+#define DVC_COL_PREFIX DVC_PREFIX "/Columns/" DVC_COL
+#define DVC_SORT_PREFIX DVC_PREFIX "/Sorting"
+
+// ----------------------------------------------------------------------------
+// local helpers
+// ----------------------------------------------------------------------------
+
+// Create the control used for testing.
+static wxDataViewCtrl* CreatePersistenceTestDVC()
+{
+ // We can't just destroy the control itself directly, we need to destroy
+ // its parent as only this will ensure that it gets wxWindowDestroyEvent
+ // from which its state will be saved.
+ wxWindow* const parent = new wxWindow(wxTheApp->GetTopWindow(), wxID_ANY);
+ wxDataViewListCtrl* const list = new wxDataViewListCtrl(parent, wxID_ANY);
+ list->SetName("dvc");
+
+ // Add some columns to the DVC.
+ list->AppendTextColumn(DVC_COL "1",
+ wxDATAVIEW_CELL_INERT, -1, wxALIGN_LEFT,
+ wxDATAVIEW_COL_RESIZABLE |
+ wxDATAVIEW_COL_REORDERABLE |
+ wxDATAVIEW_COL_SORTABLE);
+ list->AppendTextColumn(DVC_COL "2",
+ wxDATAVIEW_CELL_INERT, -1, wxALIGN_LEFT,
+ wxDATAVIEW_COL_RESIZABLE |
+ wxDATAVIEW_COL_REORDERABLE |
+ wxDATAVIEW_COL_SORTABLE);
+
+ // Populate with DVC data.
+ wxVector data;
+
+ data.push_back("AAAA");
+ data.push_back("BBBB");
+ list->AppendItem(data);
+
+ data.clear();
+ data.push_back("CCCC");
+ data.push_back("DDDD");
+ list->AppendItem(data);
+
+ data.clear();
+ data.push_back("EEEE");
+ data.push_back("FFFF");
+ list->AppendItem(data);
+
+ return list;
+}
+
+// --------------------------------------------------------------------------
+// tests themselves
+// --------------------------------------------------------------------------
+
+// Note: The wxDataViewCtrl test currently uses the derivative class
+// wxDataViewListCtrl for convenience.
+TEST_CASE_METHOD(PersistenceTests, "wxPersistDVC", "[persist][wxDataViewCtrl]")
+{
+ {
+ wxDataViewCtrl* const list = CreatePersistenceTestDVC();
+
+ // Adjust the initial settings.
+ list->GetColumn(0)->SetWidth(150);
+ list->GetColumn(1)->SetWidth(250);
+ list->GetColumn(1)->SetSortOrder(false);
+
+ CHECK(wxPersistenceManager::Get().Register(list));
+
+ // Deleting the control itself doesn't allow it to save its state as
+ // the wxEVT_DESTROY handler is called too late, so delete its parent
+ // (as would usually be the case) instead.
+ delete list->GetParent();
+
+ // Test that the relevant keys have been stored correctly.
+ int val = -1;
+ wxString text;
+
+ CHECK(GetConfig().Read(DVC_COL_PREFIX "1/Width", &val));
+ CHECK(150 == val);
+
+ CHECK(GetConfig().Read(DVC_COL_PREFIX "2/Width", &val));
+ CHECK(250 == val);
+
+ CHECK(GetConfig().Read(DVC_SORT_PREFIX "/Column", &text));
+ CHECK(text == "Column #2");
+
+ CHECK(GetConfig().Read(DVC_SORT_PREFIX "/Asc", &val));
+ CHECK(0 == val);
+ }
+
+ {
+ wxDataViewCtrl* const list = CreatePersistenceTestDVC();
+
+ // Test that the object was registered and restored.
+ CHECK(wxPersistenceManager::Get().RegisterAndRestore(list));
+
+ // Test that the correct values were restored.
+ CHECK(150 == list->GetColumn(0)->GetWidth());
+ CHECK(250 == list->GetColumn(1)->GetWidth());
+ CHECK(list->GetColumn(1)->IsSortKey());
+ CHECK(!list->GetColumn(1)->IsSortOrderAscending());
+
+ delete list->GetParent();
+ }
+}
diff --git a/tests/persistence/testpersistence.h b/tests/persistence/testpersistence.h
new file mode 100644
index 0000000000..3926b214bf
--- /dev/null
+++ b/tests/persistence/testpersistence.h
@@ -0,0 +1,67 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name: tests/persistence/testpersistence.h
+// Purpose: Fixture for wxPersistentObject unit tests
+// Author: wxWidgets Team
+// Created: 2017-08-23
+// Copyright: (c) 2017 wxWidgets Team
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef WX_TESTS_PERSIST_TESTPERSISTENCE_H
+#define WX_TESTS_PERSIST_TESTPERSISTENCE_H
+
+#include "wx/app.h"
+#include "wx/config.h"
+#include "wx/persist.h"
+
+#define PO_PREFIX "/Persistent_Options"
+
+class PersistenceTests
+{
+public:
+ PersistenceTests()
+ : m_managerOld(&wxPersistenceManager::Get())
+ {
+ // Install our custom manager, using custom config object, for the test
+ // duration.
+ wxPersistenceManager::Set(m_manager);
+ }
+
+ // Access the config object used for storing the settings.
+ const wxConfigBase& GetConfig() const
+ {
+ return *m_manager.GetConfig();
+ }
+
+ ~PersistenceTests()
+ {
+ wxPersistenceManager::Set(*m_managerOld);
+ }
+
+private:
+ class TestPersistenceManager : public wxPersistenceManager
+ {
+ public:
+ TestPersistenceManager()
+ : m_config("PersistenceTests", "wxWidgets")
+ {
+ }
+
+ ~TestPersistenceManager() wxOVERRIDE
+ {
+ m_config.DeleteAll();
+ }
+
+ wxConfigBase* GetConfig() const wxOVERRIDE
+ {
+ return const_cast(&m_config);
+ }
+
+ private:
+ wxConfig m_config;
+ };
+
+ wxPersistenceManager *m_managerOld;
+ TestPersistenceManager m_manager;
+};
+
+#endif // WX_TESTS_PERSIST_TESTPERSISTENCE_H
diff --git a/tests/persistence/tlw.cpp b/tests/persistence/tlw.cpp
new file mode 100644
index 0000000000..021f1bed64
--- /dev/null
+++ b/tests/persistence/tlw.cpp
@@ -0,0 +1,106 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name: tests/persistence/persistence.cpp
+// Purpose: wxTLW persistence support unit test
+// Author: wxWidgets Team
+// Created: 2017-08-23
+// Copyright: (c) 2017 wxWidgets Team
+///////////////////////////////////////////////////////////////////////////////
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+#include "testprec.h"
+
+#ifdef __BORLANDC__
+ #pragma hdrstop
+#endif
+
+#include "testpersistence.h"
+
+#ifndef WX_PRECOMP
+ #include "wx/frame.h"
+#endif // WX_PRECOMP
+
+#include "wx/persist/toplevel.h"
+
+// ----------------------------------------------------------------------------
+// constants
+// ----------------------------------------------------------------------------
+
+#define FRAME_OPTIONS_PREFIX PO_PREFIX "/Window/frame"
+
+// ----------------------------------------------------------------------------
+// local helpers
+// ----------------------------------------------------------------------------
+
+// Create the frame used for testing.
+static wxFrame* CreatePersistenceTestFrame()
+{
+ wxFrame* const frame = new wxFrame(wxTheApp->GetTopWindow(), wxID_ANY, "wxTest");
+ frame->SetName("frame");
+
+ return frame;
+}
+
+// ----------------------------------------------------------------------------
+// tests themselves
+// ----------------------------------------------------------------------------
+
+TEST_CASE_METHOD(PersistenceTests, "wxPersistTLW", "[persist][tlw]")
+{
+ const wxPoint pos(100, 150);
+ const wxSize size(450, 350);
+
+ // Save the frame geometry.
+ {
+ wxFrame* const frame = CreatePersistenceTestFrame();
+
+ // Set the geometry before saving.
+ frame->SetPosition(pos);
+ frame->SetSize(size);
+
+ CHECK(wxPersistenceManager::Get().Register(frame));
+
+ // Destroy the frame immediately, i.e. don't use Destroy() here.
+ delete frame;
+
+ // Test that the relevant keys have been stored correctly.
+ int val = -1;
+
+ CHECK(GetConfig().Read(FRAME_OPTIONS_PREFIX "/x", &val));
+ CHECK(pos.x == val);
+
+ CHECK(GetConfig().Read(FRAME_OPTIONS_PREFIX "/y", &val));
+ CHECK(pos.y == val);
+
+ CHECK(GetConfig().Read(FRAME_OPTIONS_PREFIX "/w", &val));
+ CHECK(size.x == val);
+
+ CHECK(GetConfig().Read(FRAME_OPTIONS_PREFIX "/h", &val));
+ CHECK(size.y == val);
+
+ CHECK(GetConfig().Read(FRAME_OPTIONS_PREFIX "/Iconized", &val));
+ CHECK(0 == val);
+
+ CHECK(GetConfig().Read(FRAME_OPTIONS_PREFIX "/Maximized", &val));
+ CHECK(0 == val);
+ }
+
+ // Now try recreating the frame using the restored values.
+ {
+ wxFrame* const frame = CreatePersistenceTestFrame();
+
+ // Test that the object was registered and restored.
+ CHECK(wxPersistenceManager::Get().RegisterAndRestore(frame));
+
+ CHECK(pos.x == frame->GetPosition().x);
+ CHECK(pos.y == frame->GetPosition().y);
+ CHECK(size.x == frame->GetSize().GetWidth());
+ CHECK(size.y == frame->GetSize().GetHeight());
+ CHECK(!frame->IsMaximized());
+ CHECK(!frame->IsIconized());
+
+ delete frame;
+ }
+}
diff --git a/tests/test.bkl b/tests/test.bkl
index e6b7194890..95007b4836 100644
--- a/tests/test.bkl
+++ b/tests/test.bkl
@@ -261,6 +261,8 @@
applications.
-->
net/socket.cpp
+ persistence/tlw.cpp
+ persistence/dataview.cpp
sizers/boxsizer.cpp
sizers/gridsizer.cpp
sizers/wrapsizer.cpp
diff --git a/tests/test_gui.vcxproj b/tests/test_gui.vcxproj
index c6810356d2..af4d68b517 100644
--- a/tests/test_gui.vcxproj
+++ b/tests/test_gui.vcxproj
@@ -545,6 +545,8 @@
+
+
diff --git a/tests/test_gui.vcxproj.filters b/tests/test_gui.vcxproj.filters
index 169cb53ca1..40ab41a51d 100644
--- a/tests/test_gui.vcxproj.filters
+++ b/tests/test_gui.vcxproj.filters
@@ -227,6 +227,12 @@
Source Files
+
+ Source Files
+
+
+ Source Files
+
Source Files
@@ -293,4 +299,4 @@
Resource Files
-
\ No newline at end of file
+
diff --git a/tests/test_vc7_test_gui.vcproj b/tests/test_vc7_test_gui.vcproj
index 9db79de191..484c4776ac 100644
--- a/tests/test_vc7_test_gui.vcproj
+++ b/tests/test_vc7_test_gui.vcproj
@@ -355,6 +355,9 @@
+
+
@@ -559,6 +562,9 @@
+
+
diff --git a/tests/test_vc8_test_gui.vcproj b/tests/test_vc8_test_gui.vcproj
index ba44877479..15fda65a98 100644
--- a/tests/test_vc8_test_gui.vcproj
+++ b/tests/test_vc8_test_gui.vcproj
@@ -910,6 +910,10 @@
RelativePath=".\config\config.cpp"
>
+
+
@@ -1214,6 +1218,10 @@
RelativePath=".\controls\textentrytest.cpp"
>
+
+
diff --git a/tests/test_vc9_test_gui.vcproj b/tests/test_vc9_test_gui.vcproj
index 557797b046..6e99dc8de7 100644
--- a/tests/test_vc9_test_gui.vcproj
+++ b/tests/test_vc9_test_gui.vcproj
@@ -882,6 +882,10 @@
RelativePath=".\config\config.cpp"
>
+
+
@@ -1186,6 +1190,10 @@
RelativePath=".\controls\textentrytest.cpp"
>
+
+