1
0
Fork 0
mirror of https://github.com/EdgeTX/edgetx.git synced 2025-07-24 00:35:14 +03:00

[Companion] MdiChild now use a QTreeWidget instead of a QListWidget (… (#4096)

* [Companion] MdiChild now use a QTreeWidget instead of a QListWidget (for Horus compatibility)

* [Companion] Horus models.txt parsing / writing implemented

* Fix for QT53 (#4109)
This commit is contained in:
Bertrand Songis 2016-12-08 21:26:08 +01:00 committed by GitHub
parent dd77670007
commit ec56d2dbdb
15 changed files with 443 additions and 385 deletions

View file

@ -1079,7 +1079,9 @@ class ModelData {
QVector<const MixData *> mixes(int channel) const; QVector<const MixData *> mixes(int channel) const;
bool used; bool used;
char category[15+1];
char name[15+1]; char name[15+1];
char filename[16+1];
TimerData timers[CPN_MAX_TIMERS]; TimerData timers[CPN_MAX_TIMERS];
bool noGlobalFunctions; bool noGlobalFunctions;
bool thrTrim; // Enable Throttle Trim bool thrTrim; // Enable Throttle Trim
@ -1208,7 +1210,8 @@ class GeneralSettings {
int calibMid[CPN_MAX_STICKS+CPN_MAX_POTS+CPN_MAX_MOUSE_ANALOGS]; int calibMid[CPN_MAX_STICKS+CPN_MAX_POTS+CPN_MAX_MOUSE_ANALOGS];
int calibSpanNeg[CPN_MAX_STICKS+CPN_MAX_POTS+CPN_MAX_MOUSE_ANALOGS]; int calibSpanNeg[CPN_MAX_STICKS+CPN_MAX_POTS+CPN_MAX_MOUSE_ANALOGS];
int calibSpanPos[CPN_MAX_STICKS+CPN_MAX_POTS+CPN_MAX_MOUSE_ANALOGS]; int calibSpanPos[CPN_MAX_STICKS+CPN_MAX_POTS+CPN_MAX_MOUSE_ANALOGS];
unsigned int currModel; // 0..15 unsigned int currModelIndex;
char currModelFilename[16+1];
unsigned int contrast; unsigned int contrast;
unsigned int vBatWarn; unsigned int vBatWarn;
int txVoltageCalibration; int txVoltageCalibration;
@ -1321,6 +1324,30 @@ class RadioData {
public: public:
GeneralSettings generalSettings; GeneralSettings generalSettings;
ModelData models[CPN_MAX_MODELS]; ModelData models[CPN_MAX_MODELS];
void setCurrentModel(unsigned int index)
{
generalSettings.currModelIndex = index;
strcpy(generalSettings.currModelFilename, models[index].filename);
}
QString getNextModelFilename()
{
char filename[sizeof(ModelData::filename)];
int index = 0;
bool found = true;
while (found) {
sprintf(filename, "model%d.bin", ++index);
found = false;
for (int i=0; i<CPN_MAX_MODELS; i++) {
if (strcmp(filename, models[i].filename) == 0) {
found = true;
break;
}
}
}
return filename;
}
}; };
enum Capability { enum Capability {

View file

@ -87,7 +87,7 @@ Er9xGeneral::operator GeneralSettings ()
result.calibSpanPos[i] = calibSpanPos[i]; result.calibSpanPos[i] = calibSpanPos[i];
} }
result.currModel = currModel; result.currModelIndex = currModel;
result.contrast = contrast; result.contrast = contrast;
result.vBatWarn = vBatWarn; result.vBatWarn = vBatWarn;
result.txVoltageCalibration = txVoltageCalibration; result.txVoltageCalibration = txVoltageCalibration;

View file

@ -99,7 +99,7 @@ Ersky9xGeneral::operator GeneralSettings ()
result.calibSpanPos[i] = calibSpanPos[i]; result.calibSpanPos[i] = calibSpanPos[i];
} }
result.currModel = currModel; result.currModelIndex = currModel;
result.contrast = contrast; result.contrast = contrast;
result.vBatWarn = vBatWarn; result.vBatWarn = vBatWarn;
result.txVoltageCalibration = txVoltageCalibration; result.txVoltageCalibration = txVoltageCalibration;

View file

@ -3394,9 +3394,9 @@ OpenTxModelData::OpenTxModelData(ModelData & modelData, BoardEnum board, unsigne
if (IS_HORUS(board)) { if (IS_HORUS(board)) {
for (int i = 0; i < 5; i++) { for (int i = 0; i < 5; i++) {
internalField.Append(new CharField<610>(modelData.customScreenData[i], true, "Custom screen blob")); internalField.Append(new CharField<610>(modelData.customScreenData[i], false, "Custom screen blob"));
} }
internalField.Append(new CharField<216>(modelData.topbarData, true, "Top bar blob")); internalField.Append(new CharField<216>(modelData.topbarData, false, "Top bar blob"));
internalField.Append(new SpareBitsField<8>()); // current view internalField.Append(new SpareBitsField<8>()); // current view
} }
} }
@ -3512,7 +3512,7 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, BoardEnum bo
internalField.Append(new UnsignedField<16>(chkSum)); internalField.Append(new UnsignedField<16>(chkSum));
if (!IS_HORUS(board)) { if (!IS_HORUS(board)) {
internalField.Append(new UnsignedField<8>(generalData.currModel)); internalField.Append(new UnsignedField<8>(generalData.currModelIndex));
internalField.Append(new UnsignedField<8>(generalData.contrast)); internalField.Append(new UnsignedField<8>(generalData.contrast));
} }
internalField.Append(new UnsignedField<8>(generalData.vBatWarn)); internalField.Append(new UnsignedField<8>(generalData.vBatWarn));
@ -3711,8 +3711,7 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, BoardEnum bo
for (int i=0; i<MAX_SLIDERS(board); ++i) { for (int i=0; i<MAX_SLIDERS(board); ++i) {
internalField.Append(new ZCharField<3>(generalData.sliderName[i], "Slider name")); internalField.Append(new ZCharField<3>(generalData.sliderName[i], "Slider name"));
} }
static char modelName[17+1] = "model1.bin\0 "; internalField.Append(new CharField<17>(generalData.currModelFilename, true, "Current model filename"));
internalField.Append(new CharField<17>(modelName, true, "Model name"));
} }
else if (IS_TARANIS(board) && version >= 217) { else if (IS_TARANIS(board) && version >= 217) {
for (int i=0; i<MAX_SWITCHES(board, version); i++) { for (int i=0; i<MAX_SWITCHES(board, version); i++) {

View file

@ -225,27 +225,38 @@ unsigned long OpenTxEepromInterface::loadxml(RadioData &radioData, QDomDocument
int OpenTxEepromInterface::loadFile(RadioData & radioData, const QString & filename) int OpenTxEepromInterface::loadFile(RadioData & radioData, const QString & filename)
{ {
StorageSdcard storage; StorageSdcard storage;
storage.read(filename); storage.read(filename);
// models.txt // Radio settings
QString modelList = QString(storage.modelList);
qDebug() << "Models: size" << modelList.size() << "contents" << modelList;
// radio.bin
qDebug() << "Radio settings:" << storage.radio.size(); qDebug() << "Radio settings:" << storage.radio.size();
loadFromByteArray<GeneralSettings, OpenTxGeneralData>(radioData.generalSettings, storage.radio); loadFromByteArray<GeneralSettings, OpenTxGeneralData>(radioData.generalSettings, storage.radio);
// all models // Models
QList<QString> models = storage.getModelsFileNames(); int modelIndex = 0;
qDebug() << "We have" << models.size() << "models:"; QString modelList = QString(storage.modelList);
QList<QByteArray> lines = storage.modelList.split('\n');
int index = 0; QString category = QObject::tr("Unknown");
for (QList<ModelFile>::iterator it = storage.models.begin(); it != storage.models.end(); ++it, ++index) { foreach (const QByteArray & line, lines) {
loadFromByteArray<ModelData, OpenTxModelData>(radioData.models[index], it->data); if (!line.isEmpty()) {
radioData.models[index].used = true; if (line.startsWith('[') && line.endsWith(']')) {
category = line.mid(1, line.size() - 2);
}
else {
qDebug() << "Loading" << line;
foreach (const ModelFile &model, storage.models) {
if (line == model.filename) {
loadFromByteArray<ModelData, OpenTxModelData>(radioData.models[modelIndex], model.data);
strncpy(radioData.models[modelIndex].filename, line.data(), sizeof(radioData.models[modelIndex].filename));
strncpy(radioData.models[modelIndex].category, category.toStdString().c_str(), sizeof(radioData.models[modelIndex].category));
radioData.models[modelIndex].used = true;
modelIndex++;
}
}
}
}
} }
return 0; return 0;
} }
@ -253,37 +264,43 @@ int OpenTxEepromInterface::saveFile(const RadioData & radioData, const QString &
{ {
StorageSdcard storage; StorageSdcard storage;
uint8_t version = getLastDataVersion(board); uint8_t version = getLastDataVersion(board);
// models.txt // models.txt
storage.modelList = QByteArray("[Models]\n"); storage.modelList = QByteArray();
QString currentCategory = "";
// radio.bin // radio.bin
saveToByteArray<GeneralSettings, OpenTxGeneralData>(radioData.generalSettings, storage.radio, version); saveToByteArray<GeneralSettings, OpenTxGeneralData>(radioData.generalSettings, storage.radio, version);
// all models // all models
for (int i=0; i<CPN_MAX_MODELS; i++) { for (int i=0; i<CPN_MAX_MODELS; i++) {
const ModelData & model = radioData.models[i]; const ModelData & model = radioData.models[i];
if (!model.isEmpty()) { if (!model.isEmpty()) {
QString modelFilename = QString().sprintf("model%d.bin", i+1); QString modelFilename = model.filename;
QByteArray modelData; QByteArray modelData;
saveToByteArray<ModelData, OpenTxModelData>(model, modelData, version); saveToByteArray<ModelData, OpenTxModelData>(model, modelData, version);
ModelFile modelFile = { modelFilename, modelData }; ModelFile modelFile = { modelFilename, modelData };
storage.models.append(modelFile); storage.models.append(modelFile);
storage.modelList.append(QString(" ") + modelFilename + "\n"); QString modelCategory = model.category;
if (currentCategory != modelCategory) {
storage.modelList.append(QString().sprintf("[%s]\n", model.category));
currentCategory = modelCategory;
}
storage.modelList.append(modelFilename + "\n");
} }
} }
storage.write(filename); storage.write(filename);
return 0; return 0;
} }
unsigned long OpenTxEepromInterface::load(RadioData &radioData, const uint8_t * eeprom, int size) unsigned long OpenTxEepromInterface::load(RadioData &radioData, const uint8_t * eeprom, int size)
{ {
std::cout << "trying " << getName() << " import..."; std::cout << "trying " << getName() << " import...";
std::bitset<NUM_ERRORS> errors; std::bitset<NUM_ERRORS> errors;
if (size != getEEpromSize()) { if (size != getEEpromSize()) {
if (size == 4096) { if (size == 4096) {
int notnull = false; int notnull = false;
@ -309,24 +326,24 @@ unsigned long OpenTxEepromInterface::load(RadioData &radioData, const uint8_t *
return errors.to_ulong(); return errors.to_ulong();
} }
} }
if (!efile->EeFsOpen((uint8_t *) eeprom, size, board)) { if (!efile->EeFsOpen((uint8_t *) eeprom, size, board)) {
std::cout << " wrong file system\n"; std::cout << " wrong file system\n";
errors.set(WRONG_FILE_SYSTEM); errors.set(WRONG_FILE_SYSTEM);
return errors.to_ulong(); return errors.to_ulong();
} }
efile->openRd(FILE_GENERAL); efile->openRd(FILE_GENERAL);
uint8_t version; uint8_t version;
if (efile->readRlc2(&version, 1) != 1) { if (efile->readRlc2(&version, 1) != 1) {
std::cout << " no\n"; std::cout << " no\n";
errors.set(UNKNOWN_ERROR); errors.set(UNKNOWN_ERROR);
return errors.to_ulong(); return errors.to_ulong();
} }
std::cout << " version " << (unsigned int) version; std::cout << " version " << (unsigned int) version;
EepromLoadErrors version_error = checkVersion(version); EepromLoadErrors version_error = checkVersion(version);
if (version_error == OLD_VERSION) { if (version_error == OLD_VERSION) {
errors.set(version_error); errors.set(version_error);
@ -337,13 +354,13 @@ unsigned long OpenTxEepromInterface::load(RadioData &radioData, const uint8_t *
errors.set(version_error); errors.set(version_error);
return errors.to_ulong(); return errors.to_ulong();
} }
if (!loadRadioSettingsFromRLE(radioData.generalSettings, efile, version)) { if (!loadRadioSettingsFromRLE(radioData.generalSettings, efile, version)) {
std::cout << " ko\n"; std::cout << " ko\n";
errors.set(UNKNOWN_ERROR); errors.set(UNKNOWN_ERROR);
return errors.to_ulong(); return errors.to_ulong();
} }
std::cout << " variant " << radioData.generalSettings.variant; std::cout << " variant " << radioData.generalSettings.variant;
for (int i = 0; i < getMaxModels(); i++) { for (int i = 0; i < getMaxModels(); i++) {
if (!loadModelFromRLE(radioData.models[i], efile, i, version, radioData.generalSettings.variant)) { if (!loadModelFromRLE(radioData.models[i], efile, i, version, radioData.generalSettings.variant)) {
@ -352,7 +369,7 @@ unsigned long OpenTxEepromInterface::load(RadioData &radioData, const uint8_t *
return errors.to_ulong(); return errors.to_ulong();
} }
} }
std::cout << " ok\n"; std::cout << " ok\n";
errors.set(ALL_OK); errors.set(ALL_OK);
return errors.to_ulong(); return errors.to_ulong();
@ -375,27 +392,27 @@ uint8_t OpenTxEepromInterface::getLastDataVersion(BoardEnum board)
int OpenTxEepromInterface::save(uint8_t * eeprom, RadioData & radioData, uint8_t version, uint32_t variant) int OpenTxEepromInterface::save(uint8_t * eeprom, RadioData & radioData, uint8_t version, uint32_t variant)
{ {
EEPROMWarnings.clear(); EEPROMWarnings.clear();
if (version == 0) { if (version == 0) {
version = getLastDataVersion(board); version = getLastDataVersion(board);
} }
int size = getEEpromSize(); int size = getEEpromSize();
efile->EeFsCreate(eeprom, size, board, version); efile->EeFsCreate(eeprom, size, board, version);
if (board == BOARD_M128) { if (board == BOARD_M128) {
variant |= M128_VARIANT; variant |= M128_VARIANT;
} }
else if (board == BOARD_TARANIS_X9E) { else if (board == BOARD_TARANIS_X9E) {
variant |= TARANIS_X9E_VARIANT; variant |= TARANIS_X9E_VARIANT;
} }
int result = saveRadioSettings<OpenTxGeneralData>(radioData.generalSettings, board, version, variant); int result = saveRadioSettings<OpenTxGeneralData>(radioData.generalSettings, board, version, variant);
if (!result) { if (!result) {
return 0; return 0;
} }
for (int i = 0; i < getMaxModels(); i++) { for (int i = 0; i < getMaxModels(); i++) {
if (!radioData.models[i].isEmpty()) { if (!radioData.models[i].isEmpty()) {
result = saveModel<OpenTxModelData>(i, radioData.models[i], version, variant); result = saveModel<OpenTxModelData>(i, radioData.models[i], version, variant);
@ -404,7 +421,7 @@ int OpenTxEepromInterface::save(uint8_t * eeprom, RadioData & radioData, uint8_t
} }
} }
} }
if (!EEPROMWarnings.empty()) { if (!EEPROMWarnings.empty()) {
QString msg; QString msg;
int noErrorsToDisplay = std::min((int) EEPROMWarnings.size(), 10); int noErrorsToDisplay = std::min((int) EEPROMWarnings.size(), 10);
@ -420,7 +437,7 @@ int OpenTxEepromInterface::save(uint8_t * eeprom, RadioData & radioData, uint8_t
QObject::tr("Warning"), QObject::tr("Warning"),
QObject::tr("EEPROM saved with these warnings:") + "\n" + msg); QObject::tr("EEPROM saved with these warnings:") + "\n" + msg);
} }
return size; return size;
} }
@ -428,15 +445,15 @@ int OpenTxEepromInterface::getSize(const ModelData &model)
{ {
if (IS_SKY9X(board)) if (IS_SKY9X(board))
return 0; return 0;
if (model.isEmpty()) if (model.isEmpty())
return 0; return 0;
QByteArray tmp(EESIZE_MAX, 0); QByteArray tmp(EESIZE_MAX, 0);
efile->EeFsCreate((uint8_t *) tmp.data(), EESIZE_MAX, board, 255/*version max*/); efile->EeFsCreate((uint8_t *) tmp.data(), EESIZE_MAX, board, 255/*version max*/);
OpenTxModelData open9xModel((ModelData &) model, board, 255/*version max*/, GetCurrentFirmware()->getVariantNumber()); OpenTxModelData open9xModel((ModelData &) model, board, 255/*version max*/, GetCurrentFirmware()->getVariantNumber());
QByteArray eeprom; QByteArray eeprom;
open9xModel.Export(eeprom); open9xModel.Export(eeprom);
int sz = efile->writeRlc2(0, FILE_TYP_MODEL, (const uint8_t *) eeprom.constData(), eeprom.size()); int sz = efile->writeRlc2(0, FILE_TYP_MODEL, (const uint8_t *) eeprom.constData(), eeprom.size());
@ -450,13 +467,13 @@ int OpenTxEepromInterface::getSize(const GeneralSettings &settings)
{ {
if (IS_SKY9X(board)) if (IS_SKY9X(board))
return 0; return 0;
QByteArray tmp(EESIZE_MAX, 0); QByteArray tmp(EESIZE_MAX, 0);
efile->EeFsCreate((uint8_t *) tmp.data(), EESIZE_MAX, board, 255); efile->EeFsCreate((uint8_t *) tmp.data(), EESIZE_MAX, board, 255);
OpenTxGeneralData open9xGeneral((GeneralSettings &) settings, board, 255, GetCurrentFirmware()->getVariantNumber()); OpenTxGeneralData open9xGeneral((GeneralSettings &) settings, board, 255, GetCurrentFirmware()->getVariantNumber());
// open9xGeneral.Dump(); // open9xGeneral.Dump();
QByteArray eeprom; QByteArray eeprom;
open9xGeneral.Export(eeprom); open9xGeneral.Export(eeprom);
int sz = efile->writeRlc2(0, FILE_TYP_GENERAL, (const uint8_t *) eeprom.constData(), eeprom.size()); int sz = efile->writeRlc2(0, FILE_TYP_GENERAL, (const uint8_t *) eeprom.constData(), eeprom.size());
@ -798,9 +815,9 @@ QString OpenTxFirmware::getAnalogInputName(unsigned int index)
QObject::tr("Ail") }; QObject::tr("Ail") };
return sticks[index]; return sticks[index];
} }
index -= 4; index -= 4;
if (IS_9X(board) || IS_2560(board) || IS_SKY9X(board)) { if (IS_9X(board) || IS_2560(board) || IS_SKY9X(board)) {
const QString pots[] = { QObject::tr("P1"), const QString pots[] = { QObject::tr("P1"),
QObject::tr("P2"), QObject::tr("P2"),
@ -899,10 +916,10 @@ bool OpenTxFirmware::isTelemetrySourceAvailable(int source)
{ {
if (IS_TARANIS(board) && (source == TELEMETRY_SOURCE_RSSI_TX)) if (IS_TARANIS(board) && (source == TELEMETRY_SOURCE_RSSI_TX))
return false; return false;
if (source == TELEMETRY_SOURCE_DTE) if (source == TELEMETRY_SOURCE_DTE)
return false; return false;
return true; return true;
} }
@ -1057,7 +1074,7 @@ EepromLoadErrors OpenTxEepromInterface::checkVersion(unsigned int version)
default: default:
return NOT_OPENTX; return NOT_OPENTX;
} }
return ALL_OK; return ALL_OK;
} }
@ -1090,7 +1107,7 @@ bool OpenTxEepromInterface::checkVariant(unsigned int version, unsigned int vari
return false; return false;
} }
} }
return true; return true;
} }
@ -1118,15 +1135,15 @@ OpenTxEepromInterface::loadModelFromBackup(ModelData & model, const uint8_t * da
unsigned long OpenTxEepromInterface::loadBackup(RadioData &radioData, const uint8_t * eeprom, int esize, int index) unsigned long OpenTxEepromInterface::loadBackup(RadioData &radioData, const uint8_t * eeprom, int esize, int index)
{ {
std::bitset<NUM_ERRORS> errors; std::bitset<NUM_ERRORS> errors;
std::cout << "trying " << getName() << " backup import..."; std::cout << "trying " << getName() << " backup import...";
if (esize < 8 || memcmp(eeprom, "o9x", 3) != 0) { if (esize < 8 || memcmp(eeprom, "o9x", 3) != 0) {
std::cout << " no\n"; std::cout << " no\n";
errors.set(WRONG_SIZE); errors.set(WRONG_SIZE);
return errors.to_ulong(); return errors.to_ulong();
} }
BoardEnum backupBoard = (BoardEnum) -1; BoardEnum backupBoard = (BoardEnum) -1;
switch (eeprom[3]) { switch (eeprom[3]) {
case 0x33: case 0x33:
@ -1143,20 +1160,20 @@ unsigned long OpenTxEepromInterface::loadBackup(RadioData &radioData, const uint
errors.set(UNKNOWN_BOARD); errors.set(UNKNOWN_BOARD);
return errors.to_ulong(); return errors.to_ulong();
} }
if (backupBoard != board) { if (backupBoard != board) {
std::cout << " not right board\n"; std::cout << " not right board\n";
errors.set(WRONG_BOARD); errors.set(WRONG_BOARD);
return errors.to_ulong(); return errors.to_ulong();
} }
uint8_t version = eeprom[4]; uint8_t version = eeprom[4];
uint8_t bcktype = eeprom[5]; uint8_t bcktype = eeprom[5];
uint16_t size = ((uint16_t) eeprom[7] << 8) + eeprom[6]; uint16_t size = ((uint16_t) eeprom[7] << 8) + eeprom[6];
uint16_t variant = ((uint16_t) eeprom[9] << 8) + eeprom[8]; uint16_t variant = ((uint16_t) eeprom[9] << 8) + eeprom[8];
std::cout << " version " << (unsigned int) version << " "; std::cout << " version " << (unsigned int) version << " ";
EepromLoadErrors version_error = checkVersion(version); EepromLoadErrors version_error = checkVersion(version);
if (version_error == OLD_VERSION) { if (version_error == OLD_VERSION) {
errors.set(version_error); errors.set(version_error);
@ -1167,13 +1184,13 @@ unsigned long OpenTxEepromInterface::loadBackup(RadioData &radioData, const uint
errors.set(version_error); errors.set(version_error);
return errors.to_ulong(); return errors.to_ulong();
} }
if (size > esize - 8) { if (size > esize - 8) {
std::cout << " wrong size\n"; std::cout << " wrong size\n";
errors.set(WRONG_SIZE); errors.set(WRONG_SIZE);
return errors.to_ulong(); return errors.to_ulong();
} }
if (bcktype == 'M') { if (bcktype == 'M') {
if (!loadModelFromBackup(radioData.models[index], &eeprom[8], size, version, variant)) { if (!loadModelFromBackup(radioData.models[index], &eeprom[8], size, version, variant)) {
std::cout << " ko\n"; std::cout << " ko\n";
@ -1186,7 +1203,7 @@ unsigned long OpenTxEepromInterface::loadBackup(RadioData &radioData, const uint
errors.set(BACKUP_NOT_SUPPORTED); errors.set(BACKUP_NOT_SUPPORTED);
return errors.to_ulong(); return errors.to_ulong();
} }
std::cout << " ok\n"; std::cout << " ok\n";
errors.set(ALL_OK); errors.set(ALL_OK);
return errors.to_ulong(); return errors.to_ulong();
@ -1205,7 +1222,7 @@ QString OpenTxFirmware::getFirmwareUrl()
{ {
QString url = getFirmwareBaseUrl(); QString url = getFirmwareBaseUrl();
QByteArray data = QUrl::toPercentEncoding(id); QByteArray data = QUrl::toPercentEncoding(id);
if (IS_ARM(board)) if (IS_ARM(board))
url.append(QString("/getfw.php?fw=%1.bin").arg((QString) data)); url.append(QString("/getfw.php?fw=%1.bin").arg((QString) data));
else else
@ -1275,7 +1292,7 @@ void addOpenTxLcdOptions(OpenTxFirmware * firmware)
void registerOpenTxFirmwares() void registerOpenTxFirmwares()
{ {
OpenTxFirmware * firmware; OpenTxFirmware * firmware;
Option ext_options[] = {{"frsky", QObject::tr("Support for frsky telemetry mod"), FRSKY_VARIANT}, Option ext_options[] = {{"frsky", QObject::tr("Support for frsky telemetry mod"), FRSKY_VARIANT},
{"telemetrez", QObject::tr("Support for telemetry easy board"), FRSKY_VARIANT}, {"telemetrez", QObject::tr("Support for telemetry easy board"), FRSKY_VARIANT},
{"jeti", QObject::tr("Support for jeti telemetry mod"), 0}, {"jeti", QObject::tr("Support for jeti telemetry mod"), 0},
@ -1295,36 +1312,36 @@ void registerOpenTxFirmwares()
Option dsm2_options[] = {{"DSM2", QObject::tr("Support for DSM2 modules"), 0}, Option dsm2_options[] = {{"DSM2", QObject::tr("Support for DSM2 modules"), 0},
{"DSM2PPM", QObject::tr("Support for DSM2 modules using ppm instead of true serial"), 0}, {"DSM2PPM", QObject::tr("Support for DSM2 modules using ppm instead of true serial"), 0},
{NULL}}; {NULL}};
/* FrSky Taranis X9D+ board */ /* FrSky Taranis X9D+ board */
firmware = new OpenTxFirmware("opentx-x9d+", QObject::tr("FrSky Taranis X9D+"), BOARD_TARANIS_X9DP); firmware = new OpenTxFirmware("opentx-x9d+", QObject::tr("FrSky Taranis X9D+"), BOARD_TARANIS_X9DP);
addOpenTxTaranisOptions(firmware); addOpenTxTaranisOptions(firmware);
firmwares.push_back(firmware); firmwares.push_back(firmware);
/* FrSky Taranis X9D board */ /* FrSky Taranis X9D board */
firmware = new OpenTxFirmware("opentx-x9d", QObject::tr("FrSky Taranis X9D"), BOARD_TARANIS_X9D); firmware = new OpenTxFirmware("opentx-x9d", QObject::tr("FrSky Taranis X9D"), BOARD_TARANIS_X9D);
firmware->addOption("haptic", QObject::tr("Haptic module installed")); firmware->addOption("haptic", QObject::tr("Haptic module installed"));
addOpenTxTaranisOptions(firmware); addOpenTxTaranisOptions(firmware);
firmwares.push_back(firmware); firmwares.push_back(firmware);
/* FrSky Taranis X9E board */ /* FrSky Taranis X9E board */
firmware = new OpenTxFirmware("opentx-x9e", QObject::tr("FrSky Taranis X9E"), BOARD_TARANIS_X9E); firmware = new OpenTxFirmware("opentx-x9e", QObject::tr("FrSky Taranis X9E"), BOARD_TARANIS_X9E);
firmware->addOption("shutdownconfirm", QObject::tr("Confirmation before radio shutdown")); firmware->addOption("shutdownconfirm", QObject::tr("Confirmation before radio shutdown"));
firmware->addOption("horussticks", QObject::tr("Horus gimbals installed (Hall sensors)")); firmware->addOption("horussticks", QObject::tr("Horus gimbals installed (Hall sensors)"));
addOpenTxTaranisOptions(firmware); addOpenTxTaranisOptions(firmware);
firmwares.push_back(firmware); firmwares.push_back(firmware);
/* FrSky X7D board */ /* FrSky X7D board */
firmware = new OpenTxFirmware("opentx-x7d", QObject::tr("FrSky X7D"), BOARD_X7D); firmware = new OpenTxFirmware("opentx-x7d", QObject::tr("FrSky X7D"), BOARD_X7D);
addOpenTxTaranisOptions(firmware); addOpenTxTaranisOptions(firmware);
firmwares.push_back(firmware); firmwares.push_back(firmware);
/* FrSky Horus board */ /* FrSky Horus board */
firmware = new OpenTxFirmware("opentx-horus", QObject::tr("FrSky Horus"), BOARD_HORUS); firmware = new OpenTxFirmware("opentx-horus", QObject::tr("FrSky Horus"), BOARD_HORUS);
addOpenTxFrskyOptions(firmware); addOpenTxFrskyOptions(firmware);
firmware->addOption("pcbdev", QObject::tr("Use ONLY with first DEV pcb version")); firmware->addOption("pcbdev", QObject::tr("Use ONLY with first DEV pcb version"));
firmwares.push_back(firmware); firmwares.push_back(firmware);
/* 9XR-Pro */ /* 9XR-Pro */
firmware = new OpenTxFirmware("opentx-9xrpro", QObject::tr("Turnigy 9XR-PRO"), BOARD_9XRPRO); firmware = new OpenTxFirmware("opentx-9xrpro", QObject::tr("Turnigy 9XR-PRO"), BOARD_9XRPRO);
firmware->addOption("heli", QObject::tr("Enable HELI menu and cyclic mix support")); firmware->addOption("heli", QObject::tr("Enable HELI menu and cyclic mix support"));
@ -1344,7 +1361,7 @@ void registerOpenTxFirmwares()
firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font")); firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font"));
addOpenTxCommonOptions(firmware); addOpenTxCommonOptions(firmware);
firmwares.push_back(firmware); firmwares.push_back(firmware);
/* 9XR board with M128 chip */ /* 9XR board with M128 chip */
firmware = new OpenTxFirmware("opentx-9xr128", QObject::tr("Turnigy 9XR with m128 chip"), BOARD_M128); firmware = new OpenTxFirmware("opentx-9xr128", QObject::tr("Turnigy 9XR with m128 chip"), BOARD_M128);
firmware->addOptions(extr_options); firmware->addOptions(extr_options);
@ -1373,7 +1390,7 @@ void registerOpenTxFirmwares()
firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font")); firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font"));
addOpenTxCommonOptions(firmware); addOpenTxCommonOptions(firmware);
firmwares.push_back(firmware); firmwares.push_back(firmware);
/* 9XR board */ /* 9XR board */
firmware = new OpenTxFirmware("opentx-9xr", QObject::tr("Turnigy 9XR"), BOARD_STOCK); firmware = new OpenTxFirmware("opentx-9xr", QObject::tr("Turnigy 9XR"), BOARD_STOCK);
firmware->addOptions(extr_options); firmware->addOptions(extr_options);
@ -1407,7 +1424,7 @@ void registerOpenTxFirmwares()
firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font")); firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font"));
addOpenTxCommonOptions(firmware); addOpenTxCommonOptions(firmware);
firmwares.push_back(firmware); firmwares.push_back(firmware);
/* 9x board */ /* 9x board */
firmware = new OpenTxFirmware("opentx-9x", QObject::tr("9X with stock board"), BOARD_STOCK); firmware = new OpenTxFirmware("opentx-9x", QObject::tr("9X with stock board"), BOARD_STOCK);
firmware->addOptions(ext_options); firmware->addOptions(ext_options);
@ -1444,7 +1461,7 @@ void registerOpenTxFirmwares()
firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font")); firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font"));
addOpenTxCommonOptions(firmware); addOpenTxCommonOptions(firmware);
firmwares.push_back(firmware); firmwares.push_back(firmware);
/* 9x board with M128 chip */ /* 9x board with M128 chip */
firmware = new OpenTxFirmware("opentx-9x128", QObject::tr("9X with stock board and m128 chip"), BOARD_M128); firmware = new OpenTxFirmware("opentx-9x128", QObject::tr("9X with stock board and m128 chip"), BOARD_M128);
firmware->addOptions(ext_options); firmware->addOptions(ext_options);
@ -1475,7 +1492,7 @@ void registerOpenTxFirmwares()
firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font")); firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font"));
addOpenTxCommonOptions(firmware); addOpenTxCommonOptions(firmware);
firmwares.push_back(firmware); firmwares.push_back(firmware);
/* ar9x board */ /* ar9x board */
firmware = new OpenTxFirmware("opentx-ar9x", QObject::tr("9X with AR9X board"), BOARD_AR9X); firmware = new OpenTxFirmware("opentx-ar9x", QObject::tr("9X with AR9X board"), BOARD_AR9X);
firmware->addOption("heli", QObject::tr("Enable HELI menu and cyclic mix support")); firmware->addOption("heli", QObject::tr("Enable HELI menu and cyclic mix support"));
@ -1498,7 +1515,7 @@ void registerOpenTxFirmwares()
// firmware->addOption("volume", QObject::tr("i2c volume control added")); // firmware->addOption("volume", QObject::tr("i2c volume control added"));
addOpenTxCommonOptions(firmware); addOpenTxCommonOptions(firmware);
firmwares.push_back(firmware); firmwares.push_back(firmware);
/* Sky9x board */ /* Sky9x board */
firmware = new OpenTxFirmware("opentx-sky9x", QObject::tr("9X with Sky9x board"), BOARD_SKY9X); firmware = new OpenTxFirmware("opentx-sky9x", QObject::tr("9X with Sky9x board"), BOARD_SKY9X);
firmware->addOption("heli", QObject::tr("Enable HELI menu and cyclic mix support")); firmware->addOption("heli", QObject::tr("Enable HELI menu and cyclic mix support"));
@ -1519,7 +1536,7 @@ void registerOpenTxFirmwares()
firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font")); firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font"));
addOpenTxCommonOptions(firmware); addOpenTxCommonOptions(firmware);
firmwares.push_back(firmware); firmwares.push_back(firmware);
/* Gruvin9x board */ /* Gruvin9x board */
firmware = new OpenTxFirmware("opentx-gruvin9x", QObject::tr("9X with Gruvin9x board"), BOARD_GRUVIN9X); firmware = new OpenTxFirmware("opentx-gruvin9x", QObject::tr("9X with Gruvin9x board"), BOARD_GRUVIN9X);
firmware->addOption("heli", QObject::tr("Enable heli menu and cyclic mix support")); firmware->addOption("heli", QObject::tr("Enable heli menu and cyclic mix support"));
@ -1545,7 +1562,7 @@ void registerOpenTxFirmwares()
firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font")); firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font"));
addOpenTxCommonOptions(firmware); addOpenTxCommonOptions(firmware);
firmwares.push_back(firmware); firmwares.push_back(firmware);
/* MEGA2560 board */ /* MEGA2560 board */
firmware = new OpenTxFirmware("opentx-mega2560", QObject::tr("DIY MEGA2560 radio"), BOARD_MEGA2560); firmware = new OpenTxFirmware("opentx-mega2560", QObject::tr("DIY MEGA2560 radio"), BOARD_MEGA2560);
addOpenTxLcdOptions(firmware); addOpenTxLcdOptions(firmware);
@ -1576,7 +1593,7 @@ void registerOpenTxFirmwares()
firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font")); firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font"));
addOpenTxCommonOptions(firmware); addOpenTxCommonOptions(firmware);
firmwares.push_back(firmware); firmwares.push_back(firmware);
default_firmware_variant = GetFirmware("opentx-x9d+"); default_firmware_variant = GetFirmware("opentx-x9d+");
current_firmware_variant = default_firmware_variant; current_firmware_variant = default_firmware_variant;
} }

View file

@ -813,7 +813,7 @@ void startSimulation(QWidget * parent, RadioData & radioData, int modelIdx)
unsigned int flags = 0; unsigned int flags = 0;
if (modelIdx >= 0) { if (modelIdx >= 0) {
flags |= SIMULATOR_FLAGS_NOTX; flags |= SIMULATOR_FLAGS_NOTX;
simuData->generalSettings.currModel = modelIdx; simuData->setCurrentModel(modelIdx);
} }
if (radioData.generalSettings.stickMode & 1) { if (radioData.generalSettings.stickMode & 1) {
flags |= SIMULATOR_FLAGS_STICK_MODE_LEFT; flags |= SIMULATOR_FLAGS_STICK_MODE_LEFT;

View file

@ -33,8 +33,6 @@
#include "wizarddialog.h" #include "wizarddialog.h"
#include "flashfirmwaredialog.h" #include "flashfirmwaredialog.h"
#include "storage_eeprom.h" #include "storage_eeprom.h"
#include "storage_sdcard.h"
#include <QFileInfo>
#if defined WIN32 || !defined __GNUC__ #if defined WIN32 || !defined __GNUC__
#include <windows.h> #include <windows.h>
@ -45,19 +43,19 @@
MdiChild::MdiChild(): MdiChild::MdiChild():
QWidget(), QWidget(),
ui(new Ui::mdiChild), ui(new Ui::MdiChild),
firmware(GetCurrentFirmware()), firmware(GetCurrentFirmware()),
isUntitled(true), isUntitled(true),
fileChanged(false) fileChanged(false)
{ {
ui->setupUi(this); ui->setupUi(this);
setWindowIcon(CompanionIcon("open.png")); setWindowIcon(CompanionIcon("open.png"));
ui->SimulateTxButton->setIcon(CompanionIcon("simulate.png")); ui->simulateButton->setIcon(CompanionIcon("simulate.png"));
setAttribute(Qt::WA_DeleteOnClose); setAttribute(Qt::WA_DeleteOnClose);
eepromInterfaceChanged(); eepromInterfaceChanged();
if (!(this->isMaximized() || this->isMinimized())) { if (!(isMaximized() || isMinimized())) {
adjustSize(); adjustSize();
} }
} }
@ -67,27 +65,14 @@ MdiChild::~MdiChild()
delete ui; delete ui;
} }
void MdiChild::qSleep(int ms)
{
if (ms<0)
return;
#if defined WIN32 || !defined __GNUC__
Sleep(uint(ms));
#else
struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 };
nanosleep(&ts, NULL);
#endif
}
void MdiChild::eepromInterfaceChanged() void MdiChild::eepromInterfaceChanged()
{ {
ui->modelsList->refreshList(); ui->modelsList->refreshList();
if (GetCurrentFirmware()->getBoard() == BOARD_HORUS && !HORUS_READY_FOR_RELEASE()) { if (GetCurrentFirmware()->getBoard() == BOARD_HORUS && !HORUS_READY_FOR_RELEASE()) {
ui->SimulateTxButton->setEnabled(false); ui->simulateButton->setEnabled(false);
} }
else { else {
ui->SimulateTxButton->setEnabled(GetCurrentFirmware()->getCapability(Simulation)); ui->simulateButton->setEnabled(GetCurrentFirmware()->getCapability(Simulation));
} }
updateTitle(); updateTitle();
} }
@ -133,7 +118,7 @@ void MdiChild::setModified()
documentWasModified(); documentWasModified();
} }
void MdiChild::on_SimulateTxButton_clicked() void MdiChild::on_simulateButton_clicked()
{ {
startSimulation(this, radioData, -1); startSimulation(this, radioData, -1);
} }
@ -158,7 +143,7 @@ void MdiChild::modelEdit()
{ {
int row = getCurrentRow(); int row = getCurrentRow();
if (row == 0){ if (row == 0) {
generalEdit(); generalEdit();
} }
else { else {

View file

@ -25,10 +25,10 @@
#include "eeprominterface.h" #include "eeprominterface.h"
namespace Ui { namespace Ui {
class mdiChild; class MdiChild;
} }
#define ER9X_EEPROM_FILE_TYPE "ER9X_EEPROM_FILE"
#define ER9X_EEPROM_FILE_TYPE "ER9X_EEPROM_FILE"
#define EEPE_EEPROM_FILE_HEADER "EEPE EEPROM FILE" #define EEPE_EEPROM_FILE_HEADER "EEPE EEPROM FILE"
#define EEPE_MODEL_FILE_HEADER "EEPE MODEL FILE" #define EEPE_MODEL_FILE_HEADER "EEPE MODEL FILE"
@ -65,8 +65,7 @@ class MdiChild : public QWidget
private slots: private slots:
void documentWasModified(); void documentWasModified();
void on_SimulateTxButton_clicked(); void on_simulateButton_clicked();
void qSleep(int ms);
public slots: public slots:
void checkAndInitModel(int row); void checkAndInitModel(int row);
@ -90,8 +89,8 @@ class MdiChild : public QWidget
QString strippedName(const QString & fullFileName); QString strippedName(const QString & fullFileName);
bool loadOtxFile(const QString & fileName); bool loadOtxFile(const QString & fileName);
Ui::mdiChild * ui; Ui::MdiChild * ui;
QString curFile; QString curFile;
Firmware * firmware; Firmware * firmware;

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"> <ui version="4.0">
<class>mdiChild</class> <class>MdiChild</class>
<widget class="QWidget" name="mdiChild"> <widget class="QWidget" name="MdiChild">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>
@ -18,7 +18,7 @@
<widget class="ModelsListWidget" name="modelsList"/> <widget class="ModelsListWidget" name="modelsList"/>
</item> </item>
<item> <item>
<widget class="QPushButton" name="SimulateTxButton"> <widget class="QPushButton" name="simulateButton">
<property name="text"> <property name="text">
<string>Simulate Tx</string> <string>Simulate Tx</string>
</property> </property>

View file

@ -356,10 +356,10 @@ void ModulePanel::update()
} }
ui->multiSubType->setCurrentIndex(module.subType); ui->multiSubType->setCurrentIndex(module.subType);
ui->cb_autoBind->setVisible(mask & MASK_MULTIMODULE); ui->autoBind->setVisible(mask & MASK_MULTIMODULE);
ui->cb_autoBind->setChecked(module.multi.autoBindMode ? Qt::Checked : Qt::Unchecked); ui->autoBind->setChecked(module.multi.autoBindMode ? Qt::Checked : Qt::Unchecked);
ui->cb_lowPower->setVisible(mask & MASK_MULTIMODULE); ui->lowPower->setVisible(mask & MASK_MULTIMODULE);
ui->cb_lowPower->setChecked(module.multi.lowPowerMode ? Qt::Checked : Qt::Unchecked); ui->lowPower->setChecked(module.multi.lowPowerMode ? Qt::Checked : Qt::Unchecked);
if (firmware->getCapability(HasFailsafe)) { if (firmware->getCapability(HasFailsafe)) {

View file

@ -609,14 +609,14 @@
</widget> </widget>
</item> </item>
<item row="4" column="4"> <item row="4" column="4">
<widget class="QCheckBox" name="cb_autoBind"> <widget class="QCheckBox" name="autoBind">
<property name="text"> <property name="text">
<string>Bind on startup</string> <string>Bind on startup</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="5"> <item row="4" column="5">
<widget class="QCheckBox" name="cb_lowPower"> <widget class="QCheckBox" name="lowPower">
<property name="text"> <property name="text">
<string>Low Power</string> <string>Low Power</string>
</property> </property>

View file

@ -34,25 +34,43 @@ class DragDropHeader {
uint8_t models[CPN_MAX_MODELS]; uint8_t models[CPN_MAX_MODELS];
}; };
ModelsListWidget::ModelsListWidget(QWidget *parent): ModelsListWidget::ModelsListWidget(QWidget * parent):
QListWidget(parent) QTreeWidget(parent)
{ {
setFont(QFont("Courier New",12)); BoardEnum board = GetCurrentFirmware()->getBoard();
radioData = &((MdiChild *)parent)->radioData; QStringList labels;
refreshList(); labels << tr("Index") << tr("Name");
if (!(IS_HORUS(board) || IS_SKY9X(board))) {
labels << tr("Size");
}
setColumnCount(labels.size());
setHeaderLabels(labels);
setColumnWidth(0, 50);
setColumnWidth(2, 100);
connect(this, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(OpenEditWindow())); connect(this, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(OpenEditWindow()));
connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(ShowContextMenu(const QPoint&))); connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(ShowContextMenu(const QPoint&)));
connect(this, SIGNAL(currentRowChanged(int)), this, SLOT(viableModelSelected(int))); connect(this, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), this, SLOT(onCurrentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)));
setContextMenuPolicy(Qt::CustomContextMenu); setContextMenuPolicy(Qt::CustomContextMenu);
setSelectionBehavior(QAbstractItemView::SelectRows);
setSelectionMode(QAbstractItemView::ExtendedSelection); setSelectionMode(QAbstractItemView::ExtendedSelection);
setDragEnabled(true); setDragEnabled(true);
setAcceptDrops(true); setAcceptDrops(true);
setDragDropOverwriteMode(true); setDragDropOverwriteMode(true);
setDropIndicatorShown(true); setDropIndicatorShown(true);
if (!IS_HORUS(board)) {
setIndentation(0);
}
active_highlight_color = palette().color(QPalette::Active, QPalette::Highlight); active_highlight_color = palette().color(QPalette::Active, QPalette::Highlight);
radioData = &((MdiChild *)parent)->radioData;
refreshList();
for (int i=0; i<labels.size(); i++) {
resizeColumnToContents(i);
}
} }
void ModelsListWidget::ShowContextMenu(const QPoint& pos) void ModelsListWidget::ShowContextMenu(const QPoint& pos)
@ -65,29 +83,34 @@ void ModelsListWidget::ShowContextMenu(const QPoint& pos)
const QMimeData *mimeData = clipboard->mimeData(); const QMimeData *mimeData = clipboard->mimeData();
bool hasData = mimeData->hasFormat("application/x-companion"); bool hasData = mimeData->hasFormat("application/x-companion");
contextMenu.addAction(CompanionIcon("edit.png"), tr("&Edit"),this,SLOT(EditModel())); contextMenu.addAction(CompanionIcon("edit.png"), tr("&Edit"), this, SLOT(EditModel()));
contextMenu.addAction(CompanionIcon("open.png"), tr("&Restore from backup"),this,SLOT(LoadBackup())); contextMenu.addAction(CompanionIcon("open.png"), tr("&Restore from backup"), this, SLOT(LoadBackup()));
contextMenu.addAction(CompanionIcon("wizard.png"), tr("&Model Wizard"),this,SLOT(OpenWizard())); contextMenu.addAction(CompanionIcon("wizard.png"), tr("&Model Wizard"), this, SLOT(OpenWizard()));
contextMenu.addSeparator(); contextMenu.addSeparator();
contextMenu.addAction(CompanionIcon("clear.png"), tr("&Delete"),this,SLOT(confirmDelete()),tr("Delete")); contextMenu.addAction(CompanionIcon("clear.png"), tr("&Delete"), this, SLOT(confirmDelete()), tr("Delete"));
contextMenu.addAction(CompanionIcon("copy.png"), tr("&Copy"),this,SLOT(copy()),tr("Ctrl+C")); contextMenu.addAction(CompanionIcon("copy.png"), tr("&Copy"), this, SLOT(copy()), tr("Ctrl+C"));
contextMenu.addAction(CompanionIcon("cut.png"), tr("&Cut"),this,SLOT(cut()),tr("Ctrl+X")); contextMenu.addAction(CompanionIcon("cut.png"), tr("&Cut"), this, SLOT(cut()), tr("Ctrl+X"));
contextMenu.addAction(CompanionIcon("paste.png"), tr("&Paste"),this,SLOT(paste()),tr("Ctrl+V"))->setEnabled(hasData); contextMenu.addAction(CompanionIcon("paste.png"), tr("&Paste"), this, SLOT(paste()), tr("Ctrl+V"))->setEnabled(hasData);
contextMenu.addAction(CompanionIcon("duplicate.png"), tr("D&uplicate"),this,SLOT(duplicate()),tr("Ctrl+U")); contextMenu.addAction(CompanionIcon("duplicate.png"), tr("D&uplicate"), this, SLOT(duplicate()), tr("Ctrl+U"));
contextMenu.addSeparator(); contextMenu.addSeparator();
contextMenu.addAction(CompanionIcon("currentmodel.png"), tr("&Use as default"),this,SLOT(setdefault())); contextMenu.addAction(CompanionIcon("currentmodel.png"), tr("&Use as default"), this, SLOT(setdefault()));
contextMenu.addSeparator(); contextMenu.addSeparator();
contextMenu.addAction(CompanionIcon("print.png"), tr("P&rint model"),this, SLOT(print()),QKeySequence(tr("Ctrl+P"))); contextMenu.addAction(CompanionIcon("print.png"), tr("P&rint model"), this, SLOT(print()),QKeySequence(tr("Ctrl+P")));
contextMenu.addSeparator(); contextMenu.addSeparator();
contextMenu.addAction(CompanionIcon("simulate.png"), tr("&Simulate model"),this, SLOT(simulate()),tr("Alt+S")); contextMenu.addAction(CompanionIcon("simulate.png"), tr("&Simulate model"), this, SLOT(simulate()), tr("Alt+S"));
} }
else { else {
// context menu for radio settings // context menu for radio settings
contextMenu.addAction(CompanionIcon("edit.png"), tr("&Edit"),this,SLOT(EditModel())); contextMenu.addAction(CompanionIcon("edit.png"), tr("&Edit"), this, SLOT(EditModel()));
} }
contextMenu.exec(globalPos); contextMenu.exec(globalPos);
} }
int ModelsListWidget::currentRow() const
{
return indexOfTopLevelItem(currentItem());
}
void ModelsListWidget::EditModel() void ModelsListWidget::EditModel()
{ {
((MdiChild *)parent())->modelEdit(); ((MdiChild *)parent())->modelEdit();
@ -120,189 +143,192 @@ void ModelsListWidget::print()
void ModelsListWidget::setdefault() void ModelsListWidget::setdefault()
{ {
if (currentRow()==0) return; if (currentRow() > 0) {
unsigned int currModel = currentRow() - 1; unsigned int currModel = currentRow() - 1;
if (!radioData->models[currModel].isEmpty() && radioData->generalSettings.currModel != currModel) { if (!radioData->models[currModel].isEmpty() && radioData->generalSettings.currModelIndex != currModel) {
radioData->generalSettings.currModel = currModel; radioData->setCurrentModel(currModel);
refreshList(); refreshList();
((MdiChild *)parent())->setModified(); ((MdiChild *) parent())->setModified();
}
} }
} }
void ModelsListWidget::mousePressEvent(QMouseEvent *event) void ModelsListWidget::mousePressEvent(QMouseEvent *event)
{ {
if (event->button() == Qt::LeftButton) if (event->button() == Qt::LeftButton)
dragStartPosition = event->pos(); dragStartPosition = event->pos();
QListWidget::mousePressEvent(event); QTreeWidget::mousePressEvent(event);
} }
void ModelsListWidget::mouseMoveEvent(QMouseEvent *event) void ModelsListWidget::mouseMoveEvent(QMouseEvent *event)
{ {
if (!(event->buttons() & Qt::LeftButton)) if (!(event->buttons() & Qt::LeftButton))
return; return;
if ((event->pos() - dragStartPosition).manhattanLength()
< QApplication::startDragDistance()) if ((event->pos() - dragStartPosition).manhattanLength() < QApplication::startDragDistance())
return; return;
QDrag *drag = new QDrag(this); QDrag * drag = new QDrag(this);
QByteArray gmData; QByteArray gmData;
doCopy(&gmData); doCopy(&gmData);
QMimeData *mimeData = new QMimeData; QMimeData * mimeData = new QMimeData;
mimeData->setData("application/x-companion", gmData); mimeData->setData("application/x-companion", gmData);
drag->setMimeData(mimeData); drag->setMimeData(mimeData);
//Qt::DropAction dropAction = //Qt::DropAction dropAction = drag->exec(Qt::CopyAction | Qt::MoveAction, Qt::CopyAction);
drag->exec(Qt::CopyAction | Qt::MoveAction, Qt::CopyAction);
//if(dropAction==Qt::MoveAction) //if(dropAction==Qt::MoveAction)
// QListWidget::mouseMoveEvent(event); // QTreeWidget::mouseMoveEvent(event);
} }
void ModelsListWidget::saveSelection() void ModelsListWidget::saveSelection()
{ {
currentSelection.current_item = currentItem(); currentSelection.current_item = currentItem();
for (int i=0; i<GetEepromInterface()->getMaxModels()+1; ++i) for (int i=0; i<GetEepromInterface()->getMaxModels()+1; ++i) {
currentSelection.selected[i] = item(i)->isSelected(); currentSelection.selected[i] = selectionModel()->isSelected(model()->index(i, 0));
}
} }
void ModelsListWidget::restoreSelection() void ModelsListWidget::restoreSelection()
{ {
setCurrentItem(currentSelection.current_item); setCurrentItem(currentSelection.current_item);
for (int i=0; i<GetEepromInterface()->getMaxModels()+1; ++i) for (int i=0; i<GetEepromInterface()->getMaxModels()+1; ++i) {
item(i)->setSelected(currentSelection.selected[i]); selectionModel()->select(model()->index(i, 0), currentSelection.selected[i] ? QItemSelectionModel::Select : QItemSelectionModel::Deselect);
}
} }
void ModelsListWidget::dragEnterEvent(QDragEnterEvent *event) void ModelsListWidget::dragEnterEvent(QDragEnterEvent *event)
{ {
if (event->mimeData()->hasFormat("application/x-companion")) if (event->mimeData()->hasFormat("application/x-companion")) {
{ event->acceptProposedAction();
event->acceptProposedAction(); saveSelection();
saveSelection(); }
}
} }
void ModelsListWidget::dragLeaveEvent(QDragLeaveEvent *) void ModelsListWidget::dragLeaveEvent(QDragLeaveEvent *)
{ {
restoreSelection(); restoreSelection();
} }
void ModelsListWidget::dragMoveEvent(QDragMoveEvent *event) void ModelsListWidget::dragMoveEvent(QDragMoveEvent *event)
{ {
int row=this->indexAt(event->pos()).row(); int row = indexAt(event->pos()).row();
const QMimeData *mimeData = event->mimeData(); const QMimeData * mimeData = event->mimeData();
if (mimeData->hasFormat("application/x-companion")) if (mimeData->hasFormat("application/x-companion")) {
{ QByteArray gmData = mimeData->data("application/x-companion");
QByteArray gmData = mimeData->data("application/x-companion"); event->acceptProposedAction();
event->acceptProposedAction(); clearSelection();
clearSelection(); DragDropHeader * header = (DragDropHeader *)gmData.data();
DragDropHeader *header = (DragDropHeader *)gmData.data(); if (row >= 0) {
if (row >= 0) { if (header->general_settings)
if (header->general_settings) selectionModel()->select(model()->index(0, 0), QItemSelectionModel::Select);
item(0)->setSelected(true); for (int i=row, end=std::min(GetEepromInterface()->getMaxModels()+1, row+header->models_count); i<end; i++)
for (int i=row, end=std::min(GetEepromInterface()->getMaxModels()+1, row+header->models_count); i<end; i++) selectionModel()->select(model()->index(i, 0), QItemSelectionModel::Select);
item(i)->setSelected(true);
}
} }
}
} }
void ModelsListWidget::dropEvent(QDropEvent *event) void ModelsListWidget::dropEvent(QDropEvent *event)
{ {
int row = this->indexAt(event->pos()).row(); int row = this->indexAt(event->pos()).row();
if (row < 0) if (row < 0)
return; return;
// QMessageBox::warning(this, tr("Companion"),tr("Index :%1").arg(row)); // QMessageBox::warning(this, tr("Companion"), tr("Index :%1").arg(row));
const QMimeData *mimeData = event->mimeData(); const QMimeData * mimeData = event->mimeData();
if(mimeData->hasFormat("application/x-companion")) if (mimeData->hasFormat("application/x-companion")) {
{ QByteArray gmData = mimeData->data("application/x-companion");
QByteArray gmData = mimeData->data("application/x-companion"); if (event->source() && event->dropAction() == Qt::MoveAction)
if (event->source() && event->dropAction() == Qt::MoveAction) ((ModelsListWidget*)event->source())->doCut(&gmData);
((ModelsListWidget*)event->source())->doCut(&gmData); doPaste(&gmData, row);
doPaste(&gmData, row); clearSelection();
clearSelection(); setCurrentItem(topLevelItem(row));
setCurrentItem(item(row)); DragDropHeader * header = (DragDropHeader *)gmData.data();
DragDropHeader *header = (DragDropHeader *)gmData.data(); if (header->general_settings)
if (header->general_settings) selectionModel()->select(model()->index(0, 0), QItemSelectionModel::Select);
item(0)->setSelected(true); for (int i=row, end=std::min(GetEepromInterface()->getMaxModels()+1, row+header->models_count); i<end; i++)
for (int i=row, end=std::min(GetEepromInterface()->getMaxModels()+1, row+header->models_count); i<end; i++) selectionModel()->select(model()->index(i, 0), QItemSelectionModel::Select);
item(i)->setSelected(true); }
} event->acceptProposedAction();
event->acceptProposedAction();
} }
#ifndef WIN32 #ifndef WIN32
void ModelsListWidget::focusInEvent ( QFocusEvent * event ) void ModelsListWidget::focusInEvent ( QFocusEvent * event )
{ {
QListWidget::focusInEvent(event); QTreeWidget::focusInEvent(event);
QPalette palette = this->palette(); QPalette palette = this->palette();
palette.setColor(QPalette::Active, QPalette::Highlight, active_highlight_color); palette.setColor(QPalette::Active, QPalette::Highlight, active_highlight_color);
palette.setColor(QPalette::Inactive, QPalette::Highlight, active_highlight_color); palette.setColor(QPalette::Inactive, QPalette::Highlight, active_highlight_color);
this->setPalette(palette); setPalette(palette);
} }
void ModelsListWidget::focusOutEvent ( QFocusEvent * event ) void ModelsListWidget::focusOutEvent ( QFocusEvent * event )
{ {
QListWidget::focusOutEvent(event); QTreeWidget::focusOutEvent(event);
QPalette palette = this->palette(); QPalette palette = this->palette();
palette.setColor(QPalette::Active, QPalette::Highlight, palette.color(QPalette::Active, QPalette::Midlight)); palette.setColor(QPalette::Active, QPalette::Highlight, palette.color(QPalette::Active, QPalette::Midlight));
palette.setColor(QPalette::Inactive, QPalette::Highlight, palette.color(QPalette::Active, QPalette::Midlight)); palette.setColor(QPalette::Inactive, QPalette::Highlight, palette.color(QPalette::Active, QPalette::Midlight));
this->setPalette(palette); setPalette(palette);
} }
#endif #endif
void ModelsListWidget::refreshList() void ModelsListWidget::refreshList()
{ {
int current = std::max(0, indexOfTopLevelItem(currentItem()));
clear(); clear();
addItem(tr("General Settings"));
QTreeWidgetItem * item = new QTreeWidgetItem();
item->setText(1, tr("General Settings"));
addTopLevelItem(item);
EEPROMInterface * eepromInterface = GetEepromInterface(); EEPROMInterface * eepromInterface = GetEepromInterface();
BoardEnum board = eepromInterface->getBoard(); BoardEnum board = eepromInterface->getBoard();
// TODO here we calculate the size used by the RLE format, this is clearly not the right place to do that... // TODO here we calculate the size used by the RLE format, this is clearly not the right place to do that...
int availableEEpromSize = eepromInterface->getEEpromSize() - 64; // let's consider fat int availableEEpromSize = eepromInterface->getEEpromSize() - 64; // let's consider fat
div_t divresult = div(eepromInterface->getSize(radioData->generalSettings), 15); availableEEpromSize -= 16 * ((eepromInterface->getSize(radioData->generalSettings) + 14) / 15);
divresult.quot += (divresult.rem != 0 ? 1 : 0);
availableEEpromSize -= divresult.quot*16;
for (uint8_t i=0; i<GetEepromInterface()->getMaxModels(); i++) { for (uint8_t i=0; i<GetEepromInterface()->getMaxModels(); i++) {
QString item = QString().sprintf("%02d: ", i+1); QTreeWidgetItem * item = new QTreeWidgetItem();
item->setTextAlignment(0, Qt::AlignLeft);
item->setText(0, QString().sprintf("%02d", i+1));
if (!radioData->models[i].isEmpty()) { if (!radioData->models[i].isEmpty()) {
QString modelName; QString modelName;
if (strlen(radioData->models[i].name) > 0) if (strlen(radioData->models[i].name) > 0)
modelName = radioData->models[i].name; modelName = radioData->models[i].name;
else else
modelName = QString().sprintf("Model%02d", i+1); modelName = QString().sprintf("Model%02d", i+1);
item += modelName; item->setText(1, modelName);
if (!IS_SKY9X(board) && !IS_HORUS(board)) { if (!IS_SKY9X(board) && !IS_HORUS(board)) {
item += QString(GetCurrentFirmware()->getCapability(ModelName)-modelName.size(), ' ');
int size = eepromInterface->getSize(radioData->models[i]); int size = eepromInterface->getSize(radioData->models[i]);
item += QString().sprintf("%5d", size); item->setText(2, QString().sprintf("%5d", size));
divresult = div(size, 15); size = 16 * ((size + 14) / 15);
divresult.quot += (divresult.rem != 0 ? 1 : 0); availableEEpromSize -= size;
availableEEpromSize -= divresult.quot*16; if (i == radioData->generalSettings.currModelIndex) {
if (i == radioData->generalSettings.currModel) { // Because we need this space for a TEMP model each time we have to write it again
// TODO why? availableEEpromSize -= size;
availableEEpromSize -= divresult.quot*16; }
}
if (i == radioData->generalSettings.currModelIndex) {
QFont font = item->font(0);
font.setBold(true);
for (int j=0; j<columnCount(); j++) {
item->setFont(j, font);
} }
} }
} }
addItem(item); addTopLevelItem(item);
} }
selectionModel()->select(model()->index(current, 0), QItemSelectionModel::Current | QItemSelectionModel::Select | QItemSelectionModel::Rows);
if (radioData->generalSettings.currModel < (unsigned int)eepromInterface->getMaxModels()) { setCurrentItem(topLevelItem(current));
QFont f = QFont("Courier New", 12);
f.setBold(true);
this->item(radioData->generalSettings.currModel+1)->setFont(f);
}
if (!IS_SKY9X(board) && !IS_HORUS(board)) { if (!IS_SKY9X(board) && !IS_HORUS(board)) {
((MdiChild*)parent())->setEEpromAvail((availableEEpromSize/16)*15); ((MdiChild*)parent())->setEEpromAvail((availableEEpromSize/16)*15);
} }
@ -310,129 +336,140 @@ void ModelsListWidget::refreshList()
void ModelsListWidget::cut() void ModelsListWidget::cut()
{ {
copy(); copy();
deleteSelected(false); deleteSelected(false);
} }
void ModelsListWidget::confirmDelete() { void ModelsListWidget::confirmDelete()
deleteSelected(true); {
deleteSelected(true);
} }
void ModelsListWidget::deleteSelected(bool ask=true) void ModelsListWidget::deleteSelected(bool ask=true)
{ {
bool isModel=false; bool isModel=false;
unsigned int selModel; unsigned int selModel;
QMessageBox::StandardButton ret = QMessageBox::Yes; QMessageBox::StandardButton ret = QMessageBox::Yes;
if(ask) { if (ask) {
foreach(QModelIndex index, this->selectionModel()->selectedIndexes()) { foreach (QModelIndex index, this->selectionModel()->selectedIndexes()) {
if (index.row()>0 && !radioData->models[index.row()-1].isEmpty()) { if (index.row()>0 && !radioData->models[index.row()-1].isEmpty()) {
isModel=true; isModel = true;
selModel=index.row()-1; selModel=index.row()-1;
}
}
if (isModel) {
if (radioData->generalSettings.currModelIndex != selModel) {
ret = QMessageBox::warning(this, "Companion", tr("Delete Selected Models?"), QMessageBox::Yes | QMessageBox::No);
}
else {
ret = QMessageBox::warning(this, "Companion", tr("Cannot delete default model."), QMessageBox::Ok);
}
}
}
if (ret == QMessageBox::Yes) {
foreach (QModelIndex index, this->selectionModel()->selectedIndexes()) {
if (index.row() > 0 && radioData->generalSettings.currModelIndex != (unsigned int)(index.row()-1)) {
radioData->models[index.row()-1].clear();
((MdiChild *)parent())->setModified();
}
else if (index.row()>0) {
if (ask) {
QMessageBox::warning(this, "Companion", tr("Cannot delete default model."), QMessageBox::Ok);
} }
} else {
if (isModel==true) { QMessageBox::warning(this, "Companion", tr("Cannot cut default model."), QMessageBox::Ok);
if (radioData->generalSettings.currModel != selModel) {
ret = QMessageBox::warning(this, "Companion", tr("Delete Selected Models?"), QMessageBox::Yes | QMessageBox::No);
} else {
ret = QMessageBox::warning(this, "Companion", tr("Cannot delete default model."), QMessageBox::Ok);
} }
} }
} }
if (ret == QMessageBox::Yes) {
foreach(QModelIndex index, this->selectionModel()->selectedIndexes()) {
if (index.row()>0 && radioData->generalSettings.currModel!=(unsigned int)(index.row()-1)) {
radioData->models[index.row()-1].clear();
((MdiChild *)parent())->setModified();
} else if (index.row()>0) {
if (ask) {
ret = QMessageBox::warning(this, "Companion", tr("Cannot delete default model."), QMessageBox::Ok);
} else {
ret = QMessageBox::warning(this, "Companion", tr("Cannot cut default model."), QMessageBox::Ok);
}
}
}
} }
} }
void ModelsListWidget::doCut(QByteArray *gmData) void ModelsListWidget::doCut(QByteArray * gmData)
{ {
bool modified=false; bool modified = false;
DragDropHeader *header = (DragDropHeader *)gmData->data(); DragDropHeader * header = (DragDropHeader *)gmData->data();
for (int i=0; i<header->models_count; i++) { for (int i=0; i<header->models_count; i++) {
if (radioData->generalSettings.currModel != (unsigned int)header->models[i]-1) { if (radioData->generalSettings.currModelIndex != (unsigned int)header->models[i]-1) {
radioData->models[header->models[i]-1].clear(); radioData->models[header->models[i]-1].clear();
modified=true; modified=true;
}
}
if (modified) {
((MdiChild *)parent())->setModified();
} }
}
if (modified) {
((MdiChild *)parent())->setModified();
}
} }
void ModelsListWidget::doCopy(QByteArray *gmData) void ModelsListWidget::doCopy(QByteArray * gmData)
{ {
DragDropHeader header; DragDropHeader header;
foreach(QModelIndex index, this->selectionModel()->selectedIndexes()) qDebug() << selectionModel()->selectedIndexes();
{ foreach(QModelIndex index, selectionModel()->selectedIndexes()) {
char row = index.row(); char column = index.column();
if(!row) { if (column == 0) {
header.general_settings = true; char row = index.row();
gmData->append('G'); if (!row) {
gmData->append((char*)&radioData->generalSettings, sizeof(GeneralSettings)); header.general_settings = true;
} gmData->append('G');
else { gmData->append((char *) &radioData->generalSettings, sizeof(GeneralSettings));
header.models[header.models_count++] = row; }
gmData->append('M'); else {
gmData->append((char*)&radioData->models[row-1], sizeof(ModelData)); header.models[header.models_count++] = row;
} gmData->append('M');
gmData->append((char *) &radioData->models[row - 1], sizeof(ModelData));
}
} }
}
gmData->prepend((char *)&header, sizeof(header)); gmData->prepend((char *)&header, sizeof(header));
} }
void ModelsListWidget::copy() void ModelsListWidget::copy()
{ {
QByteArray gmData; QByteArray gmData;
doCopy(&gmData); doCopy(&gmData);
QMimeData *mimeData = new QMimeData; QMimeData * mimeData = new QMimeData;
mimeData->setData("application/x-companion", gmData); mimeData->setData("application/x-companion", gmData);
QClipboard *clipboard = QApplication::clipboard(); QClipboard * clipboard = QApplication::clipboard();
clipboard->setMimeData(mimeData,QClipboard::Clipboard); clipboard->setMimeData(mimeData, QClipboard::Clipboard);
} }
void ModelsListWidget::doPaste(QByteArray *gmData, int index) void ModelsListWidget::doPaste(QByteArray * gmData, int index)
{ {
//QByteArray gmData = mimeD->data("application/x-companion"); // QByteArray gmData = mimeD->data("application/x-companion");
char *gData = gmData->data()+sizeof(DragDropHeader);//new char[gmData.size() + 1]; char * gData = gmData->data() + sizeof(DragDropHeader); // new char[gmData.size() + 1];
int i = sizeof(DragDropHeader); int i = sizeof(DragDropHeader);
int id = index; int id = index;
int ret,modified=0; int ret, modified=0;
if(!id) id++; if(!id) id++;
while((i<gmData->size()) && (id<=GetEepromInterface()->getMaxModels())) { while (i<gmData->size() && id<=GetEepromInterface()->getMaxModels()) {
qDebug() << i << gmData->size();
char c = *gData; char c = *gData;
i++; i++;
gData++; gData++;
if(c=='G') { //General settings if (c == 'G') {
// General settings
ret = QMessageBox::question(this, "Companion", tr("Do you want to overwrite radio general settings?"), ret = QMessageBox::question(this, "Companion", tr("Do you want to overwrite radio general settings?"),
QMessageBox::Yes | QMessageBox::No); QMessageBox::Yes | QMessageBox::No);
if (ret == QMessageBox::Yes) { if (ret == QMessageBox::Yes) {
radioData->generalSettings = *((GeneralSettings *)gData); radioData->generalSettings = *((GeneralSettings *)gData);
modified=1; modified = 1;
} }
gData += sizeof(GeneralSettings); gData += sizeof(GeneralSettings);
i += sizeof(GeneralSettings); i += sizeof(GeneralSettings);
} }
else { //model data else {
// Model data
if (!radioData->models[id-1].isEmpty()) { if (!radioData->models[id-1].isEmpty()) {
ret = QMessageBox::question(this, "Companion", tr("You are pasting on an not empty model, are you sure?"), ret = QMessageBox::question(this, "Companion", tr("You are pasting on an not empty model, are you sure?"),
QMessageBox::Yes | QMessageBox::No); QMessageBox::Yes | QMessageBox::No);
if (ret == QMessageBox::Yes) { if (ret == QMessageBox::Yes) {
radioData->models[id-1] = *((ModelData *)gData); radioData->models[id-1] = *((ModelData *)gData);
strcpy(radioData->models[id-1].filename, radioData->getNextModelFilename().toStdString().c_str());
gData += sizeof(ModelData); gData += sizeof(ModelData);
i += sizeof(ModelData); i += sizeof(ModelData);
id++; id++;
@ -446,6 +483,7 @@ void ModelsListWidget::doPaste(QByteArray *gmData, int index)
} }
else { else {
radioData->models[id-1] = *((ModelData *)gData); radioData->models[id-1] = *((ModelData *)gData);
strcpy(radioData->models[id-1].filename, radioData->getNextModelFilename().toStdString().c_str());
gData += sizeof(ModelData); gData += sizeof(ModelData);
i += sizeof(ModelData); i += sizeof(ModelData);
id++; id++;
@ -460,92 +498,85 @@ void ModelsListWidget::doPaste(QByteArray *gmData, int index)
bool ModelsListWidget::hasPasteData() bool ModelsListWidget::hasPasteData()
{ {
const QClipboard *clipboard = QApplication::clipboard(); const QClipboard *clipboard = QApplication::clipboard();
const QMimeData *mimeData = clipboard->mimeData(); const QMimeData *mimeData = clipboard->mimeData();
return mimeData->hasFormat("application/x-companion"); return mimeData->hasFormat("application/x-companion");
} }
void ModelsListWidget::paste() void ModelsListWidget::paste()
{ {
if (hasPasteData()) { if (hasPasteData()) {
const QClipboard *clipboard = QApplication::clipboard(); const QClipboard * clipboard = QApplication::clipboard();
const QMimeData *mimeData = clipboard->mimeData(); const QMimeData * mimeData = clipboard->mimeData();
QByteArray gmData = mimeData->data("application/x-companion"); QByteArray gmData = mimeData->data("application/x-companion");
doPaste(&gmData,this->currentRow()); doPaste(&gmData, currentRow());
} }
} }
void ModelsListWidget::duplicate() void ModelsListWidget::duplicate()
{ {
int i = this->currentRow(); int i = this->currentRow();
if(i && i<GetEepromInterface()->getMaxModels()) if (i && i<GetEepromInterface()->getMaxModels()) {
{ ModelData * model = &radioData->models[i-1];
ModelData *model = &radioData->models[i-1]; while (i<GetEepromInterface()->getMaxModels()) {
while(i<GetEepromInterface()->getMaxModels()) { if (radioData->models[i].isEmpty()) {
if (radioData->models[i].isEmpty()) { radioData->models[i] = *model;
radioData->models[i] = *model; strcpy(radioData->models[i].filename, radioData->getNextModelFilename().toStdString().c_str());
((MdiChild *)parent())->setModified(); ((MdiChild *)parent())->setModified();
break; break;
} }
i++; i++;
}
if (i==GetEepromInterface()->getMaxModels()) {
QMessageBox::warning(this, "Companion", tr("No free slot available, cannot duplicate"), QMessageBox::Ok);
}
} }
if (i==GetEepromInterface()->getMaxModels()) {
QMessageBox::warning(this, "Companion", tr("No free slot available, cannot duplicate"), QMessageBox::Ok);
}
}
} }
bool ModelsListWidget::hasSelection() bool ModelsListWidget::hasSelection()
{ {
return (this->selectionModel()->hasSelection()); return (this->selectionModel()->hasSelection());
} }
void ModelsListWidget::keyPressEvent(QKeyEvent *event) void ModelsListWidget::keyPressEvent(QKeyEvent *event)
{ {
if(event->matches(QKeySequence::Delete)) if (event->matches(QKeySequence::Delete)) {
{ deleteSelected();
deleteSelected(); return;
return; }
}
if(event->matches(QKeySequence::Cut)) if (event->matches(QKeySequence::Cut)) {
{ cut();
cut(); return;
return; }
}
if(event->matches(QKeySequence::Copy)) if (event->matches(QKeySequence::Copy)) {
{ copy();
copy(); return;
return; }
}
if(event->matches(QKeySequence::Paste)) if (event->matches(QKeySequence::Paste)) {
{ paste();
paste(); return;
return; }
}
if(event->matches(QKeySequence::Underline)) if (event->matches(QKeySequence::Underline)) {
{ duplicate();
duplicate(); return;
return; }
}
QListWidget::keyPressEvent(event);//run the standard event in case we didn't catch an action QTreeWidget::keyPressEvent(event);//run the standard event in case we didn't catch an action
} }
void ModelsListWidget::viableModelSelected(int idx) void ModelsListWidget::onCurrentItemChanged(QTreeWidgetItem * current, QTreeWidgetItem *)
{ {
int index = indexOfTopLevelItem(current);
if (!isVisible()) if (!isVisible())
((MdiChild*)parent())->viableModelSelected(false); ((MdiChild*)parent())->viableModelSelected(false);
else if (idx<1) else if (index<1)
((MdiChild*)parent())->viableModelSelected(false); ((MdiChild*)parent())->viableModelSelected(false);
else else
((MdiChild*)parent())->viableModelSelected(!radioData->models[currentRow()-1].isEmpty()); ((MdiChild*)parent())->viableModelSelected(!radioData->models[currentRow()-1].isEmpty());
} }

View file

@ -26,20 +26,21 @@
struct CurrentSelection struct CurrentSelection
{ {
QListWidgetItem *current_item; QTreeWidgetItem * current_item;
bool selected[CPN_MAX_MODELS+1]; bool selected[CPN_MAX_MODELS+1];
}; };
class ModelsListWidget : public QListWidget class ModelsListWidget : public QTreeWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
ModelsListWidget(QWidget *parent = 0); ModelsListWidget(QWidget * parent = 0);
bool hasSelection(); bool hasSelection();
void keyPressEvent(QKeyEvent *event); void keyPressEvent(QKeyEvent * event);
bool hasPasteData(); bool hasPasteData();
int currentRow() const;
protected: protected:
void dropEvent(QDropEvent *event); void dropEvent(QDropEvent *event);
@ -69,7 +70,7 @@ public slots:
void setdefault(); void setdefault();
void deleteSelected(bool ask); void deleteSelected(bool ask);
void confirmDelete(); void confirmDelete();
void viableModelSelected(int idx); void onCurrentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *);
private: private:
void doCut(QByteArray *gmData); void doCut(QByteArray *gmData);

View file

@ -72,8 +72,7 @@ int StorageSdcard::readOtx(const QString & path)
// go trough all files in an archive // go trough all files in an archive
QRegularExpression regexModel("MODELS/\\w+.bin", QRegularExpression::CaseInsensitiveOption); QRegularExpression regexModel("MODELS/\\w+.bin", QRegularExpression::CaseInsensitiveOption);
for (unsigned int i = 0; i < mz_zip_reader_get_num_files(&zip_archive); i++) for (unsigned int i = 0; i < mz_zip_reader_get_num_files(&zip_archive); i++) {
{
mz_zip_archive_file_stat file_stat; mz_zip_archive_file_stat file_stat;
if (!mz_zip_reader_file_stat(&zip_archive, i, &file_stat)) { if (!mz_zip_reader_file_stat(&zip_archive, i, &file_stat)) {
lastErrorMessage = QObject::tr("mz_zip_reader_file_stat() failed!"); lastErrorMessage = QObject::tr("mz_zip_reader_file_stat() failed!");
@ -117,9 +116,9 @@ int StorageSdcard::readOtx(const QString & path)
else { else {
qDebug() << "Unknown file " << filename; qDebug() << "Unknown file " << filename;
} }
} }
mz_zip_reader_end(&zip_archive); mz_zip_reader_end(&zip_archive);
return 0; return 0;
} }

View file

@ -70,7 +70,7 @@ void saveRadioSettings(GeneralSettings & settings, global_settings & gs)
Calibration p3Calib(settings.calibMid[6], settings.calibSpanNeg[6], settings.calibSpanPos[6]); Calibration p3Calib(settings.calibMid[6], settings.calibSpanNeg[6], settings.calibSpanPos[6]);
gs.calibration(calibration(rudderCalib, throttleCalib, aileronCalib, elevatorCalib, p1Calib, p2Calib, p3Calib)); gs.calibration(calibration(rudderCalib, throttleCalib, aileronCalib, elevatorCalib, p1Calib, p2Calib, p3Calib));
// TODO BSS settings.currModel; // TODO BSS settings.currModelIndex;
gs.contrast(settings.contrast); gs.contrast(settings.contrast);
gs.battery(battery(settings.txVoltageCalibration, settings.vBatWarn)); gs.battery(battery(settings.txVoltageCalibration, settings.vBatWarn));