Add Companion Outputs context menu (#5665)

* Start of cut copy paste delete

* Outputs context menu continued

* Mods from testing

* Add tool tip to channel label
This commit is contained in:
Neil Horne
2018-03-25 09:44:41 +02:00
committed by Bertrand Songis
parent 6e756c434a
commit 33998c2981
4 changed files with 241 additions and 98 deletions
+40 -25
View File
@@ -87,6 +87,9 @@ GVarGroup::GVarGroup(QCheckBox * weightGV, QAbstractSpinBox * weightSB, QComboBo
dsb(dynamic_cast<QDoubleSpinBox *>(weightSB)),
weightCB(weightCB),
weight(weight),
deflt(deflt),
mini(mini),
maxi(maxi),
step(step),
lock(true)
{
@@ -102,31 +105,7 @@ GVarGroup::GVarGroup(QCheckBox * weightGV, QAbstractSpinBox * weightSB, QComboBo
}
}
int val;
if (weight>maxi || weight<mini) {
val = deflt;
weightGV->setChecked(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);
}
setWeight(weight);
connect(weightSB, SIGNAL(editingFinished()), this, SLOT(valuesChanged()));
@@ -157,6 +136,42 @@ void GVarGroup::valuesChanged()
}
}
void GVarGroup::setWeight(int val)
{
lock = true;
int tval;
if (val>maxi || val<mini) {
tval = deflt;
weightGV->setChecked(true);
weightSB->hide();
weightCB->setCurrentIndex(weightCB->findData(val));
if (weightCB->currentIndex() == -1)
weightCB->setCurrentIndex(getCurrentFirmware()->getCapability(Gvars));
weightCB->show();
}
else {
tval = val;
weightGV->setChecked(false);
weightSB->show();
weightCB->hide();
}
if (sb) {
sb->setMinimum(mini);
sb->setMaximum(maxi);
sb->setValue(tval);
}
else {
dsb->setMinimum(mini*step);
dsb->setMaximum(maxi*step);
dsb->setValue(tval*step);
}
lock = false;
}
/*
* CurveGroup
*/
+5
View File
@@ -66,6 +66,8 @@ class GVarGroup: public QObject {
public:
GVarGroup(QCheckBox * weightGV, QAbstractSpinBox * weightSB, QComboBox * weightCB, int & weight, const ModelData & model, const int deflt, const int mini, const int maxi, const double step=1.0, bool allowGVars=true);
void setWeight(int val);
signals:
void valueChanged();
@@ -80,6 +82,9 @@ class GVarGroup: public QObject {
QDoubleSpinBox *dsb;
QComboBox *weightCB;
int & weight;
int deflt;
int mini;
int maxi;
double step;
bool lock;
};
+172 -64
View File
@@ -52,14 +52,14 @@ LimitsGroup::LimitsGroup(Firmware * firmware, TableLayout * tableLayout, int row
internalStep *= 10;
}
spinbox->setSingleStep(displayStep*internalStep);
spinbox->setSingleStep(displayStep * internalStep);
spinbox->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
QHBoxLayout * horizontalLayout = new QHBoxLayout();
QCheckBox * gv = new QCheckBox(tr("GV"));
QHBoxLayout *horizontalLayout = new QHBoxLayout();
QCheckBox *gv = new QCheckBox(tr("GV"));
gv->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
horizontalLayout->addWidget(gv);
QComboBox * cb = new QComboBox();
QComboBox *cb = new QComboBox();
cb->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
horizontalLayout->addWidget(cb);
horizontalLayout->addWidget(spinbox);
@@ -73,16 +73,21 @@ LimitsGroup::~LimitsGroup()
delete gvarGroup;
}
void LimitsGroup::setValue(int val)
{
gvarGroup->setWeight(val);
}
void LimitsGroup::updateMinMax(int max)
{
if (spinbox->maximum() == 0) {
spinbox->setMinimum(-max*displayStep);
spinbox->setMinimum(-max * displayStep);
if (value < -max) {
value = -max;
}
}
if (spinbox->minimum() == 0) {
spinbox->setMaximum(max*displayStep);
spinbox->setMaximum(max * displayStep);
if (value > max) {
value = max;
}
@@ -108,7 +113,7 @@ Channels::Channels(QWidget * parent, ModelData & model, GeneralSettings & genera
headerLabels << tr("PPM Center");
if (firmware->getCapability(SYMLimits))
headerLabels << tr("Linear Subtrim");
TableLayout * tableLayout = new TableLayout(this, firmware->getCapability(LogicalSwitches), headerLabels);
TableLayout *tableLayout = new TableLayout(this, firmware->getCapability(LogicalSwitches), headerLabels);
s1.report("header");
@@ -118,75 +123,78 @@ Channels::Channels(QWidget * parent, ModelData & model, GeneralSettings & genera
// Channel label
QLabel *label = new QLabel(this);
label->setText(tr("CH%1").arg(i+1));
label->setProperty("index", i);
label->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
label->setContextMenuPolicy(Qt::CustomContextMenu);
label->setToolTip(tr("Popup menu available"));
label->setMouseTracking(true);
connect(label, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(chn_customContextMenuRequested(QPoint)));
tableLayout->addWidget(i, col++, label);
// Channel name
if (channelNameMaxLen > 0) {
QLineEdit * name = new QLineEdit(this);
name->setProperty("index", i);
name->setMaxLength(channelNameMaxLen);
name[i] = new QLineEdit(this);
name[i]->setProperty("index", i);
name[i]->setMaxLength(channelNameMaxLen);
QRegExp rx(CHAR_FOR_NAMES_REGEX);
name->setValidator(new QRegExpValidator(rx, this));
name->setText(model.limitData[i].name);
connect(name, SIGNAL(editingFinished()), this, SLOT(nameEdited()));
tableLayout->addWidget(i, col++, name);
name[i]->setValidator(new QRegExpValidator(rx, this));
connect(name[i], SIGNAL(editingFinished()), this, SLOT(nameEdited()));
tableLayout->addWidget(i, col++, name[i]);
}
// Channel offset
limitsGroups << new LimitsGroup(firmware, tableLayout, i, col++, model.limitData[i].offset, model, -1000, 1000, 0, this);
chnOffset[i] = new LimitsGroup(firmware, tableLayout, i, col++, model.limitData[i].offset, model, -1000, 1000, 0, this);
// Channel min
limitsGroups << new LimitsGroup(firmware, tableLayout, i, col++, model.limitData[i].min, model, -model.getChannelsMax()*10, 0, -1000, this);
chnMin[i] = new LimitsGroup(firmware, tableLayout, i, col++, model.limitData[i].min, model, -model.getChannelsMax() * 10, 0, -1000, this);
// Channel max
limitsGroups << new LimitsGroup(firmware, tableLayout, i, col++, model.limitData[i].max, model, 0, model.getChannelsMax()*10, 1000, this);
chnMax[i] = new LimitsGroup(firmware, tableLayout, i, col++, model.limitData[i].max, model, 0, model.getChannelsMax() * 10, 1000, this);
// Channel inversion
QComboBox * invCB = new QComboBox(this);
invCB->insertItems(0, QStringList() << tr("---") << tr("INV"));
invCB->setProperty("index", i);
invCB->setCurrentIndex((model.limitData[i].revert) ? 1 : 0);
connect(invCB, SIGNAL(currentIndexChanged(int)), this, SLOT(invEdited()));
tableLayout->addWidget(i, col++, invCB);
invCB[i] = new QComboBox(this);
invCB[i]->insertItems(0, QStringList() << tr("---") << tr("INV"));
invCB[i]->setProperty("index", i);
connect(invCB[i], SIGNAL(currentIndexChanged(int)), this, SLOT(invEdited()));
tableLayout->addWidget(i, col++, invCB[i]);
// Curve
if (IS_HORUS_OR_TARANIS(firmware->getBoard())) {
QComboBox * curveCB = new QComboBox(this);
curveCB->setProperty("index", i);
curveCB[i] = new QComboBox(this);
curveCB[i]->setProperty("index", i);
int numcurves = firmware->getCapability(NumCurves);
for (int j=-numcurves; j<=numcurves; j++) {
curveCB->addItem(CurveReference(CurveReference::CURVE_REF_CUSTOM, j).toString(&model, false), j);
curveCB[i]->addItem(CurveReference(CurveReference::CURVE_REF_CUSTOM, j).toString(&model, false), j);
}
curveCB->setCurrentIndex(model.limitData[i].curve.value+numcurves);
connect(curveCB, SIGNAL(currentIndexChanged(int)), this, SLOT(curveEdited()));
tableLayout->addWidget(i, col++, curveCB);
curveCB[i]->setCurrentIndex(model.limitData[i].curve.value+numcurves);
connect(curveCB[i], SIGNAL(currentIndexChanged(int)), this, SLOT(curveEdited()));
tableLayout->addWidget(i, col++, curveCB[i]);
}
// PPM center
int ppmCenterMax = firmware->getCapability(PPMCenter);
if (ppmCenterMax) {
QSpinBox * center = new QSpinBox(this);
center->setProperty("index", i);
center->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
center->setSuffix("us");
center->setMinimum(1500-ppmCenterMax);
center->setMaximum(1500+ppmCenterMax);
center->setValue(1500);
center->setValue(model.limitData[i].ppmCenter + 1500);
connect(center, SIGNAL(editingFinished()), this, SLOT(ppmcenterEdited()));
tableLayout->addWidget(i, col++, center);
centerSB[i] = new QSpinBox(this);
centerSB[i]->setProperty("index", i);
centerSB[i]->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
centerSB[i]->setSuffix("us");
centerSB[i]->setMinimum(1500 - ppmCenterMax);
centerSB[i]->setMaximum(1500 + ppmCenterMax);
centerSB[i]->setValue(1500);
connect(centerSB[i], SIGNAL(editingFinished()), this, SLOT(ppmcenterEdited()));
tableLayout->addWidget(i, col++, centerSB[i]);
}
// Symetrical limits
if (firmware->getCapability(SYMLimits)) {
QCheckBox * symlimits = new QCheckBox(this);
symlimits->setProperty("index", i);
symlimits->setChecked(model.limitData[i].symetrical);
connect(symlimits, SIGNAL(toggled(bool)), this, SLOT(symlimitsEdited()));
tableLayout->addWidget(i, col++, symlimits);
symlimitsChk[i] = new QCheckBox(this);
symlimitsChk[i]->setProperty("index", i);
symlimitsChk[i]->setChecked(model.limitData[i].symetrical);
connect(symlimitsChk[i], SIGNAL(toggled(bool)), this, SLOT(symlimitsEdited()));
tableLayout->addWidget(i, col++, symlimitsChk[i]);
}
}
update();
s1.report("add elements");
disableMouseScrolling();
@@ -197,17 +205,27 @@ Channels::Channels(QWidget * parent, ModelData & model, GeneralSettings & genera
Channels::~Channels()
{
foreach(LimitsGroup *group, limitsGroups) {
delete group;
// compiler warning if delete[]
for (int i=0; i<CPN_MAX_CHNOUT;i++) {
delete name[i];
delete chnOffset[i];
delete chnMin[i];
delete chnMax[i];
delete invCB[i];
delete curveCB[i];
delete centerSB[i];
delete symlimitsChk[i];
}
}
void Channels::symlimitsEdited()
{
QCheckBox * ckb = qobject_cast<QCheckBox*>(sender());
int index = ckb->property("index").toInt();
model->limitData[index].symetrical = (ckb->checkState() ? 1 : 0);
emit modified();
if (!lock) {
QCheckBox *ckb = qobject_cast<QCheckBox*>(sender());
int index = ckb->property("index").toInt();
model->limitData[index].symetrical = (ckb->checkState() ? 1 : 0);
emit modified();
}
}
void Channels::nameEdited()
@@ -224,34 +242,124 @@ void Channels::refreshExtendedLimits()
{
int channelMax = model->getChannelsMax();
foreach(LimitsGroup *group, limitsGroups) {
group->updateMinMax(10*channelMax);
for (int i=0 ; i<CPN_MAX_CHNOUT; i++) {
chnOffset[i]->updateMinMax(10 * channelMax);
chnMin[i]->updateMinMax(10 * channelMax);
chnMax[i]->updateMinMax(10 * channelMax);
}
emit modified();
}
void Channels::invEdited()
{
QComboBox *cb = qobject_cast<QComboBox*>(sender());
int index = cb->property("index").toInt();
model->limitData[index].revert = cb->currentIndex();
emit modified();
if (!lock) {
QComboBox *cb = qobject_cast<QComboBox*>(sender());
int index = cb->property("index").toInt();
model->limitData[index].revert = cb->currentIndex();
emit modified();
}
}
void Channels::curveEdited()
{
QComboBox *cb = qobject_cast<QComboBox*>(sender());
int index = cb->property("index").toInt();
model->limitData[index].curve = CurveReference(CurveReference::CURVE_REF_CUSTOM, cb->itemData(cb->currentIndex()).toInt());
emit modified();
if (!lock) {
QComboBox *cb = qobject_cast<QComboBox*>(sender());
int index = cb->property("index").toInt();
model->limitData[index].curve = CurveReference(CurveReference::CURVE_REF_CUSTOM, cb->itemData(cb->currentIndex()).toInt());
emit modified();
}
}
void Channels::ppmcenterEdited()
{
QSpinBox *sb = qobject_cast<QSpinBox*>(sender());
int index = sb->property("index").toInt();
model->limitData[index].ppmCenter = sb->value() - 1500;
if (!lock) {
QSpinBox *sb = qobject_cast<QSpinBox*>(sender());
int index = sb->property("index").toInt();
model->limitData[index].ppmCenter = sb->value() - 1500;
emit modified();
}
}
void Channels::update()
{
for (int i=0; i<firmware->getCapability(Outputs); i++) {
updateLine(i);
}
}
void Channels::updateLine(int i)
{
lock = true;
if (firmware->getCapability(ChannelsName) > 0) {
name[i]->setText(model->limitData[i].name);
}
chnOffset[i]->setValue(model->limitData[i].offset);
chnMin[i]->setValue(model->limitData[i].min);
chnMax[i]->setValue(model->limitData[i].max);
invCB[i]->setCurrentIndex((model->limitData[i].revert) ? 1 : 0);
if (IS_HORUS_OR_TARANIS(firmware->getBoard())) {
curveCB[i]->setCurrentIndex(model->limitData[i].curve.value + firmware->getCapability(NumCurves));
}
if (firmware->getCapability(PPMCenter)) {
centerSB[i]->setValue(model->limitData[i].ppmCenter + 1500);
}
if (firmware->getCapability(SYMLimits)) {
symlimitsChk[i]->setChecked(model->limitData[i].symetrical);
}
lock = false;
}
void Channels::chnPaste()
{
const QClipboard *clipboard = QApplication::clipboard();
const QMimeData *mimeData = clipboard->mimeData();
if (mimeData->hasFormat("application/x-companion-chn")) {
QByteArray chnData = mimeData->data("application/x-companion-chn");
LimitData *chn = &model->limitData[selectedChannel];
memcpy(chn, chnData.constData(), sizeof(LimitData));
updateLine(selectedChannel);
emit modified();
}
}
void Channels::chnDelete()
{
model->limitData[selectedChannel].clear();
updateLine(selectedChannel);
emit modified();
}
void Channels::chnCopy()
{
QByteArray chnData;
chnData.append((char*)&model->limitData[selectedChannel],sizeof(LimitData));
QMimeData *mimeData = new QMimeData;
mimeData->setData("application/x-companion-chn", chnData);
QApplication::clipboard()->setMimeData(mimeData,QClipboard::Clipboard);
}
void Channels::chnCut()
{
chnCopy();
chnDelete();
}
void Channels::chn_customContextMenuRequested(QPoint pos)
{
QLabel *label = (QLabel *)sender();
selectedChannel = label->property("index").toInt();
QPoint globalPos = label->mapToGlobal(pos);
const QClipboard *clipboard = QApplication::clipboard();
const QMimeData *mimeData = clipboard->mimeData();
bool hasData = mimeData->hasFormat("application/x-companion-chn");
QMenu contextMenu;
contextMenu.addAction(CompanionIcon("copy.png"), tr("&Copy"),this,SLOT(chnCopy()));
contextMenu.addAction(CompanionIcon("cut.png"), tr("&Cut"),this,SLOT(chnCut()));
contextMenu.addAction(CompanionIcon("paste.png"), tr("&Paste"),this,SLOT(chnPaste()))->setEnabled(hasData);
contextMenu.addAction(CompanionIcon("clear.png"), tr("&Delete"),this,SLOT(chnDelete()));
contextMenu.exec(globalPos);
}
+24 -9
View File
@@ -33,16 +33,17 @@ class LimitsGroup
Q_DECLARE_TR_FUNCTIONS(LimitsGroup)
public:
LimitsGroup(Firmware * firmware, TableLayout *tableLayout, int row, int col, int & value, const ModelData & model, int min, int max, int deflt, ModelPanel * panel=NULL);
LimitsGroup(Firmware * firmware, TableLayout * tableLayout, int row, int col, int & value, const ModelData & model, int min, int max, int deflt, ModelPanel * panel=NULL);
~LimitsGroup();
void setValue(int val);
void updateMinMax(int max);
protected:
Firmware * firmware;
QDoubleSpinBox * spinbox;
GVarGroup * gvarGroup;
int & value;
Firmware *firmware;
QDoubleSpinBox *spinbox;
GVarGroup *gvarGroup;
int &value;
double displayStep;
};
@@ -51,12 +52,9 @@ class Channels : public ModelPanel
Q_OBJECT
public:
Channels(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware);
Channels(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware);
~Channels();
private:
QVector<LimitsGroup *> limitsGroups;
public slots:
void refreshExtendedLimits();
@@ -66,7 +64,24 @@ class Channels : public ModelPanel
void invEdited();
void curveEdited();
void ppmcenterEdited();
void update();
void updateLine(int index);
void chnDelete();
void chnCopy();
void chnPaste();
void chnCut();
void chn_customContextMenuRequested(QPoint pos);
private:
QLineEdit *name[CPN_MAX_CHNOUT];
LimitsGroup *chnOffset[CPN_MAX_CHNOUT];
LimitsGroup *chnMin[CPN_MAX_CHNOUT];
LimitsGroup *chnMax[CPN_MAX_CHNOUT];
QComboBox *invCB[CPN_MAX_CHNOUT];
QComboBox *curveCB[CPN_MAX_CHNOUT];
QSpinBox *centerSB[CPN_MAX_CHNOUT];
QCheckBox *symlimitsChk[CPN_MAX_CHNOUT];
int selectedChannel;
};
#endif // _CHANNELS_H_