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:
parent
dd77670007
commit
ec56d2dbdb
15 changed files with 443 additions and 385 deletions
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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++) {
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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));
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue