mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-23 15:25:35 +08:00
390 lines
12 KiB
C++
390 lines
12 KiB
C++
// SPDX-FileCopyrightText: Copyright (C) 2015 swift Project Community / Contributors
|
|
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
|
|
|
|
#include "blackgui/components/simulatorselector.h"
|
|
#include "blackgui/guiapplication.h"
|
|
#include "blackgui/guiutility.h"
|
|
#include "blackcore/context/contextsimulator.h"
|
|
#include "blackmisc/icons.h"
|
|
#include "blackmisc/mixin/mixincompare.h"
|
|
#include "blackconfig/buildconfig.h"
|
|
#include "ui_simulatorselector.h"
|
|
|
|
#include <QCheckBox>
|
|
#include <QRadioButton>
|
|
#include <QWidget>
|
|
#include <QtGlobal>
|
|
#include <QPointer>
|
|
|
|
using namespace BlackConfig;
|
|
using namespace BlackMisc;
|
|
using namespace BlackMisc::Simulation;
|
|
using namespace BlackCore::Context;
|
|
|
|
namespace BlackGui::Components
|
|
{
|
|
CSimulatorSelector::CSimulatorSelector(QWidget *parent) : QFrame(parent),
|
|
ui(new Ui::CSimulatorSelector)
|
|
{
|
|
ui->setupUi(this);
|
|
|
|
this->addComboxBoxValues();
|
|
this->setMode(CheckBoxes, true);
|
|
|
|
connect(ui->rb_FS9, &QRadioButton::toggled, this, &CSimulatorSelector::radioButtonChanged);
|
|
connect(ui->rb_FSX, &QRadioButton::toggled, this, &CSimulatorSelector::radioButtonChanged);
|
|
connect(ui->rb_P3D, &QRadioButton::toggled, this, &CSimulatorSelector::radioButtonChanged);
|
|
connect(ui->rb_FG, &QRadioButton::toggled, this, &CSimulatorSelector::radioButtonChanged);
|
|
connect(ui->rb_XPlane, &QRadioButton::toggled, this, &CSimulatorSelector::radioButtonChanged);
|
|
|
|
connect(ui->cb_FS9, &QRadioButton::toggled, this, &CSimulatorSelector::checkBoxChanged);
|
|
connect(ui->cb_FSX, &QRadioButton::toggled, this, &CSimulatorSelector::checkBoxChanged);
|
|
connect(ui->cb_P3D, &QRadioButton::toggled, this, &CSimulatorSelector::checkBoxChanged);
|
|
connect(ui->cb_FG, &QRadioButton::toggled, this, &CSimulatorSelector::checkBoxChanged);
|
|
connect(ui->cb_XPlane, &QRadioButton::toggled, this, &CSimulatorSelector::checkBoxChanged);
|
|
|
|
connect(ui->cb_Simulators, &QComboBox::currentTextChanged, this, &CSimulatorSelector::comboBoxChanged);
|
|
}
|
|
|
|
CSimulatorSelector::~CSimulatorSelector()
|
|
{}
|
|
|
|
void CSimulatorSelector::setMode(CSimulatorSelector::Mode mode, bool forced)
|
|
{
|
|
if (m_mode == mode && !forced) { return; }
|
|
m_mode = mode;
|
|
|
|
ui->wi_CheckBoxes->setVisible(false);
|
|
ui->wi_RadioButtons->setVisible(false);
|
|
ui->wi_ComboBox->setVisible(false);
|
|
|
|
switch (mode)
|
|
{
|
|
default:
|
|
case CheckBoxes: ui->wi_CheckBoxes->setVisible(true); break;
|
|
case RadioButtons: ui->wi_RadioButtons->setVisible(true); break;
|
|
case ComboBox: ui->wi_ComboBox->setVisible(true); break;
|
|
}
|
|
this->setToLastSelection();
|
|
}
|
|
|
|
CSimulatorInfo CSimulatorSelector::getValue() const
|
|
{
|
|
if (m_noSelectionMeansAll && this->isUnselected()) { return CSimulatorInfo::allSimulators(); }
|
|
|
|
switch (m_mode)
|
|
{
|
|
default:
|
|
case CheckBoxes: return CSimulatorInfo(ui->cb_FSX->isChecked(), ui->cb_FS9->isChecked(), ui->cb_XPlane->isChecked(), ui->cb_P3D->isChecked(), ui->cb_FG->isChecked());
|
|
case RadioButtons: return CSimulatorInfo(ui->rb_FSX->isChecked(), ui->rb_FS9->isChecked(), ui->rb_XPlane->isChecked(), ui->rb_P3D->isChecked(), ui->rb_FG->isChecked());
|
|
case ComboBox: return CSimulatorInfo(ui->cb_Simulators->currentText());
|
|
}
|
|
}
|
|
|
|
void CSimulatorSelector::setValue(const CSimulatorInfo &simulator)
|
|
{
|
|
const CSimulatorInfo current(this->getValue());
|
|
if (simulator == current) { return; } // avoid unnecessary signals
|
|
|
|
// checkboxes
|
|
ui->cb_FSX->setChecked(simulator.isFSX());
|
|
ui->cb_FS9->setChecked(simulator.isFS9());
|
|
ui->cb_XPlane->setChecked(simulator.isXPlane());
|
|
ui->cb_P3D->setChecked(simulator.isP3D());
|
|
ui->cb_FG->setChecked(simulator.isFG());
|
|
|
|
// Combo
|
|
ui->cb_Simulators->setCurrentText(simulator.toQString(true));
|
|
|
|
// radio buttons
|
|
if (simulator.isFSX())
|
|
{
|
|
ui->rb_FSX->setChecked(simulator.isFSX());
|
|
return;
|
|
}
|
|
if (simulator.isFS9())
|
|
{
|
|
ui->rb_FS9->setChecked(simulator.isFS9());
|
|
return;
|
|
}
|
|
if (simulator.isXPlane())
|
|
{
|
|
ui->rb_XPlane->setChecked(simulator.isXPlane());
|
|
return;
|
|
}
|
|
if (simulator.isP3D())
|
|
{
|
|
ui->rb_P3D->setChecked(simulator.isP3D());
|
|
return;
|
|
}
|
|
if (simulator.isFG())
|
|
{
|
|
ui->rb_FG->setChecked(simulator.isFG());
|
|
return;
|
|
}
|
|
}
|
|
|
|
void CSimulatorSelector::setToLastSelection()
|
|
{
|
|
const CSimulatorInfo simulator = (m_mode == RadioButtons || m_mode == ComboBox) ?
|
|
m_currentSimulator.get() :
|
|
m_currentSimulators.get();
|
|
this->setValue(simulator);
|
|
}
|
|
|
|
void CSimulatorSelector::setToConnectedSimulator(bool makeReadOnly)
|
|
{
|
|
if (sGui && sGui->supportsContexts() && sGui->getIContextSimulator())
|
|
{
|
|
const CSimulatorPluginInfo pluginInfo = sGui->getIContextSimulator()->getSimulatorPluginInfo();
|
|
if (!this->isSingleSelection()) { this->setMode(RadioButtons); } // only one sim can be connected
|
|
|
|
if (pluginInfo.isValid())
|
|
{
|
|
this->setReadOnly(makeReadOnly);
|
|
this->setValue(pluginInfo.getSimulator());
|
|
}
|
|
else
|
|
{
|
|
if (makeReadOnly) { this->setReadOnly(false); }
|
|
const CSimulatorInfo simulator = sGui->getIContextSimulator()->getModelSetLoaderSimulator();
|
|
if (simulator.isSingleSimulator())
|
|
{
|
|
this->setValue(simulator);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (makeReadOnly) { this->setReadOnly(false); }
|
|
}
|
|
}
|
|
|
|
void CSimulatorSelector::setToConnectedSimulator(int deferredMs, bool makeReadOnly)
|
|
{
|
|
if (deferredMs < 1)
|
|
{
|
|
this->setToConnectedSimulator(makeReadOnly);
|
|
return;
|
|
}
|
|
|
|
if (!sGui || sGui->isShuttingDown()) { return; }
|
|
QPointer<CSimulatorSelector> myself(this);
|
|
QTimer::singleShot(deferredMs, this, [=] {
|
|
if (!sGui || sGui->isShuttingDown() || !myself) { return; }
|
|
this->setToConnectedSimulator(makeReadOnly);
|
|
});
|
|
}
|
|
|
|
void CSimulatorSelector::setFsxP3DOnly()
|
|
{
|
|
ui->cb_FS9->setVisible(false);
|
|
ui->cb_XPlane->setVisible(false);
|
|
ui->cb_FG->setVisible(false);
|
|
ui->rb_FS9->setVisible(false);
|
|
ui->rb_XPlane->setVisible(false);
|
|
ui->rb_FG->setVisible(false);
|
|
}
|
|
|
|
void CSimulatorSelector::enableFG(bool enabled)
|
|
{
|
|
ui->cb_FG->setVisible(enabled);
|
|
ui->rb_FG->setVisible(enabled);
|
|
ui->cb_FG->setChecked(false);
|
|
ui->rb_FG->setChecked(false);
|
|
}
|
|
|
|
void CSimulatorSelector::checkAll()
|
|
{
|
|
// checkboxes
|
|
ui->cb_FSX->setChecked(true);
|
|
ui->cb_FS9->setChecked(true);
|
|
ui->cb_XPlane->setChecked(true);
|
|
ui->cb_P3D->setChecked(true);
|
|
ui->cb_FG->setChecked(true);
|
|
|
|
// radio
|
|
ui->rb_P3D->setChecked(true);
|
|
}
|
|
|
|
void CSimulatorSelector::uncheckAll()
|
|
{
|
|
// checkboxes
|
|
ui->cb_FSX->setChecked(false);
|
|
ui->cb_FS9->setChecked(false);
|
|
ui->cb_XPlane->setChecked(false);
|
|
ui->cb_P3D->setChecked(false);
|
|
ui->cb_FG->setChecked(false);
|
|
}
|
|
|
|
bool CSimulatorSelector::isUnselected() const
|
|
{
|
|
bool c = false;
|
|
switch (m_mode)
|
|
{
|
|
default:
|
|
case CheckBoxes:
|
|
c = ui->cb_FSX->isChecked() || ui->cb_FS9->isChecked() || ui->cb_XPlane->isChecked() || ui->cb_P3D->isChecked() || ui->cb_FG->isChecked();
|
|
break;
|
|
case RadioButtons:
|
|
c = ui->rb_FSX->isChecked() || ui->rb_FS9->isChecked() || ui->rb_XPlane->isChecked() || ui->rb_P3D->isChecked() || ui->rb_FG->isChecked();
|
|
break;
|
|
case ComboBox:
|
|
const int i = ui->cb_Simulators->currentIndex();
|
|
c = i < 0;
|
|
break;
|
|
}
|
|
return !c;
|
|
}
|
|
|
|
bool CSimulatorSelector::areAllSelected() const
|
|
{
|
|
bool c = false;
|
|
switch (m_mode)
|
|
{
|
|
default:
|
|
case CheckBoxes:
|
|
c = ui->cb_FSX->isChecked() && ui->cb_FS9->isChecked() && ui->cb_XPlane->isChecked() && ui->cb_P3D->isChecked() && ui->cb_FG->isChecked();
|
|
break;
|
|
case RadioButtons:
|
|
// actually this should never be true
|
|
c = false;
|
|
break;
|
|
case ComboBox:
|
|
// actually this should never be true
|
|
c = false;
|
|
break;
|
|
}
|
|
return c;
|
|
}
|
|
|
|
void CSimulatorSelector::setLeftMargin(int margin)
|
|
{
|
|
QMargins m = ui->hl_RadioButtons->contentsMargins();
|
|
m.setLeft(margin);
|
|
ui->hl_RadioButtons->setContentsMargins(m);
|
|
|
|
m = ui->hl_CheckBoxes->contentsMargins();
|
|
m.setLeft(margin);
|
|
ui->hl_CheckBoxes->setContentsMargins(m);
|
|
}
|
|
|
|
void CSimulatorSelector::setRememberSelectionAndSetToLastSelection()
|
|
{
|
|
this->setRememberSelection(true);
|
|
this->setToLastSelection();
|
|
}
|
|
|
|
void CSimulatorSelector::clear()
|
|
{
|
|
if (m_mode == CheckBoxes)
|
|
{
|
|
this->uncheckAll();
|
|
}
|
|
}
|
|
|
|
bool CSimulatorSelector::isSingleSelection() const
|
|
{
|
|
return m_mode == RadioButtons || m_mode == ComboBox;
|
|
}
|
|
|
|
void CSimulatorSelector::setReadOnly(bool readOnly)
|
|
{
|
|
CGuiUtility::checkBoxesReadOnly(this, readOnly);
|
|
ui->rb_FSX->setEnabled(!readOnly);
|
|
ui->rb_FS9->setEnabled(!readOnly);
|
|
ui->rb_XPlane->setEnabled(!readOnly);
|
|
ui->rb_P3D->setEnabled(!readOnly);
|
|
ui->rb_FG->setEnabled(!readOnly);
|
|
|
|
ui->cb_Simulators->setEnabled(!readOnly);
|
|
|
|
this->setEnabled(!readOnly);
|
|
}
|
|
|
|
void CSimulatorSelector::radioButtonChanged(bool checked)
|
|
{
|
|
if (m_mode != RadioButtons) { return; }
|
|
if (!checked) { return; } // only the checked ones are relevant, as the unchecked ones are accompanied with checked events
|
|
m_digestButtonsChanged.inputSignal();
|
|
}
|
|
|
|
void CSimulatorSelector::checkBoxChanged(bool checked)
|
|
{
|
|
if (m_mode != CheckBoxes) { return; }
|
|
Q_UNUSED(checked);
|
|
m_digestButtonsChanged.inputSignal();
|
|
}
|
|
|
|
void CSimulatorSelector::comboBoxChanged(const QString &value)
|
|
{
|
|
if (m_mode != ComboBox) { return; }
|
|
Q_UNUSED(value);
|
|
m_digestButtonsChanged.inputSignal();
|
|
}
|
|
|
|
void CSimulatorSelector::rememberSelection()
|
|
{
|
|
if (!m_rememberSelection) { return; }
|
|
if (this->isSingleSelection())
|
|
{
|
|
// single
|
|
const CSimulatorInfo sim = this->getValue();
|
|
m_currentSimulator.set(sim);
|
|
}
|
|
else
|
|
{
|
|
// multiple
|
|
const CSimulatorInfo sim = this->getValue();
|
|
m_currentSimulators.set(sim);
|
|
}
|
|
}
|
|
|
|
void CSimulatorSelector::changedLastSelection()
|
|
{
|
|
// force decoupled update
|
|
this->triggerSetToLastSelection();
|
|
}
|
|
|
|
void CSimulatorSelector::changedLastSelectionRb()
|
|
{
|
|
// force decoupled update
|
|
if (m_mode != RadioButtons) { return; }
|
|
this->triggerSetToLastSelection();
|
|
}
|
|
|
|
void CSimulatorSelector::changedLastSelectionCb()
|
|
{
|
|
// force decoupled update
|
|
if (m_mode != CheckBoxes) { return; }
|
|
this->triggerSetToLastSelection();
|
|
}
|
|
|
|
void CSimulatorSelector::triggerSetToLastSelection()
|
|
{
|
|
QPointer<CSimulatorSelector> myself(this);
|
|
QTimer::singleShot(100, this, [=] {
|
|
if (!myself) { return; }
|
|
this->setToLastSelection();
|
|
});
|
|
}
|
|
|
|
void CSimulatorSelector::emitChangedSignal()
|
|
{
|
|
const CSimulatorInfo simulator(this->getValue());
|
|
this->rememberSelection();
|
|
emit this->changed(simulator);
|
|
}
|
|
|
|
void CSimulatorSelector::addComboxBoxValues()
|
|
{
|
|
int cbi = 0;
|
|
ui->cb_Simulators->clear();
|
|
ui->cb_Simulators->insertItem(cbi++, CSimulatorInfo::fs9().toQString());
|
|
ui->cb_Simulators->insertItem(cbi++, CSimulatorInfo::fsx().toQString());
|
|
ui->cb_Simulators->insertItem(cbi++, CSimulatorInfo::p3d().toQString());
|
|
ui->cb_Simulators->insertItem(cbi++, CSimulatorInfo::xplane().toQString());
|
|
ui->cb_Simulators->insertItem(cbi++, CSimulatorInfo::fg().toQString());
|
|
}
|
|
} // ns
|