Merge branch 'dvc-persist' from iwbnwif
See https://github.com/wxWidgets/wxWidgets/pull/541
This commit is contained in:
@@ -147,6 +147,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.
|
||||
|
@@ -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
|
||||
|
175
include/wx/persist/dataview.h
Normal file
175
include/wx/persist/dataview.h
Normal file
@@ -0,0 +1,175 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// 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_COLUMNS "Columns"
|
||||
|
||||
#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"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Helper function to search for a column by its title.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
namespace wxPrivate
|
||||
{
|
||||
|
||||
inline
|
||||
wxDataViewColumn*
|
||||
GetColumnByTitle(wxDataViewCtrl* control, const wxString& name)
|
||||
{
|
||||
for ( unsigned int col = 0; col < control->GetColumnCount(); col++)
|
||||
{
|
||||
if ( control->GetColumn(col)->GetTitle() == name )
|
||||
return control->GetColumn(col);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
} // namespace wxPrivate
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// 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<wxDataViewCtrl>
|
||||
{
|
||||
public:
|
||||
wxPersistentDataViewCtrl(wxDataViewCtrl* control)
|
||||
: wxPersistentWindow<wxDataViewCtrl>(control)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void Save() const wxOVERRIDE
|
||||
{
|
||||
wxDataViewCtrl* const control = Get();
|
||||
|
||||
wxDataViewColumn* sortColumn = NULL;
|
||||
|
||||
for ( unsigned int col = 0; col < control->GetColumnCount(); col++ )
|
||||
{
|
||||
wxDataViewColumn* column = control->GetColumn(col);
|
||||
wxASSERT(column);
|
||||
|
||||
// Create a prefix string to identify each column.
|
||||
wxString columnPrefix;
|
||||
columnPrefix.Printf("/%s/%s/", wxPERSIST_DVC_COLUMNS,
|
||||
column->GetTitle());
|
||||
|
||||
// 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();
|
||||
wxDataViewColumn* column;
|
||||
|
||||
for ( unsigned int col = 0; col < control->GetColumnCount(); col++ )
|
||||
{
|
||||
column = control->GetColumn(col);
|
||||
wxASSERT(column);
|
||||
|
||||
// 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.
|
||||
wxString columnPrefix;
|
||||
columnPrefix.Printf("/%s/%s/", wxPERSIST_DVC_COLUMNS,
|
||||
column->GetTitle());
|
||||
|
||||
// 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 != "" )
|
||||
{
|
||||
bool sortAsc = true;
|
||||
column = wxPrivate::GetColumnByTitle(control, sortColumn);
|
||||
|
||||
if ( column )
|
||||
{
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
inline wxPersistentObject *wxCreatePersistentObject(wxDataViewCtrl* control)
|
||||
{
|
||||
return new wxPersistentDataViewCtrl(control);
|
||||
}
|
||||
|
||||
#endif // _WX_PERSIST_DATAVIEW_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.
|
||||
|
229
tests/persist/persistence.cpp
Normal file
229
tests/persist/persistence.cpp
Normal file
@@ -0,0 +1,229 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Name: tests/persistence/persistence.cpp
|
||||
// Purpose: wxPersistentObjects unit test
|
||||
// Author: wxWidgets Team
|
||||
// Created: 2017-08-23
|
||||
// Copyright: (c) 2017 wxWidgets Team
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Note: The wxDataViewCtrl test currently uses the derivative class
|
||||
// wxDataViewListCtrl for convenience.
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// headers
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "testprec.h"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/app.h"
|
||||
#include "wx/config.h"
|
||||
#include "wx/dataview.h"
|
||||
#include "wx/frame.h"
|
||||
#include "wx/persist/dataview.h"
|
||||
#include "wx/persist/toplevel.h"
|
||||
#endif // WX_PRECOMP
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// macros
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#define APP_NAME "cpptest"
|
||||
#define PO_PREFIX "/Persistent_Options"
|
||||
#define DVLC_PREFIX PO_PREFIX "/DataView/dvlc"
|
||||
#define DVLC_COL "Column #"
|
||||
#define DVLC_COL_PREFIX DVLC_PREFIX "/Columns/" DVLC_COL
|
||||
#define DVLC_SORT_PREFIX DVLC_PREFIX "/Sorting"
|
||||
#define DVLC_FRAME_PREFIX PO_PREFIX "/Window/frame"
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// test class
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
class PersistenceTestCase : public CppUnit::TestCase
|
||||
{
|
||||
public:
|
||||
PersistenceTestCase()
|
||||
{
|
||||
wxTheApp->SetAppName("PersistTest");
|
||||
wxConfig::Get()->DeleteGroup("/Persistent_Options");
|
||||
wxConfig::Get()->Flush();
|
||||
}
|
||||
|
||||
virtual void setUp();
|
||||
|
||||
private:
|
||||
CPPUNIT_TEST_SUITE( PersistenceTestCase );
|
||||
CPPUNIT_TEST( FrameSaveTest );
|
||||
CPPUNIT_TEST( FrameRestoreTest );
|
||||
CPPUNIT_TEST( DVLCSaveTest );
|
||||
CPPUNIT_TEST( DVLCRestoreTest );
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
void FrameSaveTest();
|
||||
void FrameRestoreTest();
|
||||
void DVLCSaveTest();
|
||||
void DVLCRestoreTest();
|
||||
|
||||
wxDataViewListCtrl* m_list;
|
||||
wxFrame* m_frame;
|
||||
|
||||
wxDECLARE_NO_COPY_CLASS(PersistenceTestCase);
|
||||
};
|
||||
|
||||
// register in the unnamed registry so that these tests are run by default
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION( PersistenceTestCase );
|
||||
|
||||
// also include in its own registry so that these tests can be run alone
|
||||
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( PersistenceTestCase, "PersistenceTestCase" );
|
||||
|
||||
void PersistenceTestCase::setUp()
|
||||
{
|
||||
// Create the objects to persist.
|
||||
m_frame = new wxFrame(wxTheApp->GetTopWindow(), wxID_ANY,
|
||||
"Persistence Test",
|
||||
wxDefaultPosition, wxSize(400,400));
|
||||
|
||||
m_list = new wxDataViewListCtrl(m_frame, wxID_ANY,
|
||||
wxDefaultPosition,
|
||||
wxDLG_UNIT(m_frame, wxSize(-1,-1)),
|
||||
wxDV_ROW_LINES|wxDV_SINGLE);
|
||||
|
||||
// Define names so the objects can be found using wxConfig.
|
||||
m_frame->SetName("frame");
|
||||
m_list->SetName("dvlc");
|
||||
|
||||
// Add some columns to the DVLC.
|
||||
m_list->AppendTextColumn(DVLC_COL "1",
|
||||
wxDATAVIEW_CELL_INERT, -1, wxALIGN_LEFT,
|
||||
wxDATAVIEW_COL_RESIZABLE |
|
||||
wxDATAVIEW_COL_REORDERABLE |
|
||||
wxDATAVIEW_COL_SORTABLE);
|
||||
m_list->AppendTextColumn(DVLC_COL "2",
|
||||
wxDATAVIEW_CELL_INERT, -1, wxALIGN_LEFT,
|
||||
wxDATAVIEW_COL_RESIZABLE |
|
||||
wxDATAVIEW_COL_REORDERABLE |
|
||||
wxDATAVIEW_COL_SORTABLE);
|
||||
|
||||
// Populate with DVLC data.
|
||||
wxVector<wxVariant> data;
|
||||
|
||||
data.push_back("AAAA");
|
||||
data.push_back("BBBB");
|
||||
m_list->AppendItem(data);
|
||||
|
||||
data.clear();
|
||||
data.push_back("CCCC");
|
||||
data.push_back("DDDD");
|
||||
m_list->AppendItem(data);
|
||||
|
||||
data.clear();
|
||||
data.push_back("EEEE");
|
||||
data.push_back("FFFF");
|
||||
m_list->AppendItem(data);
|
||||
}
|
||||
|
||||
void PersistenceTestCase::FrameSaveTest()
|
||||
{
|
||||
// Adjust the initial settings.
|
||||
m_frame->SetPosition(wxPoint(100, 150));
|
||||
m_frame->SetSize(wxSize(450, 350));
|
||||
|
||||
// Get default managers.
|
||||
wxPersistenceManager& pm = wxPersistenceManager::Get();
|
||||
wxConfigBase* conf = wxConfig::Get();
|
||||
|
||||
pm.Register(m_frame);
|
||||
|
||||
// Destroy the frame immediately.
|
||||
m_frame->wxWindowBase::Destroy();
|
||||
|
||||
// Test that the relevant keys have been stored correctly.
|
||||
int val;
|
||||
|
||||
CPPUNIT_ASSERT(conf->Read(DVLC_FRAME_PREFIX "/x", &val));
|
||||
CPPUNIT_ASSERT_EQUAL(100, val);
|
||||
|
||||
CPPUNIT_ASSERT(conf->Read(DVLC_FRAME_PREFIX "/y", &val));
|
||||
CPPUNIT_ASSERT_EQUAL(150, val);
|
||||
|
||||
CPPUNIT_ASSERT(conf->Read(DVLC_FRAME_PREFIX "/h", &val));
|
||||
CPPUNIT_ASSERT_EQUAL(350, val);
|
||||
|
||||
CPPUNIT_ASSERT(conf->Read(DVLC_FRAME_PREFIX "/w", &val));
|
||||
CPPUNIT_ASSERT_EQUAL(450, val);
|
||||
|
||||
CPPUNIT_ASSERT(conf->Read(DVLC_FRAME_PREFIX "/Iconized", &val));
|
||||
CPPUNIT_ASSERT_EQUAL(0, val);
|
||||
|
||||
CPPUNIT_ASSERT(conf->Read(DVLC_FRAME_PREFIX "/Maximized", &val));
|
||||
CPPUNIT_ASSERT_EQUAL(0, val);
|
||||
}
|
||||
|
||||
void PersistenceTestCase::FrameRestoreTest()
|
||||
{
|
||||
// Get default manager.
|
||||
wxPersistenceManager& pm = wxPersistenceManager::Get();
|
||||
|
||||
// Test that the objects are registered and can be restored.
|
||||
CPPUNIT_ASSERT(pm.RegisterAndRestore(m_frame));
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL(100, m_frame->GetPosition().x);
|
||||
CPPUNIT_ASSERT_EQUAL(150, m_frame->GetPosition().y);
|
||||
CPPUNIT_ASSERT_EQUAL(350, m_frame->GetSize().GetHeight());
|
||||
CPPUNIT_ASSERT_EQUAL(450, m_frame->GetSize().GetWidth());
|
||||
CPPUNIT_ASSERT(!m_frame->IsMaximized());
|
||||
CPPUNIT_ASSERT(!m_frame->IsIconized());
|
||||
}
|
||||
|
||||
void PersistenceTestCase::DVLCSaveTest()
|
||||
{
|
||||
// Adjust the initial settings.
|
||||
m_list->GetColumn(0)->SetWidth(150);
|
||||
m_list->GetColumn(1)->SetWidth(250);
|
||||
m_list->GetColumn(1)->SetSortOrder(false);
|
||||
|
||||
// Get default managers.
|
||||
wxPersistenceManager& pm = wxPersistenceManager::Get();
|
||||
wxConfigBase* conf = wxConfig::Get();
|
||||
|
||||
pm.Register(m_list);
|
||||
|
||||
// Destroy the frame containing the DVLC immediately.
|
||||
m_frame->wxWindowBase::Destroy();
|
||||
|
||||
// Test that the relevant keys have been stored correctly.
|
||||
int val;
|
||||
wxString text;
|
||||
|
||||
CPPUNIT_ASSERT(conf->Read(DVLC_COL_PREFIX "1/Width", &val));
|
||||
CPPUNIT_ASSERT_EQUAL(150, val);
|
||||
|
||||
CPPUNIT_ASSERT(conf->Read(DVLC_COL_PREFIX "2/Width", &val));
|
||||
CPPUNIT_ASSERT_EQUAL(250, val);
|
||||
|
||||
CPPUNIT_ASSERT(conf->Read(DVLC_SORT_PREFIX "/Column", &text));
|
||||
CPPUNIT_ASSERT_EQUAL("Column #2", text);
|
||||
|
||||
CPPUNIT_ASSERT(conf->Read(DVLC_SORT_PREFIX "/Asc", &val));
|
||||
CPPUNIT_ASSERT_EQUAL(0, val);
|
||||
}
|
||||
|
||||
void PersistenceTestCase::DVLCRestoreTest()
|
||||
{
|
||||
// Get default manager.
|
||||
wxPersistenceManager& pm = wxPersistenceManager::Get();
|
||||
|
||||
// Test that the objects are registered and can be restored.
|
||||
CPPUNIT_ASSERT(pm.RegisterAndRestore(m_list));
|
||||
|
||||
// Test that the correct values were restored.
|
||||
CPPUNIT_ASSERT_EQUAL(150, m_list->GetColumn(0)->GetWidth());
|
||||
CPPUNIT_ASSERT_EQUAL(250, m_list->GetColumn(1)->GetWidth());
|
||||
CPPUNIT_ASSERT(m_list->GetColumn(1)->IsSortKey());
|
||||
CPPUNIT_ASSERT(!m_list->GetColumn(1)->IsSortOrderAscending());
|
||||
}
|
Reference in New Issue
Block a user