#include #if defined WIN32 #include #include #endif #if !defined WIN32 && defined __GNUC__ #include #endif #include "appdata.h" #include "helpers.h" #include "simulatordialog.h" #include "simulatorinterface.h" #include "flashinterface.h" const QColor colors[C9X_MAX_CURVES] = { QColor(0,0,127), QColor(0,127,0), QColor(127,0,0), QColor(0,127,127), QColor(127,0,127), QColor(127,127,0), QColor(127,127,127), QColor(0,0,255), QColor(0,127,255), QColor(127,0,255), QColor(0,255,0), QColor(0,255,127), QColor(127,255,0), QColor(255,0,0), QColor(255,0,127), QColor(255,127,0), QColor(0,0,127), QColor(0,127,0), QColor(127,0,0), QColor(0,127,127), QColor(127,0,127), QColor(127,127,0), QColor(127,127,127), QColor(0,0,255), QColor(0,127,255), QColor(127,0,255), QColor(0,255,0), QColor(0,255,127), QColor(127,255,0), QColor(255,0,0), QColor(255,0,127), QColor(255,127,0), }; QString getPhaseName(int val, const char * phasename) { if (!val) return "---"; if (!phasename) { return QString(val < 0 ? "!" : "") + QObject::tr("FM%1").arg(abs(val) - 1); } else { QString phaseName; phaseName.append(phasename); if (phaseName.isEmpty()) { return QString(val < 0 ? "!" : "") + QObject::tr("FM%1").arg(abs(val) - 1); } else { return QString(val < 0 ? "!" : "") + phaseName; } } } QString getInputStr(ModelData & model, int index) { QString result; if (GetCurrentFirmware()->getCapability(VirtualInputs)) { if (strlen(model.inputNames[index]) > 0) { result = QObject::tr("[I%1]").arg(index+1); result += QString(model.inputNames[index]); } else { result = QObject::tr("Input%1").arg(index+1, 2, 10, QChar('0')); } } else { result = RawSource(SOURCE_TYPE_STICK, index).toString(model); } return result; } void populateGvSourceCB(QComboBox *b, int value) { QString strings[] = { QObject::tr("---"), QObject::tr("Rud Trim"), QObject::tr("Ele Trim"), QObject::tr("Thr Trim"), QObject::tr("Ail Trim"), QObject::tr("Rot Enc"), QObject::tr("Rud"), QObject::tr("Ele"), QObject::tr("Thr"), QObject::tr("Ail"), QObject::tr("P1"), QObject::tr("P2"), QObject::tr("P3")}; b->clear(); for (int i=0; i<= 12; i++) { b->addItem(strings[i]); } b->setCurrentIndex(value); } QString getProtocolStr(const int proto) { static const char *strings[] = { "OFF", "PPM", "Silverlit A", "Silverlit B", "Silverlit C", "CTP1009", "LP45", "DSM2", "DSMX", "PPM16", "PPMsim", "FrSky XJT - D16", "FrSky XJT - D8", "FrSky XJT - LR12", "FrSky DJT", }; return CHECK_IN_ARRAY(strings, proto); } void populatePhasesCB(QComboBox *b, int value) { for (int i=-GetCurrentFirmware()->getCapability(FlightModes); i<=GetCurrentFirmware()->getCapability(FlightModes); i++) { if (i < 0) b->addItem(QObject::tr("!Flight mode %1").arg(-i-1), i); else if (i > 0) b->addItem(QObject::tr("Flight mode %1").arg(i-1), i); else b->addItem(QObject::tr("----"), 0); } b->setCurrentIndex(value + GetCurrentFirmware()->getCapability(FlightModes)); } GVarGroup::GVarGroup(QCheckBox *weightGV, QAbstractSpinBox *weightSB, QComboBox *weightCB, int & weight, const int deflt, const int mini, const int maxi, const double step, bool allowGvars): QObject(), weightGV(weightGV), weightSB(weightSB), sb(dynamic_cast(weightSB)), dsb(dynamic_cast(weightSB)), weightCB(weightCB), weight(weight), step(step), lock(true) { if (allowGvars && GetCurrentFirmware()->getCapability(Gvars)) { populateGVCB(weightCB, weight); connect(weightGV, SIGNAL(stateChanged(int)), this, SLOT(gvarCBChanged(int))); connect(weightCB, SIGNAL(currentIndexChanged(int)), this, SLOT(valuesChanged())); } else { weightGV->hide(); if (weight > maxi || weight < mini) { weight = deflt; } } int val; if (weight>maxi || weightsetChecked(true); weightSB->hide(); weightCB->show(); } else { val = weight; weightGV->setChecked(false); weightSB->show(); weightCB->hide(); } if (sb) { sb->setMinimum(mini); sb->setMaximum(maxi); sb->setValue(val); } else { dsb->setMinimum(mini*step); dsb->setMaximum(maxi*step); dsb->setValue(val*step); } connect(weightSB, SIGNAL(editingFinished()), this, SLOT(valuesChanged())); lock = false; } void GVarGroup::gvarCBChanged(int state) { weightCB->setVisible(state); if (weightSB) weightSB->setVisible(!state); else weightSB->setVisible(!state); valuesChanged(); } void GVarGroup::valuesChanged() { if (!lock) { if (weightGV->isChecked()) weight = weightCB->itemData(weightCB->currentIndex()).toInt(); else if (sb) weight = sb->value(); else weight = dsb->value()/step; } } CurveGroup::CurveGroup(QComboBox *curveTypeCB, QCheckBox *curveGVarCB, QComboBox *curveValueCB, QSpinBox *curveValueSB, CurveReference & curve, unsigned int flags): QObject(), curveTypeCB(curveTypeCB), curveGVarCB(curveGVarCB), curveValueCB(curveValueCB), curveValueSB(curveValueSB), curve(curve), flags(flags), lock(false), lastType(-1) { curveTypeCB->addItem(tr("Diff")); curveTypeCB->addItem(tr("Expo")); curveTypeCB->addItem(tr("Func")); curveTypeCB->addItem(tr("Curve")); curveValueCB->setMaxVisibleItems(10); connect(curveTypeCB, SIGNAL(currentIndexChanged(int)), this, SLOT(typeChanged(int))); connect(curveGVarCB, SIGNAL(stateChanged(int)), this, SLOT(gvarCBChanged(int))); connect(curveValueCB, SIGNAL(currentIndexChanged(int)), this, SLOT(valuesChanged())); connect(curveValueSB, SIGNAL(editingFinished()), this, SLOT(valuesChanged())); update(); } void CurveGroup::update() { lock = true; curveTypeCB->setCurrentIndex(curve.type); if (curve.type == CurveReference::CURVE_REF_DIFF || curve.type == CurveReference::CURVE_REF_EXPO) { curveGVarCB->show(); if (curve.value > 100 || curve.value < -100) { curveGVarCB->setChecked(true); if (lastType != CurveReference::CURVE_REF_DIFF && lastType != CurveReference::CURVE_REF_EXPO) { lastType = curve.type; populateGVCB(curveValueCB, curve.value); } curveValueCB->show(); curveValueSB->hide(); } else { curveGVarCB->setChecked(false); curveValueSB->setMinimum(-100); curveValueSB->setMaximum(100); curveValueSB->setValue(curve.value); curveValueSB->show(); curveValueCB->hide(); } } else { curveGVarCB->hide(); curveValueSB->hide(); curveValueCB->show(); switch (curve.type) { case CurveReference::CURVE_REF_FUNC: if (lastType != curve.type) { lastType = curve.type; curveValueCB->clear(); for (int i=0; i<=6/*TODO constant*/; i++) { curveValueCB->addItem(CurveReference(CurveReference::CURVE_REF_FUNC, i).toString()); } } curveValueCB->setCurrentIndex(curve.value); break; case CurveReference::CURVE_REF_CUSTOM: { int numcurves = GetCurrentFirmware()->getCapability(NumCurves); if (lastType != curve.type) { lastType = curve.type; curveValueCB->clear(); for (int i=-numcurves; i<=numcurves; i++) { curveValueCB->addItem(CurveReference(CurveReference::CURVE_REF_CUSTOM, i).toString()); } } curveValueCB->setCurrentIndex(curve.value+numcurves); break; } default: break; } } lock = false; } void CurveGroup::gvarCBChanged(int state) { if (!lock) { if (state) { curve.value = 10000+1; // TODO constant in EEpromInterface ... } else { curve.value = 0; // TODO could be better } update(); } } void CurveGroup::typeChanged(int value) { if (!lock) { switch (value) { case 0: curve = CurveReference(CurveReference::CURVE_REF_DIFF, 0); break; case 1: curve = CurveReference(CurveReference::CURVE_REF_EXPO, 0); break; case 2: curve = CurveReference(CurveReference::CURVE_REF_FUNC, 0); break; case 3: curve = CurveReference(CurveReference::CURVE_REF_CUSTOM, 0); break; } update(); } } void CurveGroup::valuesChanged() { if (!lock) { switch (curveTypeCB->currentIndex()) { case 0: case 1: { int value; if (curveGVarCB->isChecked()) value = curveValueCB->itemData(curveValueCB->currentIndex()).toInt(); else value = curveValueSB->value(); curve = CurveReference(curveTypeCB->currentIndex() == 0 ? CurveReference::CURVE_REF_DIFF : CurveReference::CURVE_REF_EXPO, value); break; } case 2: curve = CurveReference(CurveReference::CURVE_REF_FUNC, curveValueCB->currentIndex()); break; case 3: curve = CurveReference(CurveReference::CURVE_REF_CUSTOM, curveValueCB->currentIndex() - GetCurrentFirmware()->getCapability(NumCurves)); break; } update(); } } void populateGvarUseCB(QComboBox *b, unsigned int phase) { b->addItem(QObject::tr("Own value")); for (int i=0; igetCapability(FlightModes); i++) { if (i != (int)phase) { b->addItem(QObject::tr("Flight mode %1 value").arg(i)); } } } void populateSwitchCB(QComboBox *b, const RawSwitch & value, const GeneralSettings & generalSettings, SwitchContext context) { RawSwitch item; b->clear(); if (context != MixesContext) { // !FMx if (IS_ARM(GetCurrentFirmware()->getBoard())) { for (int i=-GetCurrentFirmware()->getCapability(FlightModes); i<0; i++) { item = RawSwitch(SWITCH_TYPE_FLIGHT_MODE, i); b->addItem(item.toString(), item.toValue()); if (item == value) b->setCurrentIndex(b->count()-1); } } } for (int i=-GetCurrentFirmware()->getCapability(LogicalSwitches); i<0; i++) { item = RawSwitch(SWITCH_TYPE_VIRTUAL, i); b->addItem(item.toString(), item.toValue()); if (item == value) b->setCurrentIndex(b->count()-1); } for (int i=-GetCurrentFirmware()->getCapability(RotaryEncoders); i<0; i++) { item = RawSwitch(SWITCH_TYPE_ROTARY_ENCODER, i); b->addItem(item.toString(), item.toValue()); if (item == value) b->setCurrentIndex(b->count()-1); } for (int i=-8; i<0; i++) { item = RawSwitch(SWITCH_TYPE_TRIM, i); b->addItem(item.toString(), item.toValue()); if (item == value) b->setCurrentIndex(b->count()-1); } for (int i=GetCurrentFirmware()->getCapability(MultiposPots)-1; i>=0; i--) { if (generalSettings.potsType[i] == 2/* TODO constant*/) { for (int j=-GetCurrentFirmware()->getCapability(MultiposPotsPositions); j<0; j++) { item = RawSwitch(SWITCH_TYPE_MULTIPOS_POT, -i*GetCurrentFirmware()->getCapability(MultiposPotsPositions)+j); b->addItem(item.toString(), item.toValue()); if (item == value) b->setCurrentIndex(b->count()-1); } } } for (int i=-GetCurrentFirmware()->getCapability(SwitchesPositions); i<0; i++) { item = RawSwitch(SWITCH_TYPE_SWITCH, i); if (IS_TARANIS(GetCurrentFirmware()->getBoard())) { //hide up and down for !SH and !SF, because they are redundant (!SFup == SFdown) if (item.toString().contains("H") || item.toString().contains("F")) continue; } b->addItem(item.toString(), item.toValue()); if (item == value) b->setCurrentIndex(b->count()-1); } if (context == TimersContext) { for (int i=0; i<5; i++) { item = RawSwitch(SWITCH_TYPE_TIMER_MODE, i); b->addItem(item.toString(), item.toValue()); if (item == value) b->setCurrentIndex(b->count()-1); } } else { item = RawSwitch(SWITCH_TYPE_NONE); b->addItem(item.toString(), item.toValue()); if (item == value) b->setCurrentIndex(b->count()-1); } for (int i=1; i<=GetCurrentFirmware()->getCapability(SwitchesPositions); i++) { item = RawSwitch(SWITCH_TYPE_SWITCH, i); b->addItem(item.toString(), item.toValue()); if (item == value) b->setCurrentIndex(b->count()-1); } for (int i=0; igetCapability(MultiposPots); i++) { if (generalSettings.potsType[i] == 2/* TODO constant*/) { for (int j=1; j<=GetCurrentFirmware()->getCapability(MultiposPotsPositions); j++) { item = RawSwitch(SWITCH_TYPE_MULTIPOS_POT, i*GetCurrentFirmware()->getCapability(MultiposPotsPositions)+j); b->addItem(item.toString(), item.toValue()); if (item == value) b->setCurrentIndex(b->count()-1); } } } for (int i=1; i<=8; i++) { item = RawSwitch(SWITCH_TYPE_TRIM, i); b->addItem(item.toString(), item.toValue()); if (item == value) b->setCurrentIndex(b->count()-1); } for (int i=1; i<=GetCurrentFirmware()->getCapability(RotaryEncoders); i++) { item = RawSwitch(SWITCH_TYPE_ROTARY_ENCODER, i); b->addItem(item.toString(), item.toValue()); if (item == value) b->setCurrentIndex(b->count()-1); } for (int i=1; i<=GetCurrentFirmware()->getCapability(LogicalSwitches); i++) { item = RawSwitch(SWITCH_TYPE_VIRTUAL, i); b->addItem(item.toString(), item.toValue()); if (item == value) b->setCurrentIndex(b->count()-1); } if (context == CustomFunctionsContext) { // ON item = RawSwitch(SWITCH_TYPE_ON); b->addItem(item.toString(), item.toValue()); if (item == value) b->setCurrentIndex(b->count()-1); // One item = RawSwitch(SWITCH_TYPE_ONE, 1); b->addItem(item.toString(), item.toValue()); if (item == value) b->setCurrentIndex(b->count()-1); } // FMx if (context != MixesContext) { if (IS_ARM(GetCurrentFirmware()->getBoard())) { for (int i=1; i<=GetCurrentFirmware()->getCapability(FlightModes); i++) { item = RawSwitch(SWITCH_TYPE_FLIGHT_MODE, i); b->addItem(item.toString(), item.toValue()); if (item == value) b->setCurrentIndex(b->count()-1); } } } b->setMaxVisibleItems(10); } void populateGVCB(QComboBox *b, int value) { bool selected = false; b->clear(); int pgvars = GetCurrentFirmware()->getCapability(Gvars); for (int i=-pgvars; i<=-1; i++) { int16_t gval = (int16_t)(-10000+i); b->addItem(QObject::tr("-GV%1").arg(-i), gval); if (value == gval) { b->setCurrentIndex(b->count()-1); selected = true; } } for (int i=1; i<=pgvars; i++) { int16_t gval = (int16_t)(10000+i); b->addItem(QObject::tr("GV%1").arg(i), gval); if (value == gval) { b->setCurrentIndex(b->count()-1); selected = true; } } if (!selected) { b->setCurrentIndex(pgvars); } } void populateSourceCB(QComboBox *b, const RawSource & source, const ModelData & model, unsigned int flags) { BoardEnum board = GetCurrentFirmware()->getBoard(); RawSource item; b->clear(); if (flags & POPULATE_SOURCES) { item = RawSource(SOURCE_TYPE_NONE); b->addItem(item.toString(model), item.toValue()); if (item == source) b->setCurrentIndex(b->count()-1); } if (flags & POPULATE_SCRIPT_OUTPUTS) { for (int i=0; igetCapability(LuaScripts); i++) { for (int j=0; jgetCapability(LuaOutputsPerScript); j++) { item = RawSource(SOURCE_TYPE_LUA_OUTPUT, i*16+j); b->addItem(item.toString(model), item.toValue()); if (item == source) b->setCurrentIndex(b->count()-1); } } } if (flags & POPULATE_VIRTUAL_INPUTS) { int virtualInputs = GetCurrentFirmware()->getCapability(VirtualInputs); for (int i=0; iaddItem(item.toString(model), item.toValue()); if (item == source) b->setCurrentIndex(b->count()-1); } } } if (flags & POPULATE_SOURCES) { for (int i=0; i<4+GetCurrentFirmware()->getCapability(Pots); i++) { item = RawSource(SOURCE_TYPE_STICK, i); b->addItem(item.toString(model), item.toValue()); if (item == source) b->setCurrentIndex(b->count()-1); } for (int i=0; igetCapability(RotaryEncoders); i++) { item = RawSource(SOURCE_TYPE_ROTARY_ENCODER, i); b->addItem(item.toString(model), item.toValue()); if (item == source) b->setCurrentIndex(b->count()-1); } } if (flags & POPULATE_TRIMS) { for (int i=0; i<4; i++) { item = RawSource(SOURCE_TYPE_TRIM, i); b->addItem(item.toString(model), item.toValue()); if (item == source) b->setCurrentIndex(b->count()-1); } } if (flags & POPULATE_SOURCES) { item = RawSource(SOURCE_TYPE_MAX); b->addItem(item.toString(model), item.toValue()); if (item == source) b->setCurrentIndex(b->count()-1); } if (flags & POPULATE_SWITCHES) { for (int i=0; igetCapability(Switches); i++) { item = RawSource(SOURCE_TYPE_SWITCH, i); b->addItem(item.toString(model), item.toValue()); if (item == source) b->setCurrentIndex(b->count()-1); } for (int i=0; igetCapability(LogicalSwitches); i++) { item = RawSource(SOURCE_TYPE_CUSTOM_SWITCH, i); b->addItem(item.toString(model), item.toValue()); if (item == source) b->setCurrentIndex(b->count()-1); } } if (flags & POPULATE_SOURCES) { for (int i=0; iaddItem(item.toString(model), item.toValue()); if (item == source) b->setCurrentIndex(b->count()-1); } for (int i=0; igetCapability(TrainerInputs); i++) { item = RawSource(SOURCE_TYPE_PPM, i); b->addItem(item.toString(model), item.toValue()); if (item == source) b->setCurrentIndex(b->count()-1); } for (int i=0; igetCapability(Outputs); i++) { item = RawSource(SOURCE_TYPE_CH, i); b->addItem(item.toString(model), item.toValue()); if (item == source) b->setCurrentIndex(b->count()-1); } } if (flags & POPULATE_TELEMETRYEXT) { for (int i=0; iaddItem(item.toString(model), item.toValue()); if (item == source) b->setCurrentIndex(b->count()-1); } } else if (flags & POPULATE_TELEMETRY) { for (int i=0; iaddItem(item.toString(model), item.toValue()); if (item == source) b->setCurrentIndex(b->count()-1); } } if (flags & POPULATE_GVARS) { for (int i=0; igetCapability(Gvars); i++) { item = RawSource(SOURCE_TYPE_GVAR, i); b->addItem(item.toString(model), item.toValue()); if (item == source) b->setCurrentIndex(b->count()-1); } } b->setMaxVisibleItems(10); } QString image2qstring(QImage image) { if (image.isNull()) return ""; QBuffer buffer; image.save(&buffer, "PNG"); QString ImageStr; int b=0; int size=buffer.data().size(); for (int j = 0; j < size; j++) { b=buffer.data().at(j); ImageStr += QString("%1").arg(b&0xff, 2, 16, QChar('0')); } return ImageStr; } // TODO KKERNEN 20140222 // I am sure that this code has had some kind of function, but now it only seems to cause // problems. I think it is an attempt to open an image file from a double byte string which // is first converted to a single byte string. Only used in burndialog.cpp // It doesn't work for me in 2.0. I do not know why. I doubt it has ever worked for files or // file paths containing non-english characters. // Code can be removed ,when 2.0 is tested. QImage qstring2image(QString imagestr) { bool ok; bool failed=false; QImage Image; int len = imagestr.length(); char b=0; QBuffer buffer; buffer.open(QIODevice::ReadWrite); buffer.seek(0); for (int i = 0; i < len/2; i++) { QString Byte; Byte = imagestr.mid((i * 2), 2); b = Byte.toUInt(&ok, 16); if (!ok) { failed = true; } buffer.putChar(b); } buffer.seek(0); if (!failed) { Image.load(&buffer,"PNG"); } return Image; } int findmult(float value, float base) { int vvalue = value*10; int vbase = base*10; vvalue--; int mult = 0; for (int i=8; i>=0; i--) { if (vvalue/vbase >= (1<getCapability(Telemetry) & TM_HASWSHH)) return QObject::tr("Winged Shadow How High"); else return QObject::tr("Winged Shadow How High (not supported)"); case 1: return QObject::tr("FrSky Sensor Hub"); default: return QObject::tr("None"); } } QString getFrSkyMeasure(int units) { switch(units) { case 1: return QObject::tr("Imperial"); default: return QObject::tr("Metric"); } } QString getFrSkySrc(int index) { ModelData model; return RawSource(SOURCE_TYPE_TELEMETRY, index-1).toString(model); } QString getTrimInc(ModelData * g_model) { switch (g_model->trimInc) { case -2: return QObject::tr("Exponential"); case -1: return QObject::tr("Extra Fine"); case 0: return QObject::tr("Fine"); case 1: return QObject::tr("Medium"); case 2: return QObject::tr("Coarse"); default: return QObject::tr("Unknown"); } } QString getTimerStr(TimerData & timer) { QString result = QObject::tr("%1:%2").arg(timer.val/60, 2, 10, QChar('0')).arg(timer.val%60, 2, 10, QChar('0')); result += QString(", ") + timer.mode.toString(); if (timer.persistent) result += QObject::tr(", Persistent"); if (timer.minuteBeep) result += QObject::tr(", MinuteBeep"); if (timer.countdownBeep == 1) result += QObject::tr(", CountDown(Beeps)"); else if (timer.countdownBeep == 2) result += QObject::tr(", CountDown(Voice)"); return result; } QString getProtocol(ModelData * g_model) { QString str = getProtocolStr(g_model->moduleData[0].protocol); if (g_model->moduleData[0].protocol == PPM) str.append(QObject::tr(": %1 Channels, %2usec Delay").arg(g_model->moduleData[0].channelsCount).arg(g_model->moduleData[0].ppmDelay)); return str; } QString getPhasesStr(unsigned int phases, ModelData & model) { int numphases = GetCurrentFirmware()->getCapability(FlightModes); if (numphases && phases) { QString str; int count = 0; if (phases == (unsigned int)(1< 0) str += QString(", "); str += getPhaseName(i+1, model.flightModeData[i].name); } } } if (count > 1) return QObject::tr("Flight modes(%1)").arg(str); else return QObject::tr("Flight mode(%1)").arg(str); } else { return ""; } } QString getCenterBeepStr(ModelData * g_model) { QStringList strl; if (g_model->beepANACenter & 0x01) strl << QObject::tr("Rudder"); if (g_model->beepANACenter & 0x02) strl << QObject::tr("Elevator"); if (g_model->beepANACenter & 0x04) strl << QObject::tr("Throttle"); if (g_model->beepANACenter & 0x08) strl << QObject::tr("Aileron"); if (IS_TARANIS(GetCurrentFirmware()->getBoard())) { if (g_model->beepANACenter & 0x10) strl << "S1"; if (g_model->beepANACenter & 0x20) strl << "S2"; if (g_model->beepANACenter & 0x40) strl << "S3"; if (g_model->beepANACenter & 0x80) strl << "LS"; if (g_model->beepANACenter & 0x100) strl << "RS"; } else { if (g_model->beepANACenter & 0x10) strl << "P1"; if (g_model->beepANACenter & 0x20) strl << "P2"; if (g_model->beepANACenter & 0x40) strl << "P3"; } return strl.join(", "); } QString getTheme() { int theme_set = g.theme(); QString Theme; switch(theme_set) { case 0: Theme="classic"; break; case 2: Theme="monowhite"; break; case 3: Theme="monochrome"; break; case 4: Theme="monoblue"; break; default: Theme="yerico"; break; } return Theme; } CompanionIcon::CompanionIcon(QString baseimage) { static QString theme = getTheme(); addFile(":/themes/"+theme+"/16/"+baseimage, QSize(16,16)); addFile(":/themes/"+theme+"/24/"+baseimage, QSize(24,24)); addFile(":/themes/"+theme+"/32/"+baseimage, QSize(32,32)); addFile(":/themes/"+theme+"/48/"+baseimage, QSize(48,48)); } void startSimulation(QWidget * parent, RadioData & radioData, int modelIdx) { SimulatorInterface * si = GetCurrentFirmware()->getSimulator(); if (si) { delete si; RadioData * simuData = new RadioData(radioData); unsigned int flags = 0; if (modelIdx >= 0) { flags |= SIMULATOR_FLAGS_NOTX; simuData->generalSettings.currModel = modelIdx; } if (radioData.generalSettings.stickMode & 1) { flags |= SIMULATOR_FLAGS_STICK_MODE_LEFT; } BoardEnum board = GetCurrentFirmware()->getBoard(); SimulatorDialog * sd; if (IS_TARANIS(board)) sd = new SimulatorDialogTaranis(parent, flags); else sd = new SimulatorDialog9X(parent, flags); QByteArray eeprom(GetEepromInterface()->getEEpromSize(), 0); GetEepromInterface()->save((uint8_t *)eeprom.data(), *simuData, GetCurrentFirmware()->getCapability(SimulatorVariant)); delete simuData; sd->start(eeprom); sd->exec(); delete sd; } else { QMessageBox::warning(NULL, QObject::tr("Warning"), QObject::tr("Simulator for this firmware is not yet available")); } } QPixmap makePixMap( QImage image, QString firmwareType ) { if (firmwareType.contains( "taranis" )) { image = image.convertToFormat(QImage::Format_RGB32); QRgb col; int gray; for (int i = 0; i < image.width(); ++i) { for (int j = 0; j < image.height(); ++j) { col = image.pixel(i, j); gray = qGray(col); image.setPixel(i, j, qRgb(gray, gray, gray)); } } image = image.scaled(SPLASHX9D_WIDTH, SPLASHX9D_HEIGHT); } else { image = image.scaled(SPLASH_WIDTH, SPLASH_HEIGHT).convertToFormat(QImage::Format_Mono); } return(QPixmap::fromImage(image)); } int version2index(QString version) { QStringList parts = version.split('.'); int result = 0; if (parts.size() > 2) result = parts[2].toInt(); if (parts.size() > 1) result += 100 * parts[1].toInt(); if (parts.size() > 0) result += 10000 * parts[0].toInt(); return result; } QString index2version(int index) { if (index >= 19900) { int revision = index % 100; index /= 100; int minor = index % 100; int major = index / 100; return QString("%1.%2.%3").arg(major).arg(minor).arg(revision); } else { return QString(); } } int qunlink(const QString & fileName) { QByteArray ba = fileName.toLatin1(); return unlink(ba.constData()); } QString generateProcessUniqueTempFileName(const QString & fileName) { QString sanitizedFileName = fileName; sanitizedFileName.remove('/'); return QDir::tempPath() + QString("/%1-").arg(QCoreApplication::applicationPid()) + sanitizedFileName; } GenericPanel::GenericPanel(QWidget * parent): QWidget(parent), lock(false) { } GenericPanel::~GenericPanel() { } void GenericPanel::update() { } void GenericPanel::addLabel(QGridLayout * gridLayout, QString text, int col, bool minimize) { QLabel *label = new QLabel(this); label->setFrameShape(QFrame::Panel); label->setFrameShadow(QFrame::Raised); label->setMidLineWidth(0); label->setAlignment(Qt::AlignCenter); label->setMargin(5); label->setText(text); if (!minimize) label->setMinimumWidth(100); gridLayout->addWidget(label, 0, col, 1, 1); } void GenericPanel::addEmptyLabel(QGridLayout * gridLayout, int col) { QLabel *label = new QLabel(this); label->setText(""); gridLayout->addWidget(label, 0, col, 1, 1); } void GenericPanel::addHSpring(QGridLayout * gridLayout, int col, int row) { QSpacerItem * spacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum ); gridLayout->addItem(spacer, row, col); } void GenericPanel::addVSpring(QGridLayout * gridLayout, int col, int row) { QSpacerItem * spacer = new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding ); gridLayout->addItem(spacer, row, col); } void GenericPanel::addDoubleSpring(QGridLayout * gridLayout, int col, int row) { QSpacerItem * spacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Expanding ); gridLayout->addItem(spacer, row, col); } bool GenericPanel::eventFilter(QObject *object, QEvent * event) { QWidget * widget = qobject_cast(object); if (widget) { if (event->type() == QEvent::Wheel) { if (widget->focusPolicy() == Qt::WheelFocus) { event->accept(); return false; } else { event->ignore(); return true; } } else if (event->type() == QEvent::FocusIn) { widget->setFocusPolicy(Qt::WheelFocus); } else if (event->type() == QEvent::FocusOut) { widget->setFocusPolicy(Qt::StrongFocus); } } return QWidget::eventFilter(object, event); } void GenericPanel::disableMouseScrolling() { Q_FOREACH(QComboBox * cb, findChildren()) { cb->installEventFilter(this); cb->setFocusPolicy(Qt::StrongFocus); } Q_FOREACH(QAbstractSpinBox * sb, findChildren()) { sb->installEventFilter(this); sb->setFocusPolicy(Qt::StrongFocus); } Q_FOREACH(QSlider * slider, findChildren()) { slider->installEventFilter(this); slider->setFocusPolicy(Qt::StrongFocus); } } VerticalScrollArea::VerticalScrollArea(QWidget * parent, GenericPanel * panel): QScrollArea(parent), panel(panel), parent(parent) { setWidgetResizable(true); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setWidget(panel); panel->installEventFilter(this); } bool VerticalScrollArea::eventFilter(QObject *o, QEvent *e) { if (o == panel && e->type() == QEvent::Resize) { setMinimumWidth(panel->minimumSizeHint().width() + verticalScrollBar()->width()); } return false; }