Skip to content

Commit

Permalink
[Companion] Radio conversion improvements (opentx#5534)
Browse files Browse the repository at this point in the history
* Move MultiposPots & MultiposPotsPositions capability lookups and getAnalogInputName() to Boards class.

* Add RawSource::isAvailable() and RawSwitch::isAvailable(); Add board type param to various RawSource lookup functions.

* Add CustomFunctionData::toString(), FlightModeData::toString(), FactoryInstalledPots board capability, MAX_SWITCH_TYPE, & break out GeneralSettings source/switch defaults to own function.

* Add RadioDataConversionState class for tracking conversion actions.

* Implement RadioDataConversionState handler, add conversion process report, and improve/fix conversion issues:
    * Make sure all switches/pots/knobs have default configs for destination board type;
    * Try to move more custom control names, intelligently;
    * Convert model timers and throttle source;
    * Adjust for Horus 6P switch in place of Taranis S2 knob;
    * Adjust for extra sliders on X12 and X9E to move LS and RS to proper slots as needed;
    * Make sure ALL controls are validated, eg. to always account for extra trims/analogs/switches/etc which don't exist on destination;
    * Properly indicate invalid RawSource::toString() items with "???".

* Allow user to cancel out of file conversions & provide ample warnings if switching radio type/profile with unsaved file(s) still open;
Also: Fix bug with some orphaned MdiChild windows never being deleted; Create static bool Storage::isBoardCompatible(b1, b2).

* Add maxLibQt "stub" (will not compile).

* Add ExportableTableView for better presentation of conversion results table.

* Move getFourCC() and isBoardCompatible() to Boards class.
  • Loading branch information
mpaperno authored and bsongis committed Dec 18, 2017
1 parent e63a877 commit 0dbad18
Show file tree
Hide file tree
Showing 25 changed files with 1,528 additions and 412 deletions.
8 changes: 5 additions & 3 deletions companion/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ set(common_SRCS
eeprominterface.cpp
helpers.cpp
radiodata.cpp
radiodataconversionstate.cpp
translations.cpp
firmwares/er9x/er9xeeprom.cpp
firmwares/er9x/er9xinterface.cpp
Expand Down Expand Up @@ -207,6 +208,7 @@ add_subdirectory(generaledit)
add_subdirectory(simulation)
add_subdirectory(storage)
add_subdirectory(thirdparty/qcustomplot)
add_subdirectory(thirdparty/maxlibqt/src/widgets)

############# Companion ###############

Expand Down Expand Up @@ -305,7 +307,7 @@ qt5_wrap_cpp(companion_SRCS ${companion_MOC_HDRS})

add_executable(${COMPANION_NAME} MACOSX_BUNDLE ${WIN_EXECUTABLE_TYPE} ${companion_SRCS} ${icon_RC})
qt5_use_modules(${COMPANION_NAME} Core Widgets Network)
target_link_libraries(${COMPANION_NAME} PRIVATE generaledit modeledit simulation ${CPN_COMMON_LIB} qcustomplot shared storage ${PTHREAD_LIBRARY} ${SDL_LIBRARY} ${WIN_LINK_LIBRARIES})
target_link_libraries(${COMPANION_NAME} PRIVATE generaledit modeledit simulation ${CPN_COMMON_LIB} maxLibQtWidgets qcustomplot shared storage ${PTHREAD_LIBRARY} ${SDL_LIBRARY} ${WIN_LINK_LIBRARIES})

PrintTargetReport("${COMPANION_NAME}")

Expand Down Expand Up @@ -528,9 +530,9 @@ IF(APPLE)
get_filename_component(AVRDUDECONF_ABSOLUTE_PATH ${AVRDUDE_CONF} REALPATH)
install(PROGRAMS ${DFU_UTIL_ABSOLUTE_PATH} ${AVRDUDE_ABSOLUTE_PATH} DESTINATION ${companion_res_dir} COMPONENT Runtime)
install(FILES ${AVRDUDECONF_ABSOLUTE_PATH} DESTINATION ${companion_res_dir} COMPONENT Runtime)

set(bundle_tools_path "\${CMAKE_INSTALL_PREFIX}/${companion_res_dir}/dfu-util;\${CMAKE_INSTALL_PREFIX}/${companion_res_dir}/avrdude")


# Include depencies (adding frameworks, fixing the embbeded libraries)
# I get write errors without setting BU_CHMOD_BUNDLE_ITEMS even though it is
Expand Down
49 changes: 41 additions & 8 deletions companion/src/apppreferencesdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,24 +23,25 @@
#include "mainwindow.h"
#include "appdata.h"
#include "helpers.h"
#include "storage.h"
#if defined(JOYSTICKS)
#include "joystick.h"
#include "joystickdialog.h"
#endif

AppPreferencesDialog::AppPreferencesDialog(QWidget * parent) :
QDialog(parent),
updateLock(false),
mainWinHasDirtyChild(false),
ui(new Ui::AppPreferencesDialog)
{
ui->setupUi(this);
updateLock=false;
setWindowIcon(CompanionIcon("apppreferences.png"));

initSettings();
connect(ui->downloadVerCB, SIGNAL(currentIndexChanged(int)), this, SLOT(baseFirmwareChanged()));
connect(ui->opt_appDebugLog, &QCheckBox::toggled, this, &AppPreferencesDialog::toggleAppLogSettings);
connect(ui->opt_fwTraceLog, &QCheckBox::toggled, this, &AppPreferencesDialog::toggleAppLogSettings);
connect(this, SIGNAL(accepted()), this, SLOT(writeValues()));

#if !defined(JOYSTICKS)
ui->joystickCB->hide();
Expand All @@ -58,7 +59,12 @@ AppPreferencesDialog::~AppPreferencesDialog()
delete ui;
}

void AppPreferencesDialog::writeValues()
void AppPreferencesDialog::setMainWinHasDirtyChild(bool value)
{
mainWinHasDirtyChild = value;
}

void AppPreferencesDialog::accept()
{
g.autoCheckApp(ui->autoCheckCompanion->isChecked());
g.OpenTxBranch(DownloadBranchType(ui->OpenTxBranch->currentIndex()));
Expand Down Expand Up @@ -102,15 +108,42 @@ void AppPreferencesDialog::writeValues()
else
g.profile[g.id()].name(ui->profileNameLE->text());

bool fwchange = false;
Firmware * newFw = getFirmwareVariant();
// If a new fw type has been choosen, several things need to reset
Firmware::setCurrentVariant(getFirmwareVariant());
QString id = Firmware::getCurrentVariant()->getId();
if (g.profile[g.id()].fwType() != id) {
if (Firmware::getCurrentVariant()->getId() != newFw->getId()) {
// check if we're going to be converting to a new radio type and there are unsaved files in the main window
if (mainWinHasDirtyChild && !Boards::isBoardCompatible(Firmware::getCurrentVariant()->getBoard(), newFw->getBoard())) {
QString q = tr("<p><b>You cannot switch Radio Type or change Build Options while there are unsaved file changes. What do you wish to do?</b></p> <ul>" \
"<li><i>Save All</i> - Save any open file(s) before saving Settings.<li>" \
"<li><i>Reset</i> - Revert to the previous Radio Type and Build Options before saving Settings.</li>" \
"<li><i>Cancel</i> - Return to the Settings editor dialog.</li></ul>");
int resp = QMessageBox::question(this, windowTitle(), q, (QMessageBox::SaveAll | QMessageBox::Reset | QMessageBox::Cancel), QMessageBox::Cancel);
if (resp == QMessageBox::SaveAll) {
// signal main window to save files, need to do this before the fw actually changes
emit firmwareProfileAboutToChange();
}
else if (resp == QMessageBox::Reset) {
// bail out early before saving the radio type & firmware options
QDialog::accept();
return;
}
else {
// we do not accept the dialog close
return;
}
}
Firmware::setCurrentVariant(newFw);
g.profile[g.id()].fwName("");
g.profile[g.id()].initFwVariables();
g.profile[g.id()].fwType(id);
emit firmwareProfileChanged(g.id());
g.profile[g.id()].fwType(newFw->getId());
fwchange = true;
}

QDialog::accept();

if (fwchange)
emit firmwareProfileChanged(g.id()); // important to do this after the accepted() signal
}

void AppPreferencesDialog::on_snapshotPathButton_clicked()
Expand Down
8 changes: 7 additions & 1 deletion companion/src/apppreferencesdialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,21 @@ class AppPreferencesDialog : public QDialog
public:
explicit AppPreferencesDialog(QWidget * parent = 0);
~AppPreferencesDialog();

Joystick * joystick;

public slots:
void accept() Q_DECL_OVERRIDE;
void setMainWinHasDirtyChild(bool value);

signals:
void firmwareProfileChanged(int profId);
void firmwareProfileAboutToChange(bool saveFiles = true);

private:
QList<QCheckBox *> optionsCheckBoxes;
bool updateLock;
bool mainWinHasDirtyChild;
void showVoice(bool);
void showVoice();
void hideVoice();
Expand All @@ -64,7 +71,6 @@ class AppPreferencesDialog : public QDialog
void firmwareOptionChanged(bool state);
void toggleAppLogSettings();

void writeValues();
void on_libraryPathButton_clicked();
void on_snapshotPathButton_clicked();
void on_snapshotClipboardCKB_clicked();
Expand Down
124 changes: 124 additions & 0 deletions companion/src/boards.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,32 @@ void Boards::setBoardType(const Type & board)
m_boardType = BOARD_UNKNOWN;
}

uint32_t Boards::getFourCC(Type board)
{
switch (board) {
case BOARD_X12S:
return 0x3478746F;
case BOARD_X10:
return 0x3778746F;
case BOARD_TARANIS_X7:
return 0x3678746F;
case BOARD_TARANIS_X9E:
return 0x3578746F;
case BOARD_TARANIS_X9D:
case BOARD_TARANIS_X9DP:
return 0x3378746F;
case BOARD_SKY9X:
case BOARD_AR9X:
case BOARD_9XRPRO:
return 0x3278746F;
case BOARD_MEGA2560:
case BOARD_GRUVIN9X:
return 0x3178746F;
default:
return 0;
}
}

const int Boards::getEEpromSize(Board::Type board)
{
switch (board) {
Expand Down Expand Up @@ -177,6 +203,12 @@ const int Boards::getCapability(Board::Type board, Board::Capability capability)
else
return 3;

case FactoryInstalledPots:
if (IS_TARANIS_X9(board))
return 2;
else
return getCapability(board, Pots);

case Sliders:
if (IS_HORUS_X12S(board) || IS_TARANIS_X9E(board))
return 4;
Expand All @@ -191,6 +223,15 @@ const int Boards::getCapability(Board::Type board, Board::Capability capability)
else
return 0;

case MaxAnalogs:
return getCapability(board, Board::Sticks) + getCapability(board, Board::Pots) + getCapability(board, Board::Sliders) + getCapability(board, Board::MouseAnalogs);

case MultiposPots:
return IS_HORUS_OR_TARANIS(board) ? 3 : 0;

case MultiposPotsPositions:
return IS_HORUS_OR_TARANIS(board) ? 6 : 0;

case Switches:
if (IS_TARANIS_X9E(board))
return 18;
Expand Down Expand Up @@ -242,6 +283,89 @@ const QString Boards::getAxisName(int index)
return QObject::tr("Unknown");
}

const QString Boards::getAnalogInputName(Board::Type board, unsigned index)
{
if ((int)index < getBoardCapability(board, Board::Sticks)) {
const QString sticks[] = {
QObject::tr("Rud"),
QObject::tr("Ele"),
QObject::tr("Thr"),
QObject::tr("Ail")
};
return sticks[index];
}

index -= getCapability(board, Board::Sticks);

if (IS_9X(board) || IS_2560(board) || IS_SKY9X(board)) {
const QString pots[] = {
"P1",
"P2",
"P3"
};
if (index < DIM(pots))
return pots[index];
}
else if (IS_TARANIS_X9E(board)) {
const QString pots[] = {
"F1",
"F2",
"F3",
"F4",
"S1",
"S2",
"LS",
"RS"
};
if (index < DIM(pots))
return pots[index];
}
else if (IS_TARANIS(board)) {
const QString pots[] = {
"S1",
"S2",
"S3",
"LS",
"RS"
};
if (index < DIM(pots))
return pots[index];
}
else if (IS_HORUS_X12S(board)) {
const QString pots[] = {
"S1",
"6P",
"S2",
"L1",
"L2",
"LS",
"RS",
"JSx",
"JSy"
};
if (index < DIM(pots))
return pots[index];
}
else if (IS_HORUS_X10(board)) {
const QString pots[] = {
"S1",
"6P",
"S2",
"LS",
"RS"
};
if (index < DIM(pots))
return pots[index];
}

return "???";
}

const bool Boards::isBoardCompatible(Type board1, Type board2)
{
return (getFourCC(board1) == getFourCC(board2));
}

/* Currently unused
const QString Boards::getBoardName(Board::Type board)
Expand Down
19 changes: 15 additions & 4 deletions companion/src/boards.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,12 @@ namespace Board {
enum Capability {
Sticks,
Pots,
FactoryInstalledPots,
Sliders,
MouseAnalogs,
MaxAnalogs,
MultiposPots,
MultiposPotsPositions,
Switches,
SwitchPositions,
FactoryInstalledSwitches,
Expand Down Expand Up @@ -146,16 +150,22 @@ class Boards
void setBoardType(const Board::Type & board);
Board::Type getBoardType() const { return m_boardType; }

const int getEEpromSize() { return getEEpromSize(m_boardType); }
const int getFlashSize() { return getFlashSize(m_boardType); }
const Board::SwitchInfo getSwitchInfo(unsigned index) { return getSwitchInfo(m_boardType, index); }
const int getCapability(Board::Capability capability) { return getCapability(m_boardType, capability); }
const uint32_t getFourCC() const { return getFourCC(m_boardType); }
const int getEEpromSize() const { return getEEpromSize(m_boardType); }
const int getFlashSize() const { return getFlashSize(m_boardType); }
const Board::SwitchInfo getSwitchInfo(unsigned index) const { return getSwitchInfo(m_boardType, index); }
const int getCapability(Board::Capability capability) const { return getCapability(m_boardType, capability); }
const QString getAnalogInputName(unsigned index) const { return getAnalogInputName(m_boardType, index); }
const bool isBoardCompatible(Board::Type board2) const { return isBoardCompatible(m_boardType, board2); }

static uint32_t getFourCC(Board::Type board);
static const int getEEpromSize(Board::Type board);
static const int getFlashSize(Board::Type board);
static const Board::SwitchInfo getSwitchInfo(Board::Type board, unsigned index);
static const int getCapability(Board::Type board, Board::Capability capability);
static const QString getAxisName(int index);
static const QString getAnalogInputName(Board::Type board, unsigned index);
static const bool isBoardCompatible(Board::Type board1, Board::Type board2);

protected:

Expand All @@ -178,6 +188,7 @@ class Boards
#define IS_TARANIS_PLUS(board) (board==Board::BOARD_TARANIS_X9DP || board==Board::BOARD_TARANIS_X9E)
#define IS_TARANIS_X9E(board) (board==Board::BOARD_TARANIS_X9E)
#define IS_TARANIS(board) (IS_TARANIS_X9(board) || IS_TARANIS_X7(board))
#define IS_TARANIS_NOT_X9E(board) (IS_TARANIS(board) && !IS_TARANIS_X9E(board))
#define IS_HORUS_X12S(board) (board==Board::BOARD_X12S)
#define IS_HORUS_X10(board) (board==Board::BOARD_X10)
#define IS_HORUS(board) (IS_HORUS_X12S(board) || IS_HORUS_X10(board))
Expand Down
Loading

0 comments on commit 0dbad18

Please sign in to comment.