Add wxPersistentComboBox for saving and restoring combobox items

This allows to preserve the history of user input.
This commit is contained in:
Vadim Zeitlin
2020-11-19 03:47:37 +01:00
parent 8469642959
commit 7f5d45b9b4
3 changed files with 175 additions and 0 deletions

View File

@@ -0,0 +1,99 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/persist/combobox.h
// Purpose: Persistence adapter for wxComboBox
// Author: Vadim Zeitlin
// Created: 2020-11-19
// Copyright: (c) 2020 Vadim Zeitlin <vadim@wxwidgets.org>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_PERSIST_COMBOBOX_H_
#define _WX_PERSIST_COMBOBOX_H_
#include "wx/persist/window.h"
#include "wx/combobox.h"
#define wxPERSIST_COMBOBOX_KIND wxASCII_STR("Combobox")
// Stores semicolon-separated list of combobox entries (real semicolons are
// escaped using backslash), i.e. "first;second;...".
#define wxPERSIST_COMBOBOX_ITEMS wxASCII_STR("Items")
#define wxPERSIST_COMBOBOX_ITEMS_SEP ';'
// ----------------------------------------------------------------------------
// wxPersistentComboBox: supports saving/restoring combobox items
// ----------------------------------------------------------------------------
class wxPersistentComboBox : public wxPersistentWindow<wxComboBox>
{
public:
// The maximum number of items to save is currently hard-coded.
//
// Notice that we must have some limit, as otherwise the length of the
// items string in the config would be unbounded, which certainly wouldn't
// be a good idea.
enum { MaxSavedItemsCount = 10 };
explicit wxPersistentComboBox(wxComboBox* combobox)
: wxPersistentWindow<wxComboBox>(combobox)
{
}
virtual void Save() const wxOVERRIDE
{
const wxComboBox* const combobox = Get();
wxArrayString items = combobox->GetStrings();
const wxString value = combobox->GetValue();
if ( !value.empty() )
{
wxArrayString::iterator it;
for ( it = items.begin(); it != items.end(); ++it )
{
if ( *it == value )
{
// There is no need to add the text of an item already
// present in the combobox again, but do move it to the top
// of it to indicate that it was the last one used.
wxSwap(*items.begin(), *it);
break;
}
}
if ( it == items.end() )
{
// This is a genuinely new item, so just insert it front.
items.insert(items.begin(), value);
if ( items.size() > MaxSavedItemsCount )
items.erase(items.begin() + MaxSavedItemsCount, items.end());
}
}
SaveValue(wxPERSIST_COMBOBOX_ITEMS,
wxJoin(items, wxPERSIST_COMBOBOX_ITEMS_SEP));
}
virtual bool Restore() wxOVERRIDE
{
wxString items;
if ( !RestoreValue(wxPERSIST_COMBOBOX_ITEMS, &items) )
return false;
Get()->Set(wxSplit(items, wxPERSIST_COMBOBOX_ITEMS_SEP));
return true;
}
virtual wxString GetKind() const wxOVERRIDE { return wxPERSIST_COMBOBOX_KIND; }
};
inline wxPersistentObject *wxCreatePersistentObject(wxComboBox* combobox)
{
return new wxPersistentComboBox(combobox);
}
#endif // _WX_PERSIST_COMBOBOX_H_

View File

@@ -0,0 +1,75 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/persist/combobox.h
// Purpose: Interface of wxPersistentComboBox
// Author: Vadim Zeitlin
// Created: 2020-11-19
// Copyright: (c) 2020 Vadim Zeitlin <vadim@wxwidgets.org>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
/**
Persistence adapter for wxComboBox.
This adapter saves and restores the items of wxComboBox. A persistent
combobox can be used to preserve history of user entries.
Example of using it:
@code
// Suppose you need to ask the user to select their favourite Linux
// distribution, for some reason:
wxComboBox* combo = new wxComboBox(this, wxID_ANY);
if ( !wxPersistentRegisterAndRestore(combo, "distribution") )
{
// Seed it with some default contents.
combo->Append("Debian");
combo->Append("Fedora");
combo->Append("Ubuntu");
}
// Optionally, you might want to restore the last used entry:
combo->SetSelection(0);
@endcode
*/
class wxPersistentComboBox : public wxPersistentWindow<wxComboBox>
{
public:
/**
Constructor.
@param combobox
The associated combobox.
*/
explicit wxPersistentComboBox(wxComboBox *combobox);
/**
Save the current items and value.
The current control value is saved as the first item, so that calling
@c SetSelection(0) when the control is created the next time will
restore the value which was last used. If the current value is the same
as one of the existing items, this item is moved to the front of the
list, instead of being added again.
If the current value is empty, it is not saved at all.
At most 10 items are saved, if the combobox has more than 10 items, or
exactly 10 items and the current value is different from all of them,
the items beyond the tenth one are discarded.
*/
virtual void Save() const;
/**
Restore the combobox items.
This function doesn't change the current combobox value, you need to
call @c SetSelection(0) explicitly, after verifying that the combobox
is not empty using its IsListEmpty() method, if you want to restore the
last used value automatically. Otherwise the user can always do it by
opening the combobox and selecting it manually.
*/
virtual bool Restore();
};
/// Overload allowing persistence adapter creation for wxComboBox objects.
wxPersistentObject *wxCreatePersistentObject(wxComboBox *combobox);

View File

@@ -255,6 +255,7 @@
#include <wx/peninfobase.h>
#include <wx/persist.h>
#include <wx/persist/bookctrl.h>
#include <wx/persist/combobox.h>
#include <wx/persist/dataview.h>
#include <wx/persist/splitter.h>
#include <wx/persist/toplevel.h>