mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2024-11-30 08:08:39 -05:00
Added commentary to the Configuration module
Description and instructions to help those adding or amending settings values. git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@4952 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
parent
d91aed5aee
commit
fe6c04a5cf
@ -1,5 +1,128 @@
|
||||
#include "Configuration.hpp"
|
||||
|
||||
//
|
||||
// Read me!
|
||||
//
|
||||
// This file defines a configuration dialog with the user. The general
|
||||
// strategy is to expose agreed configuration parameters via a custom
|
||||
// interface (See Configuration.hpp). The state exposed through this
|
||||
// public interface reflects stored or derived data in the
|
||||
// Configuration::impl object. The Configuration::impl structure is
|
||||
// an implementation of the PIMPL (a.k.a. Cheshire Cat or compilation
|
||||
// firewall) implementation hiding idiom that allows internal state to
|
||||
// be completely removed from the public interface.
|
||||
//
|
||||
// There is a secondary level of parameter storage which reflects
|
||||
// current settings UI state, these parameters are not copied to the
|
||||
// state store that the public interface exposes until the
|
||||
// Configuration:impl::accept() operation is successful. The accept()
|
||||
// operation is tied to the settings OK button. The normal and most
|
||||
// convenient place to store this intermediate settings UI state is in
|
||||
// the data models of the UI controls, if that is not convenient then
|
||||
// separate member variables must be used to store that state. It is
|
||||
// important for the user experience that no publicly visible settings
|
||||
// are changed while the settings UI are changed i.e. all settings
|
||||
// changes must be deferred until the "OK" button is
|
||||
// clicked. Conversely, all changes must be discarded if the settings
|
||||
// UI "Cancel" button is clicked.
|
||||
//
|
||||
// There is a complication related to the radio interface since the
|
||||
// this module offers the facility to test the radio interface. This
|
||||
// test means that the public visibility to the radio being tested
|
||||
// must be changed. To maintain the illusion of deferring changes
|
||||
// until they are accepted, the original radio related settings are
|
||||
// stored upon showing the UI and restored if the UI is dismissed by
|
||||
// canceling.
|
||||
//
|
||||
// It should be noted that the settings UI lives as long as the
|
||||
// application client that uses it does. It is simply shown and hidden
|
||||
// as it is needed rather than creating it on demand. This strategy
|
||||
// saves a lot of expensive UI drawing at the expense of a little
|
||||
// storage and gives a convenient place to deliver settings values
|
||||
// from.
|
||||
//
|
||||
// Here is an overview of the high level flow of this module:
|
||||
//
|
||||
// 1) On construction the initial environment is initialized and
|
||||
// initial values for settings are read from the QSettings
|
||||
// database. At this point default values for any new settings are
|
||||
// established by providing a default value to the QSettings value
|
||||
// queries. This should be the only place where a hard coded value for
|
||||
// a settings item is defined. Any remaining one-time UI
|
||||
// initialization is also done. At the end of the constructor a method
|
||||
// initialise_models() is called to load the UI with the current
|
||||
// settings values.
|
||||
//
|
||||
// 2) When the settings UI is displayed by a client calling the exec()
|
||||
// operation, only temporary state need be stored as the UI state will
|
||||
// already mirror the publicly visible settings state.
|
||||
//
|
||||
// 3) As the user makes changes to the settings UI only validation
|
||||
// need be carried out since the UI control data models are used as
|
||||
// the temporary store of unconfirmed settings. As some settings will
|
||||
// depend on each other a validate() operation is available, this
|
||||
// operations implements a check of any complex multi-field values.
|
||||
//
|
||||
// 4) If the user discards the settings changes by dismissing the UI
|
||||
// with the "Cancel" button; the reject() operation is called. The
|
||||
// reject() operation calls initialise_models() which will revert all
|
||||
// the UI visible state to the values as at the initial exec()
|
||||
// operation. No changes are moved into the data fields in
|
||||
// Configuration::impl that reflect the settings state published by
|
||||
// the public interface (Configuration.hpp).
|
||||
//
|
||||
// 5) If the user accepts the settings changes by dismissing the UI
|
||||
// with the "OK" button; the accept() operation is called which calls
|
||||
// the validate() operation again and, if it passes, the fields that
|
||||
// are used to deliver the settings state are updated from the UI
|
||||
// control models or other temporary state variables. At the end of
|
||||
// the accept() operation, just before hiding the UI and returning
|
||||
// control to the caller; the new settings values are stored into the
|
||||
// settings database by a call to the write_settings() operation, thus
|
||||
// ensuring that settings changes are saved even if the application
|
||||
// crashes or is subsequently killed.
|
||||
//
|
||||
// 6) On destruction, which only happens when the application
|
||||
// terminates, the settings are saved to the settings database by
|
||||
// calling the write_settings() operation. This is largely redundant
|
||||
// but is still done to save the default values of any new settings on
|
||||
// an initial run.
|
||||
//
|
||||
// To add a new setting:
|
||||
//
|
||||
// 1) Update the UI with the new widget to view and change the value.
|
||||
//
|
||||
// 2) Add a member to Configuration::impl to store the accepted
|
||||
// setting state. If the setting state is dynamic; add a new signal to
|
||||
// broadcast the setting value.
|
||||
//
|
||||
// 3) Add a query method to the public interface (Configuration.hpp)
|
||||
// to access the new setting value. If the settings is dynamic; this
|
||||
// step is optional since value changes will be broadcast via a
|
||||
// signal.
|
||||
//
|
||||
// 4) Add a forwarding operation to implement the new query (3) above.
|
||||
//
|
||||
// 5) Add a settings read call to read_settings() with a sensible
|
||||
// default value. If the setting value is dynamic, add a signal emit
|
||||
// call to broadcast the setting value change.
|
||||
//
|
||||
// 6) Add code to initialise_models() to load the widget control's
|
||||
// data model with the current setting value.
|
||||
//
|
||||
// 7) Add any required inter-field validation to the validate()
|
||||
// operation.
|
||||
//
|
||||
// 8) Add code to the accept() operation to extract the setting value
|
||||
// from the widget control data model and load it into the
|
||||
// Configuration::impl member that reflects the publicly visible
|
||||
// setting state. If the setting value is dynamic; add a signal emit
|
||||
// call to broadcast any changed state of the setting.
|
||||
//
|
||||
// 9) Add a settings write call to save the setting value to the
|
||||
// settings database.
|
||||
//
|
||||
|
||||
#include <stdexcept>
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
|
@ -36,7 +36,9 @@ class QStringListModel;
|
||||
// functions are blocking.
|
||||
//
|
||||
// All user settings required by the wsjtx GUI are exposed through
|
||||
// query methods.
|
||||
// query methods. Settings only become visible once they have been
|
||||
// accepted by the user which is done by clicking the "OK" button on
|
||||
// the settings dialog.
|
||||
//
|
||||
// The QSettings instance passed to the constructor is used to read
|
||||
// and write user settings.
|
||||
|
Loading…
Reference in New Issue
Block a user