LoadoutManager
LoadoutManager is the singleton that owns the persistent collection
of HardwareLoadout records and the FTMW presets they
contain. It is the sole writer of the Loadouts/ QSettings subtree:
every other component in the application observes loadouts through this
manager, and every CRUD operation funnels through one of its public
methods. Loadout-level changes propagate to the rest of the application
through the manager’s Qt signals; the user-facing model is described in
the Loadouts and
FTMW Presets chapters.
The manager loads every known loadout into an in-memory QHash cache
during construction, then services subsequent reads against that cache.
Writes update both the cache and QSettings under the appropriate
sub-group, then emit the matching loadoutAdded,
loadoutChanged, ftmwPresetChanged, or currentFtmwPresetChanged
signal so observing widgets can refresh. All public methods are
thread-safe via an internal QMutex; signals are emitted on the
thread of the caller that triggered the change.
Loadouts and FTMW presets are paired, but the manager exposes them
through separate CRUD surfaces: putLoadout / removeLoadout /
getLoadout for whole-loadout operations, and
putFtmwPreset / removeFtmwPreset / renameFtmwPreset for
individual preset operations within a named loadout. The
loadoutsMatchingHwKey helper supports the hardware-profile rename
flow by enumerating every loadout whose hardware map references a given
hardware key.
The __LastUsed__ sentinel
Each loadout reserves the preset name __LastUsed__
(BC::Store::LM::lastUsedFtmwPresetName) for an automatic sentinel
preset that captures the most recent fully accepted FTMW
configuration. The sentinel is hidden from all user-facing dropdowns
and is never user-deletable; ftmwPresetNames excludes it unless its
includeLastUsed flag is set.
The sentinel is updated only on two events:
FtmwConfigDialog::accept— when the user dismisses the FTMW configuration dialog with OK.Experiment start — when an experiment begins with the current FTMW configuration.
It is not updated on Apply, on Cancel, or on incidental edits
to the live configuration. The semantics ensure that, after restoring a
loadout, the application can fall back to __LastUsed__ to recover
the configuration the user most recently committed to, even if no named
preset matches.
QSettings storage layout
The keys that name each field and sub-group below are declared in the
BC::Store::LM namespace at the top of loadoutmanager.h. The
RF-side keys used inside rfClocks/ array entries belong to the
BC::Store::RFC namespace; the loadout-specific extensions of that
namespace are declared in hardwareloadout.h and documented on
HardwareLoadout.
Loadouts/
currentLoadout = "<name>"
defaultLoadout = "Default"
names/ # array of {name}
<name>/
name = "<name>"
hardwareMap/ # array of {key, value}
currentFtmwPreset = "<presetName>" # may be "__LastUsed__"
ftmwPresetNames/ # array of {name}
lastModified = <ISO timestamp>
ftmwPresets/
<presetName>/
rfScalars/
rfClocks/
chirpScalars/
chirpSegments/
chirpMarkers/
digiScalars/
digiAnalog/
digiDigital/
digiHwKey = "<hwKey>"
lastModified = <ISO timestamp>
The flattening from HardwareLoadout and
FtmwPreset into this layout is performed by the
BC::Loadout free-function helpers; see HardwareLoadout for
the helper signatures.
Relationship to other configuration singletons
LoadoutManager is one of three loosely coupled configuration
singletons. HardwareProfileManager owns profile metadata
and persistence; RuntimeHardwareConfig tracks which
profiles are active for the running session; LoadoutManager stores
named hardware maps and the FTMW presets that ride on top of them.
Switching the active loadout via the Hardware menu causes
RuntimeHardwareConfigDialog to drive
RuntimeHardwareConfig to the loadout’s stored hardware
map, after the drift-detection prompt described in
Loadouts.
API Reference
-
class LoadoutManager : public QObject, public SettingsStorage
Singleton that owns the persistent collection of
HardwareLoadoutrecords and their FTMW presets.LoadoutManageris the sole writer of theLoadouts/QSettings subtree. It loads every known loadout into an in-memory cache at construction, services CRUD operations against that cache, and flushes changes back to QSettings under the appropriate sub-groups. Read access is unrestricted; write access is funneled through the public CRUD methods, which emit Qt signals so the UI can refresh in response to changes from any caller.All public methods are thread-safe via an internal
QMutex. The helper signals (loadoutAdded,currentFtmwPresetChanged, etc.) are emitted on the thread of the caller that triggered the change.Public Functions
-
~LoadoutManager() override
-
QStringList loadoutNames() const
Names of all loadouts currently known to the manager.
-
bool loadoutExists(const QString &name) const
Whether a loadout with the given name exists in the cache.
-
std::optional<HardwareLoadout> getLoadout(const QString &name) const
Fetch a copy of the named loadout, or
std::nulloptif it does not exist.
-
bool putLoadout(const HardwareLoadout &loadout)
Insert or replace a loadout, persisting it to QSettings and emitting the appropriate signal.
-
bool removeLoadout(const QString &name)
Remove the named loadout, including all of its FTMW presets, from cache and QSettings.
-
QString currentLoadoutName() const
Name of the loadout marked active for the running session.
-
void setCurrentLoadoutName(const QString &name)
Set the active loadout, emitting
currentLoadoutChanged.
-
std::optional<HardwareLoadout> currentLoadout() const
Convenience accessor that returns the active loadout, if any.
-
QString defaultLoadoutName() const
Name of the loadout selected on application startup when no other selection is in force.
-
void setDefaultLoadoutName(const QString &name)
Set the default loadout, emitting
defaultLoadoutChanged.
-
std::optional<HardwareLoadout> defaultLoadout() const
Convenience accessor that returns the default loadout, if any.
-
QStringList loadoutsMatchingHwKey(const QString &hwKey) const
Names of all loadouts whose member set includes the given profile identity.
-
std::optional<FtmwPreset> getFtmwPreset(const QString &loadoutName, const QString &presetName) const
Fetch a copy of a named preset from the named loadout.
-
bool putFtmwPreset(const QString &loadoutName, const QString &presetName, const FtmwPreset &preset)
Insert or replace an FTMW preset in the named loadout.
-
bool removeFtmwPreset(const QString &loadoutName, const QString &presetName)
Remove the named preset from the named loadout. Cannot remove the active preset.
-
bool renameFtmwPreset(const QString &loadoutName, const QString &oldName, const QString &newName)
Rename a preset within the named loadout, updating the current-preset pointer if needed.
-
bool ftmwPresetExists(const QString &loadoutName, const QString &presetName) const
Whether the named loadout contains a preset with the given name.
-
QStringList ftmwPresetNames(const QString &loadoutName, bool includeLastUsed = false) const
Names of the FTMW presets owned by the named loadout.
- Parameters:
loadoutName – Loadout whose preset names should be returned.
includeLastUsed – If true, the
__LastUsed__sentinel is included in the returned list.
-
bool clearFtmwPresets(const QString &loadoutName)
Remove every FTMW preset from the named loadout.
-
QString currentFtmwPresetName(const QString &loadoutName) const
Name of the named loadout’s currently active FTMW preset.
-
bool setCurrentFtmwPresetName(const QString &loadoutName, const QString &presetName)
Set the active FTMW preset for the named loadout, emitting
currentFtmwPresetChanged.
-
std::optional<FtmwPreset> currentFtmwPreset(const QString &loadoutName) const
Convenience accessor that returns the named loadout’s active preset, if any.
Signals
-
void loadoutAdded(QString name)
Emitted after a new loadout is inserted into the cache.
-
void loadoutRemoved(QString name)
Emitted after a loadout is removed from the cache.
-
void loadoutChanged(QString name)
Emitted after the contents of an existing loadout are replaced.
-
void currentLoadoutChanged(QString name)
Emitted after the active loadout selection changes.
-
void defaultLoadoutChanged(QString name)
Emitted after the default loadout selection changes.
-
void ftmwPresetAdded(QString loadoutName, QString presetName)
Emitted after a new FTMW preset is added to a loadout.
-
void ftmwPresetRemoved(QString loadoutName, QString presetName)
Emitted after an FTMW preset is removed from a loadout.
-
void ftmwPresetChanged(QString loadoutName, QString presetName)
Emitted after an FTMW preset’s contents are replaced.
-
void currentFtmwPresetChanged(QString loadoutName, QString presetName)
Emitted after a loadout’s active FTMW preset selection changes.
Public Static Functions
-
static LoadoutManager &instance()
Access the process-wide singleton.
Private Functions
-
LoadoutManager()
-
LoadoutManager(QAnyStringView orgName, QAnyStringView appName)
-
void p_loadAll()
-
HardwareLoadout p_readLoadout(const QString &name) const
-
void p_writeLoadout(const HardwareLoadout &loadout)
-
void p_removeFromSettings(const QString &name)
-
void p_syncIndex()
-
FtmwPreset p_readFtmwPreset(const QString &loadoutName, const QString &presetName) const
-
void p_writeFtmwPreset(const QString &loadoutName, const QString &presetName, const FtmwPreset &preset)
-
void p_removeFtmwPresetFromSettings(const QString &loadoutName, const QString &presetName)
-
void p_syncFtmwPresetIndex(const QString &loadoutName)
-
void p_writeFtmwPresetPointers(const QString &loadoutName)
Private Members
-
QHash<QString, HardwareLoadout> d_loadouts
-
QString d_current
-
QString d_default
-
mutable QMutex d_mutex
Private Static Attributes
-
static LoadoutManager *s_instance = nullptr
Friends
- friend class LoadoutManagerTest
-
class LoadoutHelper : public SettingsStorage
Public Functions
-
inline LoadoutHelper(const QStringList &keys)
Friends
- friend class LoadoutManager
-
inline LoadoutHelper(const QStringList &keys)
-
~LoadoutManager() override
-
namespace LM
QSettings field keys for the
LoadoutManagerstorage tree.All loadout state is persisted under the top-level
Loadouts/group named bykey. The remaining identifiers name the scalar fields and array sub-groups used byLoadoutManagerand theBC::Loadoutfree-function helpers.lastUsedFtmwPresetNameis the reserved name used for the per-loadout__LastUsed__sentinel preset.Variables
-
constexpr QLatin1StringView key = {"Loadouts"}
Top-level QSettings group that holds all loadout state.
-
constexpr QLatin1StringView current = {"currentLoadout"}
Field that stores the active loadout name.
-
constexpr QLatin1StringView defaultName = {"defaultLoadout"}
Field that stores the default loadout name.
-
constexpr QLatin1StringView namesKey = {"names"}
Array group that lists all known loadout names.
-
constexpr QLatin1StringView nameField = {"name"}
Field used inside name-array entries to hold the loadout or preset name.
-
constexpr QLatin1StringView hwMapKey = {"hardwareMap"}
Array group that holds the loadout’s hardware map entries.
-
constexpr QLatin1StringView digiHwKeyField = {"DigiHwKey"}
Field that records which digitizer hardware key a preset was captured against.
-
constexpr QLatin1StringView rfScalarsKey = {"rfScalars"}
Sub-group that holds an FTMW preset’s RF scalar fields.
-
constexpr QLatin1StringView rfClocksKey = {"rfClocks"}
Array group that holds an FTMW preset’s RF clock entries.
-
constexpr QLatin1StringView chirpScalarsKey = {"chirpScalars"}
Sub-group that holds an FTMW preset’s chirp scalar fields.
-
constexpr QLatin1StringView chirpSegmentsKey = {"chirpSegments"}
Array group that holds an FTMW preset’s chirp segment table.
-
constexpr QLatin1StringView chirpMarkersKey = {"chirpMarkers"}
Array group that holds an FTMW preset’s chirp marker table.
-
constexpr QLatin1StringView digiScalarsKey = {"digiScalars"}
Sub-group that holds an FTMW preset’s digitizer scalar fields.
-
constexpr QLatin1StringView digiAnalogKey = {"digiAnalog"}
Array group that holds an FTMW preset’s digitizer analog channel entries.
-
constexpr QLatin1StringView digiDigitalKey = {"digiDigital"}
Array group that holds an FTMW preset’s digitizer digital channel entries.
-
constexpr QLatin1StringView ftmwPresetsKey = {"ftmwPresets"}
Sub-group under each loadout that holds its FTMW presets.
-
constexpr QLatin1StringView ftmwPresetNamesKey = {"ftmwPresetNames"}
Array group that lists the FTMW preset names owned by a loadout.
-
constexpr QLatin1StringView currentFtmwPresetKey = {"currentFtmwPreset"}
Field that names a loadout’s currently active FTMW preset.
-
constexpr QLatin1StringView lastModifiedKey = {"lastModified"}
Field that records the last-modified timestamp of a loadout or preset.
-
constexpr QLatin1StringView lastUsedFtmwPresetName = {"__LastUsed__"}
Reserved preset name used for the per-loadout last-used sentinel.
-
constexpr QLatin1StringView key = {"Loadouts"}