diff --git a/companion/src/CMakeLists.txt b/companion/src/CMakeLists.txt index 0c8f7e70b..b5f1e17bd 100644 --- a/companion/src/CMakeLists.txt +++ b/companion/src/CMakeLists.txt @@ -191,6 +191,7 @@ SET( companion9x_MOC_HDRS myslider.h modelconfigdialog.h qcustomplot.h + helpers.h ) SET( companion9x_UIS diff --git a/companion/src/eeprominterface.cpp b/companion/src/eeprominterface.cpp index a8736f9e1..998e8d9bf 100644 --- a/companion/src/eeprominterface.cpp +++ b/companion/src/eeprominterface.cpp @@ -412,7 +412,7 @@ QString RawSwitch::toString() QString CurveReference::toString() { if (value == 0) { - return ""; + return "----"; } else { switch(type) { diff --git a/companion/src/eeprominterface.h b/companion/src/eeprominterface.h index f5c5762af..02cc9650d 100644 --- a/companion/src/eeprominterface.h +++ b/companion/src/eeprominterface.h @@ -1008,6 +1008,11 @@ enum Capability { CSFunc, LCDWidth, GetThrSwitch, + VirtualInputs, + LuaInputs, + LimitsPer1000, + EnhancedCurves, + TelemetryInternalAlarms }; enum UseContext { diff --git a/companion/src/firmwares/opentx/opentxinterface.cpp b/companion/src/firmwares/opentx/opentxinterface.cpp index c07f0875a..73738e0b4 100644 --- a/companion/src/firmwares/opentx/opentxinterface.cpp +++ b/companion/src/firmwares/opentx/opentxinterface.cpp @@ -694,7 +694,13 @@ int Open9xInterface::getCapability(const Capability capability) case LCDWidth: return (IS_TARANIS(board) ? 212 : 128) ; case GetThrSwitch: - return (IS_TARANIS(board) ?DSW_SF1 : DSW_THR) ; + return (IS_TARANIS(board) ? DSW_SF1 : DSW_THR) ; + case VirtualInputs: + case LuaInputs: + case LimitsPer1000: + case EnhancedCurves: + case TelemetryInternalAlarms: + return IS_TARANIS(board); default: return 0; } diff --git a/companion/src/helpers.cpp b/companion/src/helpers.cpp index 142b65b43..27094edda 100644 --- a/companion/src/helpers.cpp +++ b/companion/src/helpers.cpp @@ -471,14 +471,35 @@ void populatePhasesCB(QComboBox *b, int value) b->setCurrentIndex(value + GetEepromInterface()->getCapability(FlightPhases)); } -void populateCurveReference(QComboBox *curveTypeCB, QCheckBox *curveGVarCB, QComboBox *curveValueCB, QSpinBox *curveValueSB, CurveReference & curve, unsigned int flags) +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) { - if (curveTypeCB->count() == 0) { - curveTypeCB->addItem(QObject::tr("Diff")); - curveTypeCB->addItem(QObject::tr("Expo")); - curveTypeCB->addItem(QObject::tr("Func")); - curveTypeCB->addItem(QObject::tr("Curve")); - } + 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(valuesChanged())); + 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); @@ -486,7 +507,10 @@ void populateCurveReference(QComboBox *curveTypeCB, QCheckBox *curveGVarCB, QCom curveGVarCB->show(); if (curve.value > 100 || curve.value < -100) { curveGVarCB->setChecked(true); - populateGVCB(curveValueCB, curve.value); + if (lastType != CurveReference::CURVE_REF_DIFF && lastType != CurveReference::CURVE_REF_EXPO) { + lastType = curve.type; + populateGVCB(curveValueCB, curve.value); + } curveValueCB->show(); curveValueSB->hide(); } @@ -503,19 +527,26 @@ void populateCurveReference(QComboBox *curveTypeCB, QCheckBox *curveGVarCB, QCom curveGVarCB->hide(); curveValueSB->hide(); curveValueCB->show(); - curveValueCB->setMaxVisibleItems(10); switch (curve.type) { case CurveReference::CURVE_REF_FUNC: - for (int i=0; i<=6/*TODO constant*/; i++) { - curveValueCB->addItem(CurveReference(CurveReference::CURVE_REF_FUNC, i).toString()); + 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 = GetEepromInterface()->getCapability(NumCurves); - for (int i=-numcurves; iaddItem(CurveReference(CurveReference::CURVE_REF_CUSTOM, i).toString()); + if (lastType != curve.type) { + lastType = curve.type; + curveValueCB->clear(); + for (int i=-numcurves; iaddItem(CurveReference(CurveReference::CURVE_REF_CUSTOM, i).toString()); + } } curveValueCB->setCurrentIndex(curve.value+numcurves); break; @@ -524,31 +555,49 @@ void populateCurveReference(QComboBox *curveTypeCB, QCheckBox *curveGVarCB, QCom break; } } + + lock = false; } -void retrieveCurveReference(QComboBox *curveTypeCB, QCheckBox *curveGVarCB, QComboBox *curveValueCB, QSpinBox *curveValueSB, CurveReference & curve, unsigned int flags) +void CurveGroup::gvarCBChanged(int state) { - switch (curveTypeCB->currentIndex()) { - case 0: - case 1: - { - int value; - if (curveGVarCB->isChecked()) - value = curveValueCB->itemData(curveValueCB->currentIndex()).toInt(); - else - value = curveValueSB->value(); - qDebug() << value; - curve = CurveReference(curveTypeCB->currentIndex() == 0 ? CurveReference::CURVE_REF_DIFF : CurveReference::CURVE_REF_EXPO, value); - break; + if (!lock) { + if (state) { + curve.value = 10000; // TODO constant in EEpromInterface ... } - case 2: - curve = CurveReference(CurveReference::CURVE_REF_FUNC, curveValueCB->currentIndex()); - break; - case 3: - curve = CurveReference(CurveReference::CURVE_REF_CUSTOM, curveValueCB->currentIndex() - GetEepromInterface()->getCapability(NumCurves)); - break; + else { + curve.value = 0; // TODO could be better + } + + 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() - GetEepromInterface()->getCapability(NumCurves)); + break; + } + + update(); } - populateCurveReference(curveTypeCB, curveGVarCB, curveValueCB, curveValueSB, curve, flags); } void populateTrimUseCB(QComboBox *b, unsigned int phase) @@ -831,7 +880,9 @@ void populateGVCB(QComboBox *b, int value) { int selected=0; int nullitem; + b->clear(); + int pgvars = GetEepromInterface()->getCapability(Gvars); for (int i=-pgvars; i<=-1; i++) { int16_t gval = (int16_t)(-10000+i); @@ -841,12 +892,15 @@ void populateGVCB(QComboBox *b, int value) selected=1; } } + b->addItem("---", 0); + nullitem=b->count()-1; if (value == 0) { b->setCurrentIndex(b->count()-1); selected=1; } + for (int i=1; i<=pgvars; i++) { int16_t gval = (int16_t)(10000+i); b->addItem(QObject::tr("GV%1").arg(i), gval); @@ -855,6 +909,7 @@ void populateGVCB(QComboBox *b, int value) selected=1; } } + if (selected==0) b->setCurrentIndex(nullitem); } diff --git a/companion/src/helpers.h b/companion/src/helpers.h index 511f726c1..33a3d21df 100644 --- a/companion/src/helpers.h +++ b/companion/src/helpers.h @@ -29,6 +29,29 @@ void populateTTraceCB(QComboBox *b, int value); void populateRotEncCB(QComboBox *b, int value, int renumber); void populateBacklightCB(QComboBox *b, const uint8_t value); +class CurveGroup : public QObject { + + Q_OBJECT + + public: + CurveGroup(QComboBox *curveTypeCB, QCheckBox *curveGVarCB, QComboBox *curveValueCB, QSpinBox *curveValueSB, CurveReference & curve, unsigned int flags=0); + void update(); + + protected slots: + void gvarCBChanged(int); + void valuesChanged(); + + protected: + QComboBox *curveTypeCB; + QCheckBox *curveGVarCB; + QComboBox *curveValueCB; + QSpinBox *curveValueSB; + CurveReference & curve; + unsigned int flags; + bool lock; + int lastType; +}; + #define POPULATE_ONOFF 0x01 #define POPULATE_MSWITCHES 0x02 #define POPULATE_AND_SWITCHES 0x04 @@ -42,9 +65,6 @@ void populateFuncParamArmTCB(QComboBox *b, ModelData * g_model, char * value, QS void populatePhasesCB(QComboBox *b, int value); void populateTrimUseCB(QComboBox *b, unsigned int phase); void populateGvarUseCB(QComboBox *b, unsigned int phase); -void populateCurveReference(QComboBox *curveTypeCB, QCheckBox *curveGVarCB, QComboBox *curveValueCB, QSpinBox *curveValueSB, CurveReference & curve, unsigned int flags); -void retrieveCurveReference(QComboBox *curveTypeCB, QCheckBox *curveGVarCB, QComboBox *curveValueCB, QSpinBox *curveValueSB, CurveReference & curve, unsigned int flags); -void populateCurvesCB(QComboBox *b, int value); void populateCustomScreenFieldCB(QComboBox *b, unsigned int value, bool last, int hubproto); void populateTimerSwitchCB(QComboBox *b, int value); QString getCustomSwitchStr(CustomSwData * customSw, const ModelData & model); diff --git a/companion/src/main.cpp b/companion/src/main.cpp index 9cdbf430e..ed5cc25b0 100644 --- a/companion/src/main.cpp +++ b/companion/src/main.cpp @@ -77,10 +77,10 @@ class MyProxyStyle : public QProxyStyle int main(int argc, char *argv[]) { Q_INIT_RESOURCE(companion9x); - QApplication app(argc, argv); - app.setApplicationName("Companion9x"); + QApplication * app = new QApplication(argc, argv); + app->setApplicationName("Companion9x"); #ifdef __APPLE__ - app.setStyle(new MyProxyStyle); + app->setStyle(new MyProxyStyle); #endif QString dir; if(argc) dir = QFileInfo(argv[0]).canonicalPath() + "/lang"; @@ -95,20 +95,20 @@ int main(int argc, char *argv[]) qtTranslator.load((QString)"qt_" + locale.left(2), QLibraryInfo::location(QLibraryInfo::TranslationsPath)); // qDebug() << locale; // qtTranslator.load("qt_" + QLocale::system().name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath)); - app.installTranslator(&companion9xTranslator); - app.installTranslator(&qtTranslator); + app->installTranslator(&companion9xTranslator); + app->installTranslator(&qtTranslator); QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); QString firmware_id = settings.value("firmware", default_firmware_variant.id).toString(); firmware_id.replace("open9x", "opentx"); firmware_id.replace("x9da", "taranis"); - QPixmap pixmap; + QPixmap * pixmap; if (firmware_id.contains("taranis")) - pixmap = QPixmap(":/images/splasht.png"); + pixmap = new QPixmap(":/images/splasht.png"); else - pixmap = QPixmap(":/images/splash.png"); - QSplashScreen *splash = new QSplashScreen(pixmap); + pixmap = new QPixmap(":/images/splash.png"); + QSplashScreen *splash = new QSplashScreen(*pixmap); RegisterFirmwares(); @@ -116,15 +116,15 @@ int main(int argc, char *argv[]) current_firmware_variant = GetFirmwareVariant(firmware_id); // qDebug() << current_firmware_variant; - MainWindow mainWin; + MainWindow * mainWin = new MainWindow(); if (showSplash) { splash->show(); QTimer::singleShot(1000*SPLASH_TIME, splash, SLOT(close())); - QTimer::singleShot(1000*SPLASH_TIME, &mainWin, SLOT(show())); + QTimer::singleShot(1000*SPLASH_TIME, mainWin, SLOT(show())); } else { - mainWin.show(); + mainWin->show(); } - return app.exec(); + return app->exec(); } diff --git a/companion/src/modeledit/expodialog.cpp b/companion/src/modeledit/expodialog.cpp index 1a664cb20..6a027bcf6 100644 --- a/companion/src/modeledit/expodialog.cpp +++ b/companion/src/modeledit/expodialog.cpp @@ -51,9 +51,11 @@ ExpoDialog::ExpoDialog(QWidget *parent, ExpoData *expoData, int stickMode) : } populateSwitchCB(ui->switchesCB,ed->swtch); - populateCurveReference(ui->curveTypeCB, ui->curveGVarCB, ui->curveValueCB, ui->curveValueSB, ed->curve, 0); - ui->modeCB->setCurrentIndex(ed->mode-1); + // TODO keep this group, same in MixerDialog + CurveGroup * curveGroup = new CurveGroup(ui->curveTypeCB, ui->curveGVarCB, ui->curveValueCB, ui->curveValueSB, ed->curve); + + ui->sideCB->setCurrentIndex(ed->mode-1); ui->label_expo->hide(); @@ -77,6 +79,19 @@ ExpoDialog::ExpoDialog(QWidget *parent, ExpoData *expoData, int stickMode) : } } + if (GetEepromInterface()->getCapability(VirtualInputs)) { + ui->sideLabel->hide(); + ui->sideCB->hide(); + } + else { + ui->sourceLabel->hide(); + ui->sourceCB->hide(); + ui->scaleLabel->hide(); + ui->scaleSB->hide(); + ui->trimLabel->hide(); + ui->trimCB->hide(); + } + int expolength=GetEepromInterface()->getCapability(HasExpoNames); if (!expolength) { ui->label_name->hide(); @@ -101,7 +116,7 @@ ExpoDialog::ExpoDialog(QWidget *parent, ExpoData *expoData, int stickMode) : connect(ui->weightCB,SIGNAL(currentIndexChanged(int)),this,SLOT(valuesChanged())); connect(ui->weightSB,SIGNAL(editingFinished()),this,SLOT(valuesChanged())); connect(ui->switchesCB,SIGNAL(currentIndexChanged(int)),this,SLOT(valuesChanged())); - connect(ui->modeCB,SIGNAL(currentIndexChanged(int)),this,SLOT(valuesChanged())); + connect(ui->sideCB,SIGNAL(currentIndexChanged(int)),this,SLOT(valuesChanged())); connect(ui->expoGV,SIGNAL(stateChanged(int)),this,SLOT(widgetChanged())); connect(ui->weightGV,SIGNAL(stateChanged(int)),this,SLOT(widgetChanged())); for (int i=0; i<9; i++) { @@ -164,15 +179,13 @@ void ExpoDialog::valuesChanged() { QCheckBox * cb_fp[] = {ui->cb_FP0,ui->cb_FP1,ui->cb_FP2,ui->cb_FP3,ui->cb_FP4,ui->cb_FP5,ui->cb_FP6,ui->cb_FP7,ui->cb_FP8 }; - retrieveCurveReference(ui->curveTypeCB, ui->curveGVarCB, ui->curveValueCB, ui->curveValueSB, ed->curve, 0); - if (ui->weightGV->isChecked()) { ed->weight = ui->weightCB->itemData(ui->weightCB->currentIndex()).toInt(); } else { ed->weight = ui->weightSB->value(); } ed->swtch = RawSwitch(ui->switchesCB->itemData(ui->switchesCB->currentIndex()).toInt()); - ed->mode = ui->modeCB->currentIndex() + 1; + ed->mode = ui->sideCB->currentIndex() + 1; int i=0; for (i=0; iexpoName->text().toAscii().length(); i++) { ed->name[i]=ui->expoName->text().toAscii().at(i); diff --git a/companion/src/modeledit/expodialog.ui b/companion/src/modeledit/expodialog.ui index 7a5f47d64..03c45a13b 100644 --- a/companion/src/modeledit/expodialog.ui +++ b/companion/src/modeledit/expodialog.ui @@ -44,14 +44,14 @@ - + Weight - + @@ -85,14 +85,14 @@ - + Expo - + @@ -126,14 +126,14 @@ - + Flight modes - + @@ -290,14 +290,14 @@ - + Switch - + Switch used by the expo. @@ -305,14 +305,14 @@ If blank then the expo is considered to be "ON" all the time. - + Curve - + @@ -343,15 +343,15 @@ If blank then the expo is considered to be "ON" all the time. - - + + Stick Side - - + + NEG @@ -369,7 +369,7 @@ If blank then the expo is considered to be "ON" all the time. - + @@ -388,7 +388,7 @@ If blank then the expo is considered to be "ON" all the time. - + Qt::Vertical @@ -401,6 +401,71 @@ If blank then the expo is considered to be "ON" all the time. + + + + The source for the mixer + + + + + + + + No + + + + + Yes + + + + + + + + Source + + + + + + + Include Trim + + + + + + + Scale + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600; text-decoration: underline;">Delay ans Slow</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-weight:600; text-decoration: underline;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">These values control the speed and delay of the output of the mix. </p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">If Delay is not zero the actuation of the mix will be delayed by the specified amount of seconds.</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">If Slow is not zero then the speed of the mix will be set by the value specified -&gt; the value states the number of seconds it takes to transit from -100 to 100.</p></body></html> + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 1 + + + diff --git a/companion/src/modeledit/inputs.cpp b/companion/src/modeledit/inputs.cpp index 5970811b4..b529e47df 100644 --- a/companion/src/modeledit/inputs.cpp +++ b/companion/src/modeledit/inputs.cpp @@ -76,19 +76,18 @@ void InputsPanel::update() str = " "; } - switch (md->mode) { - case (1): str += " <-"; break; - case (2): str += " ->"; break; - default: str += " "; break; - }; - - str += tr("Weight(%1)").arg(getGVarString(md->weight)); - - QString curveStr = md->curve.toString(); - if (!curveStr.isEmpty()) { - str += " " + curveStr; + if (!GetEepromInterface()->getCapability(VirtualInputs)) { + switch (md->mode) { + case (1): str += " <-"; break; + case (2): str += " ->"; break; + default: str += " "; break; + }; } + str += " " + tr("Weight(%1)").arg(getGVarString(md->weight)); + + if (md->curve.value) str += " " + md->curve.toString(); + if (GetEepromInterface()->getCapability(FlightPhases)) { if(md->phases) { if (md->phases!=(unsigned int)(1<getCapability(FlightPhases))-1) { diff --git a/companion/src/modeledit/mixerdialog.cpp b/companion/src/modeledit/mixerdialog.cpp index 90d42b94f..e0bb19965 100644 --- a/companion/src/modeledit/mixerdialog.cpp +++ b/companion/src/modeledit/mixerdialog.cpp @@ -70,7 +70,7 @@ MixerDialog::MixerDialog(QWidget *parent, MixData *mixdata, int stickMode) : ui->offsetCB->hide(); } - populateCurveReference(ui->curveTypeCB, ui->curveGVarCB, ui->curveValueCB, ui->curveValueSB, md->curve, 0); + CurveGroup * curveGroup = new CurveGroup(ui->curveTypeCB, ui->curveGVarCB, ui->curveValueCB, ui->curveValueSB, md->curve); ui->MixDR_CB->setChecked(md->noExpo==0); if (!GetEepromInterface()->getCapability(MixesWithoutExpo)) { @@ -143,12 +143,6 @@ MixerDialog::MixerDialog(QWidget *parent, MixData *mixdata, int stickMode) : connect(ui->sourceCB,SIGNAL(currentIndexChanged(int)),this,SLOT(valuesChanged())); connect(ui->weightCB,SIGNAL(currentIndexChanged(int)),this,SLOT(valuesChanged())); connect(ui->offsetCB,SIGNAL(currentIndexChanged(int)),this,SLOT(valuesChanged())); - - connect(ui->curveTypeCB,SIGNAL(currentIndexChanged(int)),this,SLOT(valuesChanged())); - connect(ui->curveGVarCB,SIGNAL(stateChanged(int)),this,SLOT(valuesChanged())); - connect(ui->curveValueCB,SIGNAL(currentIndexChanged(int)),this,SLOT(valuesChanged())); - connect(ui->curveValueSB,SIGNAL(editingFinished()),this,SLOT(valuesChanged())); - connect(ui->weightSB,SIGNAL(editingFinished()),this,SLOT(valuesChanged())); connect(ui->offsetSB,SIGNAL(editingFinished()),this,SLOT(valuesChanged())); connect(ui->weightGV,SIGNAL(stateChanged(int)),this,SLOT(widgetChanged())); // TODO why the same slot? @@ -249,9 +243,6 @@ void MixerDialog::valuesChanged() } md->carryTrim = -(ui->trimCB->currentIndex()-1); md->noExpo = ui->MixDR_CB->checkState() ? 0 : 1; - - retrieveCurveReference(ui->curveTypeCB, ui->curveGVarCB, ui->curveValueCB, ui->curveValueSB, md->curve, 0); - md->swtch = RawSwitch(ui->switchesCB->itemData(ui->switchesCB->currentIndex()).toInt()); md->mixWarn = ui->warningCB->currentIndex(); md->mltpx = (MltpxValue)ui->mltpxCB->currentIndex();