Bsongis/issue 4400 (#4425)
* Cosmetics before fixing #4400 * Cosmetics before fixing #4400 * Now one more conversion issue (SF => SH sources conversion from X9D to X7) I don't know what is exactly the conversion issue as I don't have the original EEPROM, but I used this one for my tests, so I fix it * Now we display correctly the corrupted mixers list so that copy/paste will work correctly (it was not consistent) + some cosmetics * Test removed too quickly * One global removed ;)
This commit is contained in:
@@ -26,15 +26,24 @@
|
||||
|
||||
class DataField {
|
||||
public:
|
||||
DataField(const char *name=""):
|
||||
DataField(DataField * parent, const char * name=""):
|
||||
parent(parent),
|
||||
name(name)
|
||||
{
|
||||
}
|
||||
virtual const char *getName() { return name; }
|
||||
virtual ~DataField() { }
|
||||
|
||||
virtual ~DataField()
|
||||
{
|
||||
}
|
||||
|
||||
virtual const char * getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
virtual unsigned int size() = 0;
|
||||
virtual void ExportBits(QBitArray & output) = 0;
|
||||
virtual void ImportBits(const QBitArray & input) = 0;
|
||||
virtual unsigned int size() = 0;
|
||||
|
||||
QBitArray bytesToBits(QByteArray bytes)
|
||||
{
|
||||
@@ -99,13 +108,24 @@ class DataField {
|
||||
}
|
||||
|
||||
protected:
|
||||
const char *name;
|
||||
virtual void setError(const QString & error)
|
||||
{
|
||||
if (parent) {
|
||||
parent->setError(error);
|
||||
}
|
||||
else {
|
||||
qWarning() << qPrintable(error);
|
||||
}
|
||||
}
|
||||
|
||||
DataField * parent;
|
||||
const char * name;
|
||||
};
|
||||
|
||||
class ProxyField: public DataField {
|
||||
public:
|
||||
ProxyField():
|
||||
DataField("Proxy")
|
||||
explicit ProxyField(DataField * parent):
|
||||
DataField(parent, "Proxy")
|
||||
{
|
||||
}
|
||||
|
||||
@@ -116,24 +136,24 @@ class ProxyField: public DataField {
|
||||
template<class container, int N>
|
||||
class BaseUnsignedField: public DataField {
|
||||
public:
|
||||
explicit BaseUnsignedField(container & field):
|
||||
DataField("Unsigned"),
|
||||
BaseUnsignedField(DataField * parent, container & field):
|
||||
DataField(parent, "Unsigned"),
|
||||
field(field),
|
||||
min(0),
|
||||
max(std::numeric_limits<container>::max())
|
||||
{
|
||||
}
|
||||
|
||||
BaseUnsignedField(container & field, const char * name):
|
||||
DataField(name),
|
||||
BaseUnsignedField(DataField * parent, container & field, const char * name):
|
||||
DataField(parent, name),
|
||||
field(field),
|
||||
min(0),
|
||||
max(std::numeric_limits<container>::max())
|
||||
{
|
||||
}
|
||||
|
||||
BaseUnsignedField(container & field, container min, container max, const char * name="Unsigned"):
|
||||
DataField(name),
|
||||
BaseUnsignedField(DataField * parent, container & field, container min, container max, const char * name="Unsigned"):
|
||||
DataField(parent, name),
|
||||
field(field),
|
||||
min(min),
|
||||
max(max)
|
||||
@@ -182,18 +202,18 @@ template <int N>
|
||||
class UnsignedField : public BaseUnsignedField<unsigned int, N>
|
||||
{
|
||||
public:
|
||||
explicit UnsignedField(unsigned int & field):
|
||||
BaseUnsignedField<unsigned int, N>(field)
|
||||
UnsignedField(DataField * parent, unsigned int & field):
|
||||
BaseUnsignedField<unsigned int, N>(parent, field)
|
||||
{
|
||||
}
|
||||
|
||||
UnsignedField(unsigned int & field, const char *name):
|
||||
BaseUnsignedField<unsigned int, N>(field, name)
|
||||
UnsignedField(DataField * parent, unsigned int & field, const char *name):
|
||||
BaseUnsignedField<unsigned int, N>(parent, field, name)
|
||||
{
|
||||
}
|
||||
|
||||
UnsignedField(unsigned int & field, unsigned int min, unsigned int max, const char *name="Unsigned"):
|
||||
BaseUnsignedField<unsigned int, N>(field, min, max, name)
|
||||
UnsignedField(DataField * parent, unsigned int & field, unsigned int min, unsigned int max, const char *name="Unsigned"):
|
||||
BaseUnsignedField<unsigned int, N>(parent, field, min, max, name)
|
||||
{
|
||||
}
|
||||
};
|
||||
@@ -201,8 +221,8 @@ class UnsignedField : public BaseUnsignedField<unsigned int, N>
|
||||
template<int N>
|
||||
class BoolField: public DataField {
|
||||
public:
|
||||
explicit BoolField(bool & field):
|
||||
DataField("Bool"),
|
||||
explicit BoolField(DataField * parent, bool & field):
|
||||
DataField(parent, "Bool"),
|
||||
field(field)
|
||||
{
|
||||
}
|
||||
@@ -236,24 +256,24 @@ class BoolField: public DataField {
|
||||
template<int N>
|
||||
class SignedField: public DataField {
|
||||
public:
|
||||
SignedField(int & field):
|
||||
DataField("Signed"),
|
||||
SignedField(DataField * parent, int & field):
|
||||
DataField(parent, "Signed"),
|
||||
field(field),
|
||||
min(INT_MIN),
|
||||
max(INT_MAX)
|
||||
{
|
||||
}
|
||||
|
||||
SignedField(int & field, const char *name):
|
||||
DataField(name),
|
||||
SignedField(DataField * parent, int & field, const char *name):
|
||||
DataField(parent, name),
|
||||
field(field),
|
||||
min(INT_MIN),
|
||||
max(INT_MAX)
|
||||
{
|
||||
}
|
||||
|
||||
SignedField(int & field, int min, int max, const char *name="Signed"):
|
||||
DataField(name),
|
||||
SignedField(DataField * parent, int & field, int min, int max, const char *name="Signed"):
|
||||
DataField(parent, name),
|
||||
field(field),
|
||||
min(min),
|
||||
max(max)
|
||||
@@ -305,8 +325,8 @@ class SignedField: public DataField {
|
||||
template<int N>
|
||||
class SpareBitsField: public UnsignedField<N> {
|
||||
public:
|
||||
SpareBitsField():
|
||||
UnsignedField<N>(spare, 0, 0, "Spare"),
|
||||
SpareBitsField(DataField * parent):
|
||||
UnsignedField<N>(parent, spare, 0, 0, "Spare"),
|
||||
spare(0)
|
||||
{
|
||||
}
|
||||
@@ -317,8 +337,8 @@ class SpareBitsField: public UnsignedField<N> {
|
||||
template<int N>
|
||||
class CharField: public DataField {
|
||||
public:
|
||||
CharField(char * field, bool truncate=true, const char * name="Char"):
|
||||
DataField(name),
|
||||
CharField(DataField * parent, char * field, bool truncate=true, const char * name="Char"):
|
||||
DataField(parent, name),
|
||||
field(field),
|
||||
truncate(truncate)
|
||||
{
|
||||
@@ -368,8 +388,8 @@ char idx2char(int8_t idx);
|
||||
template<int N>
|
||||
class ZCharField: public DataField {
|
||||
public:
|
||||
ZCharField(char * field, const char * name = "ZChar"):
|
||||
DataField(name),
|
||||
ZCharField(DataField * parent, char * field, const char * name = "ZChar"):
|
||||
DataField(parent, name),
|
||||
field(field)
|
||||
{
|
||||
}
|
||||
@@ -421,18 +441,18 @@ class ZCharField: public DataField {
|
||||
|
||||
class StructField: public DataField {
|
||||
public:
|
||||
StructField(const char * name="Struct"):
|
||||
DataField(name)
|
||||
StructField(DataField * parent, const char * name="Struct"):
|
||||
DataField(parent, name)
|
||||
{
|
||||
}
|
||||
|
||||
~StructField() {
|
||||
foreach(DataField *field, fields) {
|
||||
foreach(DataField * field, fields) {
|
||||
delete field;
|
||||
}
|
||||
}
|
||||
|
||||
inline void Append(DataField *field) {
|
||||
inline void Append(DataField * field) {
|
||||
//eepromImportDebug() << QString("StructField(%1) appending field: %2").arg(name).arg(field->getName());
|
||||
fields.append(field);
|
||||
}
|
||||
@@ -488,8 +508,8 @@ class StructField: public DataField {
|
||||
|
||||
class TransformedField: public DataField {
|
||||
public:
|
||||
TransformedField(DataField & field):
|
||||
DataField(),
|
||||
TransformedField(DataField * parent, DataField & field):
|
||||
DataField(parent),
|
||||
field(field)
|
||||
{
|
||||
}
|
||||
@@ -512,7 +532,7 @@ class TransformedField: public DataField {
|
||||
}
|
||||
|
||||
|
||||
virtual const char *getName()
|
||||
virtual const char * getName()
|
||||
{
|
||||
return field.getName();
|
||||
}
|
||||
@@ -607,9 +627,9 @@ class ConversionTable {
|
||||
template<class T>
|
||||
class ConversionField: public TransformedField {
|
||||
public:
|
||||
ConversionField(int & field, ConversionTable *table, const char *name, const QString & error = ""):
|
||||
TransformedField(internalField),
|
||||
internalField(_field, name),
|
||||
ConversionField(DataField * parent, int & field, ConversionTable *table, const char *name, const QString & error = ""):
|
||||
TransformedField(parent, internalField),
|
||||
internalField(this, _field, name),
|
||||
field(field),
|
||||
_field(0),
|
||||
table(table),
|
||||
@@ -623,9 +643,9 @@ class ConversionField: public TransformedField {
|
||||
{
|
||||
}
|
||||
|
||||
ConversionField(unsigned int & field, ConversionTable *table, const char *name, const QString & error = ""):
|
||||
TransformedField(internalField),
|
||||
internalField((unsigned int &)_field, name),
|
||||
ConversionField(DataField * parent, unsigned int & field, ConversionTable *table, const char *name, const QString & error = ""):
|
||||
TransformedField(parent, internalField),
|
||||
internalField(this, (unsigned int &)_field, name),
|
||||
field((int &)field),
|
||||
_field(0),
|
||||
table(table),
|
||||
@@ -639,9 +659,9 @@ class ConversionField: public TransformedField {
|
||||
{
|
||||
}
|
||||
|
||||
ConversionField(int & field, int (*exportFunc)(int), int (*importFunc)(int)):
|
||||
TransformedField(internalField),
|
||||
internalField(_field),
|
||||
ConversionField(DataField * parent, int & field, int (*exportFunc)(int), int (*importFunc)(int)):
|
||||
TransformedField(parent, internalField),
|
||||
internalField(this, _field),
|
||||
field(field),
|
||||
_field(0),
|
||||
table(NULL),
|
||||
@@ -655,9 +675,9 @@ class ConversionField: public TransformedField {
|
||||
{
|
||||
}
|
||||
|
||||
ConversionField(int & field, int shift, int scale=0, int min=INT_MIN, int max=INT_MAX, const char *name = "Signed shifted"):
|
||||
TransformedField(internalField),
|
||||
internalField(_field, name),
|
||||
ConversionField(DataField * parent, int & field, int shift, int scale=0, int min=INT_MIN, int max=INT_MAX, const char *name = "Signed shifted"):
|
||||
TransformedField(parent, internalField),
|
||||
internalField(this, _field, name),
|
||||
field(field),
|
||||
_field(0),
|
||||
table(NULL),
|
||||
@@ -671,9 +691,9 @@ class ConversionField: public TransformedField {
|
||||
{
|
||||
}
|
||||
|
||||
ConversionField(unsigned int & field, int shift, int scale=0):
|
||||
TransformedField(internalField),
|
||||
internalField((unsigned int &)_field),
|
||||
ConversionField(DataField * parent, unsigned int & field, int shift, int scale=0):
|
||||
TransformedField(parent, internalField),
|
||||
internalField(this, (unsigned int &)_field),
|
||||
field((int &)field),
|
||||
_field(0),
|
||||
table(NULL),
|
||||
@@ -696,16 +716,19 @@ class ConversionField: public TransformedField {
|
||||
}
|
||||
|
||||
if (table) {
|
||||
if (table->exportValue(_field, _field))
|
||||
return;
|
||||
if (!error.isEmpty())
|
||||
EEPROMWarnings.push_back(error);
|
||||
if (!table->exportValue(_field, _field)) {
|
||||
setError(error.isEmpty() ? QObject::tr("Conversion error on field %1").arg(name) : error);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (shift) {
|
||||
if (_field < min) _field = min + shift;
|
||||
else if (_field > max) _field = max + shift;
|
||||
else _field += shift;
|
||||
if (_field < min)
|
||||
_field = min + shift;
|
||||
else if (_field > max)
|
||||
_field = max + shift;
|
||||
else
|
||||
_field += shift;
|
||||
}
|
||||
|
||||
if (exportFunc) {
|
||||
|
||||
@@ -35,8 +35,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <bitset>
|
||||
|
||||
std::list<QString> EEPROMWarnings;
|
||||
|
||||
const uint8_t chout_ar[] = { // First number is 0..23 -> template setup, Second is relevant channel out
|
||||
1,2,3,4 , 1,2,4,3 , 1,3,2,4 , 1,3,4,2 , 1,4,2,3 , 1,4,3,2,
|
||||
2,1,3,4 , 2,1,4,3 , 2,3,1,4 , 2,3,4,1 , 2,4,1,3 , 2,4,3,1,
|
||||
|
||||
@@ -180,8 +180,6 @@ class EEPROMInterface
|
||||
|
||||
};
|
||||
|
||||
extern std::list<QString> EEPROMWarnings;
|
||||
|
||||
/* EEPROM string conversion functions */
|
||||
void setEEPROMString(char *dst, const char *src, int size);
|
||||
void getEEPROMString(char *dst, const char *src, int size);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -42,17 +42,28 @@ class OpenTxGeneralData: public TransformedField {
|
||||
|
||||
virtual const char * getName() { return internalField.getName(); }
|
||||
|
||||
QStringList errors()
|
||||
{
|
||||
return _errors;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void beforeExport();
|
||||
virtual void afterImport();
|
||||
|
||||
virtual void setError(const QString & error)
|
||||
{
|
||||
qWarning() << error;
|
||||
_errors << error;
|
||||
}
|
||||
|
||||
StructField internalField;
|
||||
GeneralSettings & generalData;
|
||||
Board::Type board;
|
||||
unsigned int version;
|
||||
int inputsCount;
|
||||
unsigned int chkSum;
|
||||
// unsigned int potsType[4];
|
||||
QStringList _errors;
|
||||
};
|
||||
|
||||
class ProtocolsConversionTable: public ConversionTable
|
||||
@@ -111,21 +122,31 @@ class OpenTxModelData: public TransformedField {
|
||||
|
||||
virtual const char * getName() { return internalField.getName(); }
|
||||
|
||||
QStringList errors()
|
||||
{
|
||||
return _errors;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void beforeExport();
|
||||
virtual void afterImport();
|
||||
|
||||
virtual void setError(const QString & error)
|
||||
{
|
||||
qWarning() << error;
|
||||
_errors << error;
|
||||
}
|
||||
|
||||
StructField internalField;
|
||||
ModelData & modelData;
|
||||
Board::Type board;
|
||||
unsigned int version;
|
||||
unsigned int variant;
|
||||
|
||||
private:
|
||||
char name[256];
|
||||
int subprotocols[CPN_MAX_MODULES+1/*trainer*/];
|
||||
ProtocolsConversionTable protocolsConversionTable;
|
||||
ChannelsConversionTable channelsConversionTable;
|
||||
QStringList _errors;
|
||||
};
|
||||
|
||||
void OpenTxEepromCleanup(void);
|
||||
|
||||
@@ -201,29 +201,6 @@ bool OpenTxEepromInterface::loadFromByteArray(T & dest, const QByteArray & data)
|
||||
return loadFromByteArray<T, M>(dest, raw, version);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool
|
||||
OpenTxEepromInterface::saveRadioSettings(GeneralSettings &settings, Board::Type board, uint8_t version, uint32_t variant)
|
||||
{
|
||||
T open9xSettings(settings, board, version, variant);
|
||||
// open9xSettings.Dump();
|
||||
QByteArray eeprom;
|
||||
open9xSettings.Export(eeprom);
|
||||
int sz = efile->writeRlc2(FILE_GENERAL, FILE_TYP_GENERAL, (const uint8_t *) eeprom.constData(), eeprom.size());
|
||||
return (sz == eeprom.size());
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool OpenTxEepromInterface::saveModel(unsigned int index, ModelData &model, uint8_t version, uint32_t variant)
|
||||
{
|
||||
T open9xModel(model, board, version, variant);
|
||||
// open9xModel.Dump();
|
||||
QByteArray eeprom;
|
||||
open9xModel.Export(eeprom);
|
||||
int sz = efile->writeRlc2(FILE_MODEL(index), FILE_TYP_MODEL, (const uint8_t *) eeprom.constData(), eeprom.size());
|
||||
return (sz == eeprom.size());
|
||||
}
|
||||
|
||||
unsigned long OpenTxEepromInterface::load(RadioData &radioData, const uint8_t * eeprom, int size)
|
||||
{
|
||||
std::cout << "trying " << getName() << " import...";
|
||||
@@ -324,9 +301,30 @@ uint8_t OpenTxEepromInterface::getLastDataVersion(Board::Type board)
|
||||
}
|
||||
}
|
||||
|
||||
void OpenTxEepromInterface::showErrors(const QString & title, const QStringList & errors)
|
||||
{
|
||||
QString msg;
|
||||
if (errors.empty()) {
|
||||
msg = QObject::tr("Unknown error");
|
||||
}
|
||||
else {
|
||||
int noErrorsToDisplay = std::min((int)errors.size(), 10);
|
||||
for (int n = 0; n < noErrorsToDisplay; n++) {
|
||||
msg += " -" + errors.at(n) + "\n";
|
||||
}
|
||||
if (noErrorsToDisplay < errors.size()) {
|
||||
msg += QObject::tr(" ... plus %1 errors").arg(errors.size() - noErrorsToDisplay) + "\n" + msg;
|
||||
}
|
||||
}
|
||||
|
||||
QMessageBox::warning(NULL,
|
||||
QObject::tr("Error"),
|
||||
title + "\n" + msg);
|
||||
}
|
||||
|
||||
int OpenTxEepromInterface::save(uint8_t * eeprom, const RadioData & radioData, uint8_t version, uint32_t variant)
|
||||
{
|
||||
EEPROMWarnings.clear();
|
||||
// TODO QMessageBox::warning should not be called here
|
||||
|
||||
if (version == 0) {
|
||||
version = getLastDataVersion(board);
|
||||
@@ -346,36 +344,30 @@ int OpenTxEepromInterface::save(uint8_t * eeprom, const RadioData & radioData, u
|
||||
variant |= TARANIS_X7_VARIANT;
|
||||
}
|
||||
|
||||
int result = saveRadioSettings<OpenTxGeneralData>((GeneralSettings &)radioData.generalSettings, board, version, variant);
|
||||
if (!result) {
|
||||
OpenTxGeneralData generator((GeneralSettings &)radioData.generalSettings, board, version, variant);
|
||||
// generator.Dump();
|
||||
QByteArray data;
|
||||
generator.Export(data);
|
||||
int sz = efile->writeRlc2(FILE_GENERAL, FILE_TYP_GENERAL, (const uint8_t *)data.constData(), data.size());
|
||||
if (sz == 0 || generator.errors().count() > 0) {
|
||||
showErrors(QObject::tr("Cannot write radio settings"), generator.errors());
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < getCurrentFirmware()->getCapability(Models); i++) {
|
||||
if (!radioData.models[i].isEmpty()) {
|
||||
result = saveModel<OpenTxModelData>(i, (ModelData &)radioData.models[i], version, variant);
|
||||
if (!result) {
|
||||
OpenTxModelData generator((ModelData &)radioData.models[i], board, version, variant);
|
||||
// generator.Dump();
|
||||
QByteArray data;
|
||||
generator.Export(data);
|
||||
int sz = efile->writeRlc2(FILE_MODEL(i), FILE_TYP_MODEL, (const uint8_t *)data.constData(), data.size());
|
||||
if (sz == 0 || generator.errors().count() > 0) {
|
||||
showErrors(QObject::tr("Cannot write model %1").arg(radioData.models[i].name), generator.errors());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!EEPROMWarnings.empty()) {
|
||||
QString msg;
|
||||
int noErrorsToDisplay = std::min((int) EEPROMWarnings.size(), 10);
|
||||
for (int n = 0; n < noErrorsToDisplay; n++) {
|
||||
msg += "-" + EEPROMWarnings.front() + "\n";
|
||||
EEPROMWarnings.pop_front();
|
||||
}
|
||||
if (!EEPROMWarnings.empty()) {
|
||||
msg = QObject::tr("(displaying only first 10 warnings)") + "\n" + msg;
|
||||
}
|
||||
EEPROMWarnings.clear();
|
||||
QMessageBox::warning(NULL,
|
||||
QObject::tr("Warning"),
|
||||
QObject::tr("EEPROM saved with these warnings:") + "\n" + msg);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
@@ -67,12 +67,8 @@ class OpenTxEepromInterface : public EEPROMInterface
|
||||
bool loadRadioSettingsFromRLE(GeneralSettings & settings, RleFile * rleFile, uint8_t version);
|
||||
|
||||
bool loadModelFromRLE(ModelData & model, RleFile * rleFile, unsigned int index, uint8_t version, uint32_t variant);
|
||||
|
||||
template <class T>
|
||||
bool saveModel(unsigned int index, ModelData & model, uint8_t version, uint32_t variant);
|
||||
|
||||
template <class T>
|
||||
bool saveRadioSettings(GeneralSettings & settings, Board::Type board, uint8_t version, uint32_t variant);
|
||||
|
||||
void showErrors(const QString & title, const QStringList & errors);
|
||||
|
||||
uint8_t getLastDataVersion(Board::Type board);
|
||||
|
||||
|
||||
@@ -229,8 +229,7 @@ void FlashEEpromDialog::on_burnButton_clicked()
|
||||
QFile file(filename);
|
||||
uint8_t *eeprom = (uint8_t*)malloc(getEEpromSize(getCurrentBoard()));
|
||||
int eeprom_size = getCurrentEEpromInterface()->save(eeprom, *radioData, 0, getCurrentFirmware()->getVariantNumber());
|
||||
if (!eeprom_size) {
|
||||
QMessageBox::warning(this, tr("Error"), tr("Cannot write file %1:\n%2.").arg(filename).arg(file.errorString()));
|
||||
if (eeprom_size == 0) {
|
||||
return;
|
||||
}
|
||||
if (!file.open(QIODevice::WriteOnly)) {
|
||||
|
||||
@@ -589,14 +589,16 @@ void MainWindow::openFile()
|
||||
|
||||
void MainWindow::save()
|
||||
{
|
||||
if (activeMdiChild() && activeMdiChild()->save())
|
||||
if (activeMdiChild() && activeMdiChild()->save()) {
|
||||
statusBar()->showMessage(tr("File saved"), 2000);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::saveAs()
|
||||
{
|
||||
if (activeMdiChild() && activeMdiChild()->saveAs())
|
||||
if (activeMdiChild() && activeMdiChild()->saveAs()) {
|
||||
statusBar()->showMessage(tr("File saved"), 2000);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::openRecentFile()
|
||||
|
||||
@@ -605,7 +605,7 @@ bool MdiChild::saveAs(bool isNew)
|
||||
if (isNew)
|
||||
return saveFile(fileName);
|
||||
else
|
||||
return saveFile(fileName,true);
|
||||
return saveFile(fileName, true);
|
||||
}
|
||||
|
||||
bool MdiChild::saveFile(const QString & filename, bool setCurrent)
|
||||
@@ -614,7 +614,6 @@ bool MdiChild::saveFile(const QString & filename, bool setCurrent)
|
||||
Storage storage(filename);
|
||||
bool result = storage.write(radioData);
|
||||
if (!result) {
|
||||
QMessageBox::warning(this, "Companion", tr("Cannot save file"), QMessageBox::Ok);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ set(modeledit_SRCS
|
||||
logicalswitches.cpp
|
||||
customfunctions.cpp
|
||||
# templates.cpp
|
||||
mixerslist.cpp
|
||||
mixerslistwidget.cpp
|
||||
node.cpp
|
||||
edge.cpp
|
||||
)
|
||||
@@ -35,7 +35,7 @@ set(modeledit_HDRS
|
||||
logicalswitches.h
|
||||
customfunctions.h
|
||||
# templates.h
|
||||
mixerslist.h
|
||||
mixerslistwidget.h
|
||||
node.h
|
||||
)
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ InputsPanel::InputsPanel(QWidget *parent, ModelData & model, GeneralSettings & g
|
||||
|
||||
QGridLayout * exposLayout = new QGridLayout(this);
|
||||
|
||||
ExposlistWidget = new MixersList(this, true);
|
||||
ExposlistWidget = new MixersListWidget(this, true);
|
||||
QPushButton * qbUp = new QPushButton(this);
|
||||
QPushButton * qbDown = new QPushButton(this);
|
||||
QPushButton * qbClear = new QPushButton(this);
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#define _INPUTS_H_
|
||||
|
||||
#include "modeledit.h"
|
||||
#include "mixerslist.h"
|
||||
#include "mixerslistwidget.h"
|
||||
#include "modelprinter.h"
|
||||
|
||||
class InputsPanel : public ModelPanel
|
||||
@@ -53,7 +53,7 @@ class InputsPanel : public ModelPanel
|
||||
|
||||
private:
|
||||
bool expoInserted;
|
||||
MixersList *ExposlistWidget;
|
||||
MixersListWidget *ExposlistWidget;
|
||||
bool firstLine;
|
||||
int inputsCount;
|
||||
ModelPrinter modelPrinter;
|
||||
|
||||
+8
-8
@@ -18,9 +18,9 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "mixerslist.h"
|
||||
#include "mixerslistwidget.h"
|
||||
|
||||
MixersList::MixersList(QWidget *parent, bool expo) :
|
||||
MixersListWidget::MixersListWidget(QWidget * parent, bool expo) :
|
||||
QListWidget(parent),
|
||||
expo(expo)
|
||||
{
|
||||
@@ -33,7 +33,7 @@ MixersList::MixersList(QWidget *parent, bool expo) :
|
||||
setItemDelegate(new MixersDelegate(parent)); //set custom paint handler
|
||||
}
|
||||
|
||||
void MixersList::keyPressEvent(QKeyEvent *event)
|
||||
void MixersListWidget::keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
emit keyWasPressed(event);
|
||||
}
|
||||
@@ -42,7 +42,7 @@ void MixersList::keyPressEvent(QKeyEvent *event)
|
||||
/**
|
||||
@brief Override to give us different mime type for mixers and inputs
|
||||
*/
|
||||
QStringList MixersList::mimeTypes () const
|
||||
QStringList MixersListWidget::mimeTypes () const
|
||||
{
|
||||
QStringList types;
|
||||
if (expo) types << "application/x-companion-expo-item";
|
||||
@@ -50,7 +50,7 @@ QStringList MixersList::mimeTypes () const
|
||||
return types;
|
||||
}
|
||||
|
||||
void MixersList::dropEvent(QDropEvent *event)
|
||||
void MixersListWidget::dropEvent(QDropEvent * event)
|
||||
{
|
||||
QList<int> list;
|
||||
foreach(QListWidgetItem *item, selectedItems()) {
|
||||
@@ -62,9 +62,9 @@ void MixersList::dropEvent(QDropEvent *event)
|
||||
dropMimeData(indexAt(event->pos()).row(),event->mimeData(),event->dropAction());
|
||||
}
|
||||
|
||||
bool MixersList::dropMimeData( int index, const QMimeData * data, Qt::DropAction action )
|
||||
bool MixersListWidget::dropMimeData(int index, const QMimeData * data, Qt::DropAction action )
|
||||
{
|
||||
// qDebug() << "MixersList::dropMimeData() index:" << index << "formats" << data->formats();
|
||||
// qDebug() << "MixersListWidget::dropMimeData() index:" << index << "formats" << data->formats();
|
||||
QByteArray dropData = data->data(expo ? "application/x-companion-expo-item" : "application/x-companion-mix-item");
|
||||
if (dropData.isNull() ) return false;
|
||||
QDataStream stream(&dropData, QIODevice::ReadOnly);
|
||||
@@ -77,7 +77,7 @@ bool MixersList::dropMimeData( int index, const QMimeData * data, Qt::DropAction
|
||||
QList<QVariant> lsVars;
|
||||
lsVars = v.values();
|
||||
qba.append(lsVars.at(1).toByteArray().mid(1));
|
||||
// qDebug() << "MixersList::dropMimeData() added" << lsVars.count() << "items, data:" << lsVars;
|
||||
// qDebug() << "MixersListWidget::dropMimeData() added" << lsVars.count() << "items, data:" << lsVars;
|
||||
}
|
||||
|
||||
if(qba.length()>0) {
|
||||
@@ -18,20 +18,20 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _MIXERSLIST_H_
|
||||
#define _MIXERSLIST_H_
|
||||
#ifndef _MIXERSLISTWIDGET_H_
|
||||
#define _MIXERSLISTWIDGET_H_
|
||||
|
||||
#include <QtWidgets>
|
||||
|
||||
#define MIX_ROW_HEIGHT_INCREASE 8 //how much space is added above mixer row (for new channel), if 0 space adding is disabled
|
||||
const int GroupHeaderRole = (Qt::UserRole+2); //defines new user role for list items. If value is > 0, then space is added before that item
|
||||
|
||||
class MixersList : public QListWidget
|
||||
class MixersListWidget : public QListWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MixersList(QWidget *parent, bool expo);
|
||||
explicit MixersListWidget(QWidget *parent, bool expo);
|
||||
void keyPressEvent(QKeyEvent *event);
|
||||
void dropEvent(QDropEvent *event);
|
||||
|
||||
@@ -70,4 +70,4 @@ class MixersDelegate : public QStyledItemDelegate
|
||||
|
||||
};
|
||||
|
||||
#endif // _MIXERSLIST_H_
|
||||
#endif // _MIXERSLISTWIDGET_H_
|
||||
@@ -29,7 +29,7 @@ MixesPanel::MixesPanel(QWidget *parent, ModelData & model, GeneralSettings & gen
|
||||
{
|
||||
QGridLayout * mixesLayout = new QGridLayout(this);
|
||||
|
||||
MixerlistWidget = new MixersList(this, false); // TODO enum
|
||||
mixersListWidget = new MixersListWidget(this, false); // TODO enum
|
||||
QPushButton * qbUp = new QPushButton(this);
|
||||
QPushButton * qbDown = new QPushButton(this);
|
||||
QPushButton * qbClear = new QPushButton(this);
|
||||
@@ -42,20 +42,20 @@ MixesPanel::MixesPanel(QWidget *parent, ModelData & model, GeneralSettings & gen
|
||||
qbClear->setText(tr("Clear Mixes"));
|
||||
qbClear->setIcon(CompanionIcon("clear.png"));
|
||||
|
||||
mixesLayout->addWidget(MixerlistWidget,1,1,1,3);
|
||||
mixesLayout->addWidget(mixersListWidget,1,1,1,3);
|
||||
mixesLayout->addWidget(qbUp,2,1);
|
||||
mixesLayout->addWidget(qbClear,2,2);
|
||||
mixesLayout->addWidget(qbDown,2,3);
|
||||
|
||||
connect(MixerlistWidget,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(mixerlistWidget_customContextMenuRequested(QPoint)));
|
||||
connect(MixerlistWidget,SIGNAL(doubleClicked(QModelIndex)),this,SLOT(mixerlistWidget_doubleClicked(QModelIndex)));
|
||||
connect(MixerlistWidget,SIGNAL(mimeDropped(int,const QMimeData*,Qt::DropAction)),this,SLOT(mimeMixerDropped(int,const QMimeData*,Qt::DropAction)));
|
||||
connect(mixersListWidget,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(mixerlistWidget_customContextMenuRequested(QPoint)));
|
||||
connect(mixersListWidget,SIGNAL(doubleClicked(QModelIndex)),this,SLOT(mixerlistWidget_doubleClicked(QModelIndex)));
|
||||
connect(mixersListWidget,SIGNAL(mimeDropped(int,const QMimeData*,Qt::DropAction)),this,SLOT(mimeMixerDropped(int,const QMimeData*,Qt::DropAction)));
|
||||
|
||||
connect(qbUp,SIGNAL(pressed()),SLOT(moveMixUp()));
|
||||
connect(qbDown,SIGNAL(pressed()),SLOT(moveMixDown()));
|
||||
connect(qbClear,SIGNAL(pressed()),SLOT(clearMixes()));
|
||||
|
||||
connect(MixerlistWidget,SIGNAL(keyWasPressed(QKeyEvent*)), this, SLOT(mixerlistWidget_KeyPress(QKeyEvent*)));
|
||||
connect(mixersListWidget,SIGNAL(keyWasPressed(QKeyEvent*)), this, SLOT(mixerlistWidget_KeyPress(QKeyEvent*)));
|
||||
}
|
||||
|
||||
MixesPanel::~MixesPanel()
|
||||
@@ -64,17 +64,17 @@ MixesPanel::~MixesPanel()
|
||||
|
||||
void MixesPanel::update()
|
||||
{
|
||||
// curDest -> destination channel
|
||||
// i -> mixer number
|
||||
MixerlistWidget->clear();
|
||||
firstLine = true;
|
||||
mixersListWidget->clear();
|
||||
|
||||
unsigned int curDest = 0;
|
||||
unsigned int outputs = firmware->getCapability(Outputs);
|
||||
|
||||
for (int i=0; i<firmware->getCapability(Mixes); i++) {
|
||||
MixData & mix = model->mixData[i];
|
||||
// qDebug() << "mix.destCh: " << mix.destCh;
|
||||
if (mix.destCh == 0 || mix.destCh>outputs) continue;
|
||||
if (mix.destCh == 0 || mix.destCh > outputs) {
|
||||
// we reached the end of the mixes list
|
||||
break;
|
||||
}
|
||||
QString str = "";
|
||||
while (curDest < mix.destCh-1) {
|
||||
curDest++;
|
||||
@@ -111,19 +111,18 @@ bool MixesPanel::AddMixerLine(int dest)
|
||||
QByteArray qba(1, (quint8)dest);
|
||||
if (dest >= 0) {
|
||||
//add mix data
|
||||
MixData *md = &model->mixData[dest];
|
||||
MixData * md = &model->mixData[dest];
|
||||
qba.append((const char*)md, sizeof(MixData));
|
||||
}
|
||||
itm->setData(Qt::UserRole, qba);
|
||||
#if MIX_ROW_HEIGHT_INCREASE > 0
|
||||
if (new_ch && !firstLine) {
|
||||
//increase size of this row
|
||||
// TODO why?
|
||||
if (new_ch && mixersListWidget->count() == 0) {
|
||||
// increase size of this row
|
||||
itm->setData(GroupHeaderRole, 1);
|
||||
}
|
||||
#endif
|
||||
MixerlistWidget->addItem(itm);
|
||||
firstLine = false;
|
||||
// qDebug() << "MixesPanel::AddMixerLine(): dest" << dest << "text" << str;
|
||||
mixersListWidget->addItem(itm);
|
||||
return new_ch;
|
||||
}
|
||||
|
||||
@@ -217,15 +216,21 @@ void MixesPanel::gm_openMix(int index)
|
||||
|
||||
int MixesPanel::getMixerIndex(unsigned int dch)
|
||||
{
|
||||
int i = 0;
|
||||
while ((model->mixData[i].destCh <= dch) && (model->mixData[i].destCh) && (i < firmware->getCapability(Mixes))) i++;
|
||||
if (i == firmware->getCapability(Mixes)) return -1;
|
||||
return i;
|
||||
for (int i=0; i < firmware->getCapability(Mixes); i++) {
|
||||
if (!model->mixData[i].destCh) {
|
||||
// we reached the end of used mixes
|
||||
return i;
|
||||
}
|
||||
if (model->mixData[i].destCh > dch) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void MixesPanel::mixerlistWidget_doubleClicked(QModelIndex index)
|
||||
{
|
||||
int idx = MixerlistWidget->item(index.row())->data(Qt::UserRole).toByteArray().at(0);
|
||||
int idx = mixersListWidget->item(index.row())->data(Qt::UserRole).toByteArray().at(0);
|
||||
if (idx<0) {
|
||||
int i = -idx;
|
||||
idx = getMixerIndex(i); //get mixer index to insert
|
||||
@@ -253,7 +258,7 @@ void MixesPanel::mixersDeleteList(QList<int> list)
|
||||
QList<int> MixesPanel::createMixListFromSelected()
|
||||
{
|
||||
QList<int> list;
|
||||
foreach(QListWidgetItem *item, MixerlistWidget->selectedItems()) {
|
||||
foreach(QListWidgetItem *item, mixersListWidget->selectedItems()) {
|
||||
int idx= item->data(Qt::UserRole).toByteArray().at(0);
|
||||
if(idx >= 0 && idx<firmware->getCapability(Mixes)) list << idx;
|
||||
}
|
||||
@@ -263,10 +268,10 @@ QList<int> MixesPanel::createMixListFromSelected()
|
||||
// TODO duplicated code
|
||||
void MixesPanel::setSelectedByMixList(QList<int> list)
|
||||
{
|
||||
for(int i=0; i<MixerlistWidget->count(); i++) {
|
||||
int t = MixerlistWidget->item(i)->data(Qt::UserRole).toByteArray().at(0);
|
||||
for(int i=0; i<mixersListWidget->count(); i++) {
|
||||
int t = mixersListWidget->item(i)->data(Qt::UserRole).toByteArray().at(0);
|
||||
if(list.contains(t)) {
|
||||
MixerlistWidget->item(i)->setSelected(true);
|
||||
mixersListWidget->item(i)->setSelected(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -314,7 +319,7 @@ void MixesPanel::mixersCopy()
|
||||
|
||||
void MixesPanel::pasteMixerMimeData(const QMimeData * mimeData, int destIdx)
|
||||
{
|
||||
if(mimeData->hasFormat("application/x-companion-mix")) {
|
||||
if (mimeData->hasFormat("application/x-companion-mix")) {
|
||||
int idx; // mixer index
|
||||
int dch;
|
||||
|
||||
@@ -349,9 +354,9 @@ void MixesPanel::pasteMixerMimeData(const QMimeData * mimeData, int destIdx)
|
||||
|
||||
void MixesPanel::mixersPaste()
|
||||
{
|
||||
const QClipboard *clipboard = QApplication::clipboard();
|
||||
const QMimeData *mimeData = clipboard->mimeData();
|
||||
QListWidgetItem *item = MixerlistWidget->currentItem();
|
||||
const QClipboard * clipboard = QApplication::clipboard();
|
||||
const QMimeData * mimeData = clipboard->mimeData();
|
||||
QListWidgetItem * item = mixersListWidget->currentItem();
|
||||
if (item) {
|
||||
pasteMixerMimeData(mimeData, item->data(Qt::UserRole).toByteArray().at(0));
|
||||
}
|
||||
@@ -365,7 +370,7 @@ void MixesPanel::mixersDuplicate()
|
||||
|
||||
void MixesPanel::mixerOpen()
|
||||
{
|
||||
int idx = MixerlistWidget->currentItem()->data(Qt::UserRole).toByteArray().at(0);
|
||||
int idx = mixersListWidget->currentItem()->data(Qt::UserRole).toByteArray().at(0);
|
||||
if(idx < 0) {
|
||||
int i = -idx;
|
||||
idx = getMixerIndex(i); //get mixer index to insert
|
||||
@@ -382,7 +387,7 @@ void MixesPanel::mixerOpen()
|
||||
|
||||
void MixesPanel::mixerHighlight()
|
||||
{
|
||||
int idx = MixerlistWidget->currentItem()->data(Qt::UserRole).toByteArray().at(0);
|
||||
int idx = mixersListWidget->currentItem()->data(Qt::UserRole).toByteArray().at(0);
|
||||
int dest;
|
||||
if (idx<0) {
|
||||
dest = -idx;
|
||||
@@ -392,17 +397,17 @@ void MixesPanel::mixerHighlight()
|
||||
}
|
||||
highlightedSource = ( (int)highlightedSource == dest) ? 0 : dest;
|
||||
// qDebug() << "MixesPanel::mixerHighlight(): " << highlightedSource ;
|
||||
for(int i=0; i<MixerlistWidget->count(); i++) {
|
||||
int t = MixerlistWidget->item(i)->data(Qt::UserRole).toByteArray().at(0);
|
||||
MixerlistWidget->item(i)->setText(getMixerText(t, 0));
|
||||
for(int i=0; i<mixersListWidget->count(); i++) {
|
||||
int t = mixersListWidget->item(i)->data(Qt::UserRole).toByteArray().at(0);
|
||||
mixersListWidget->item(i)->setText(getMixerText(t, 0));
|
||||
}
|
||||
}
|
||||
|
||||
void MixesPanel::mixerAdd()
|
||||
{
|
||||
if (!MixerlistWidget->currentItem()) return;
|
||||
if (!mixersListWidget->currentItem()) return;
|
||||
|
||||
int index = MixerlistWidget->currentItem()->data(Qt::UserRole).toByteArray().at(0);
|
||||
int index = mixersListWidget->currentItem()->data(Qt::UserRole).toByteArray().at(0);
|
||||
|
||||
if(index < 0) { // if empty then return relavent index
|
||||
int i = -index;
|
||||
@@ -422,7 +427,7 @@ void MixesPanel::mixerAdd()
|
||||
|
||||
void MixesPanel::mixerlistWidget_customContextMenuRequested(QPoint pos)
|
||||
{
|
||||
QPoint globalPos = MixerlistWidget->mapToGlobal(pos);
|
||||
QPoint globalPos = mixersListWidget->mapToGlobal(pos);
|
||||
|
||||
const QClipboard *clipboard = QApplication::clipboard();
|
||||
const QMimeData *mimeData = clipboard->mimeData();
|
||||
@@ -447,7 +452,7 @@ void MixesPanel::mixerlistWidget_customContextMenuRequested(QPoint pos)
|
||||
|
||||
void MixesPanel::mimeMixerDropped(int index, const QMimeData *data, Qt::DropAction action)
|
||||
{
|
||||
int idx= MixerlistWidget->item(index > 0 ? index-1 : 0)->data(Qt::UserRole).toByteArray().at(0);
|
||||
int idx= mixersListWidget->item(index > 0 ? index-1 : 0)->data(Qt::UserRole).toByteArray().at(0);
|
||||
//qDebug() << "MixesPanel::mimeMixerDropped()" << index << data;
|
||||
if (action==Qt::CopyAction) {
|
||||
pasteMixerMimeData(data, idx);
|
||||
@@ -472,10 +477,10 @@ void MixesPanel::mixerlistWidget_KeyPress(QKeyEvent *event)
|
||||
if(event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) mixerOpen();
|
||||
|
||||
if(event->matches(QKeySequence::MoveToNextLine)) {
|
||||
MixerlistWidget->setCurrentRow(MixerlistWidget->currentRow()+1);
|
||||
mixersListWidget->setCurrentRow(mixersListWidget->currentRow()+1);
|
||||
}
|
||||
if(event->matches(QKeySequence::MoveToPreviousLine)) {
|
||||
MixerlistWidget->setCurrentRow(MixerlistWidget->currentRow()-1);
|
||||
mixersListWidget->setCurrentRow(mixersListWidget->currentRow()-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#define _MIXES_H_
|
||||
|
||||
#include "modeledit.h"
|
||||
#include "mixerslist.h"
|
||||
#include "mixerslistwidget.h"
|
||||
#include "mixerdialog.h"
|
||||
#include "modelprinter.h"
|
||||
|
||||
@@ -59,10 +59,9 @@ class MixesPanel : public ModelPanel
|
||||
void pasteMixerMimeData(const QMimeData * mimeData, int destIdx);
|
||||
|
||||
private:
|
||||
MixersList *MixerlistWidget;
|
||||
MixersListWidget * mixersListWidget;
|
||||
bool mixInserted;
|
||||
unsigned int highlightedSource;
|
||||
bool firstLine;
|
||||
ModelPrinter modelPrinter;
|
||||
|
||||
int getMixerIndex(unsigned int dch);
|
||||
|
||||
@@ -38,6 +38,25 @@ void RawSource::convert(Board::Type before, Board::Type after)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SWI to SWR don't exist on !X9E board
|
||||
if (!IS_TARANIS_X9E(after) && IS_TARANIS_X9E(before)) {
|
||||
if (type == SOURCE_TYPE_SWITCH && index >= 8) {
|
||||
index = index % 8;
|
||||
}
|
||||
}
|
||||
|
||||
// No SE and SG on X7 board
|
||||
if (IS_TARANIS_X7(after)) {
|
||||
if (IS_TARANIS_X9(before) || IS_HORUS(before)) {
|
||||
if (type == SOURCE_TYPE_SWITCH && index >= 6) {
|
||||
index -= 2;
|
||||
}
|
||||
else if (type == SOURCE_TYPE_SWITCH && index >= 4) {
|
||||
index -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MixData::convert(Board::Type before, Board::Type after)
|
||||
|
||||
@@ -60,6 +60,7 @@ bool BinEepromFormat::write(const RadioData & radioData)
|
||||
result = writeToFile(eeprom, eeprom_size);
|
||||
}
|
||||
else {
|
||||
// TODO here we could call setError(eepromInterface->errors())
|
||||
setError(QObject::tr("Cannot save EEPROM"));
|
||||
result = false;
|
||||
}
|
||||
|
||||
@@ -330,16 +330,16 @@ bool FirmwareInterface::isValid()
|
||||
return isValidFlag;
|
||||
}
|
||||
|
||||
unsigned int FirmwareInterface::save(QString fileName)
|
||||
unsigned int FirmwareInterface::save(const QString & filename)
|
||||
{
|
||||
uint8_t * binflash = (uint8_t*)malloc(FSIZE_MAX);
|
||||
if (binflash == NULL) {
|
||||
return -1;
|
||||
}
|
||||
memcpy(binflash, flash.constData(), flashSize);
|
||||
QFile file(fileName);
|
||||
QFile file(filename);
|
||||
|
||||
int fileType = getStorageType(fileName);
|
||||
int fileType = getStorageType(filename);
|
||||
|
||||
if (fileType == STORAGE_TYPE_HEX) {
|
||||
if (!file.open(QIODevice::ReadWrite | QIODevice::Truncate | QIODevice::Text)) { //reading HEX TEXT file
|
||||
|
||||
@@ -56,7 +56,7 @@ class FirmwareInterface
|
||||
int getSplashWidth();
|
||||
uint getSplashHeight();
|
||||
QImage::Format getSplashFormat();
|
||||
unsigned int save(QString fileName);
|
||||
unsigned int save(const QString & fileName);
|
||||
bool isValid();
|
||||
|
||||
private:
|
||||
|
||||
@@ -118,8 +118,9 @@ bool convertEEprom(const QString & sourceEEprom, const QString & destinationEEpr
|
||||
}
|
||||
|
||||
QFile destinationFile(destinationEEprom);
|
||||
if (!destinationFile.open(QIODevice::WriteOnly))
|
||||
if (!destinationFile.open(QIODevice::WriteOnly)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int result = destinationFile.write(eeprom.constData(), size);
|
||||
destinationFile.close();
|
||||
|
||||
Reference in New Issue
Block a user