diff --git a/include/wx/persist/combobox.h b/include/wx/persist/combobox.h new file mode 100644 index 0000000000..52efe25474 --- /dev/null +++ b/include/wx/persist/combobox.h @@ -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 +// 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 +{ +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(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_ diff --git a/interface/wx/persist/combobox.h b/interface/wx/persist/combobox.h new file mode 100644 index 0000000000..5b7e2d81b6 --- /dev/null +++ b/interface/wx/persist/combobox.h @@ -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 +// 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 +{ +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); diff --git a/tests/allheaders.h b/tests/allheaders.h index 545724635b..1425eae2b6 100644 --- a/tests/allheaders.h +++ b/tests/allheaders.h @@ -255,6 +255,7 @@ #include #include #include +#include #include #include #include