fix(color): Limit label lengths, improve lbl display, prevent inv. char (#2287)

* (cpn) Add bullets & length warning

* (fw) Show labels with bullet separators

* (fw) Check all running twice. Remove from here

* (fw) Correct buffer overflow when labels too long

* (fw) Rem bullets in model label string

* (fw, cpn) Labels length

cpn,fw Limit label length
cpn Check correct model on rename length
cpn Focus issues
cpn Add rename,  move up/down.. still has an issue with selection. TODO...
cpn Switch to utf8 encoding
cpn Rename button ;)

* (cpn) Move up down working

re-Fix Checkbox, partially isn't what I thought (not greyed)

* (fw) Add CSV string funcs

Limit length of model edit shorter in portrait mode

* (cpn) Correct Label option showing on B&W

* (fw) Radio filename set but no file exists don't create

* (cpn) Simplify wording

* (fw) Correct debug values

* (fw) Reduce truncation length

* (both) Don't allow special chars in label name

(cpn) Prevent move when at top and bottom
(fw) Remove multiple label length defines
(fw) Shorten truncate length even more

* (fw) Close model_select on new model
This commit is contained in:
Cliff
2022-09-18 10:47:21 +10:00
committed by GitHub
parent c3660ab931
commit 333c2828ea
16 changed files with 405 additions and 248 deletions
+1
View File
@@ -46,6 +46,7 @@ class AbstractStaticItemModel;
constexpr char AIM_MODELDATA_TRAINERMODE[] {"modeldata.trainermode"};
constexpr char AIM_MODELDATA_FUNCSWITCHCONFIG[] {"modeldata.funcswitchconfig"};
constexpr char AIM_MODELDATA_FUNCSWITCHSTART[] {"modeldata.funcswitchstart"};
constexpr int LABEL_LENGTH=16;
#define CHAR_FOR_NAMES " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-."
#define CHAR_FOR_NAMES_REGEX "[ A-Za-z0-9_.-,]*"
+100 -46
View File
@@ -106,33 +106,43 @@ void RadioData::convert(RadioDataConversionState & cstate)
void RadioData::addLabel(QString label)
{
label.replace("/c",",");
label.replace("//","/");
if(labels.indexOf(label) == -1)
label = unEscapeCSV(label);
// Truncate possible UTF-8 to 16char maximum
QByteArray output = label.toUtf8();
if (output.size() > LABEL_LENGTH) {
int truncateAt = 0;
for (int i = LABEL_LENGTH; i > 0; i--) {
if ((output[i] & 0xC0) != 0x80) {
truncateAt = i;
break;
}
}
output.truncate(truncateAt);
}
label = QString(output);
if (labels.indexOf(label) == -1)
labels.append(label);
}
bool RadioData::deleteLabel(QString label)
{
bool deleted = false;
QString csvLabel = label;
csvLabel.replace("/","//");
csvLabel.replace(",","/c");
// Remove labels in the models
for(auto& model : models) {
QStringList modelLabels = QString(model.labels).split(',',QString::SkipEmptyParts);
if(modelLabels.indexOf(csvLabel) >= 0)
QStringList modelLabels = fromCSV(QString::fromUtf8(model.labels));
if (modelLabels.indexOf(label) >= 0) {
deleted = true;
modelLabels.removeAll(csvLabel);
strcpy(model.labels, QString(modelLabels.join(',')).toLocal8Bit().data());
modelLabels.removeAll(label);
}
strcpy(model.labels, toCSV(modelLabels).toUtf8().data());
}
// Remove the label from the global list
labels.removeAll(label);
// If no labels remain, add a Favorites one
if(!labels.size()) {
if (!labels.size()) {
addLabel(tr("Favorites"));
}
return deleted;
@@ -140,42 +150,46 @@ bool RadioData::deleteLabel(QString label)
bool RadioData::deleteLabel(int index)
{
if(index >= labels.size()) return false;
if (index >= labels.size()) return false;
QString modelLabel = labels.at(index);
return deleteLabel(modelLabel);
}
bool RadioData::renameLabel(QString from, QString to)
{
bool success = true;
int lengthdiff = to.size() - from.size();
QString csvFrom = from;
QString csvTo = to;
csvFrom.replace("/","//");
csvFrom.replace(",","/c");
csvTo.replace("/","//");
csvTo.replace(",","/c");
bool success = true;
QString csvFrom = escapeCSV(from);
QString csvTo = escapeCSV(to);
int lengthdiff = csvTo.size() - csvFrom.size();
// Check that rename is possible, not too long
// Check that rename is possible (Rename won't cause too long of a string)
for(auto& model : models) {
if((int)strlen(model.labels) + lengthdiff > (int)sizeof(model.labels) - 1) {
success = false;
if (RadioData::fromCSV(model.labels).indexOf(from) != -1) {
if ((int)strlen(model.labels) + lengthdiff > (int)sizeof(model.labels) - 1) {
success = false;
throw std::length_error(model.name);
break;
}
}
}
if(success) {
if (success) {
for(auto& model : models) {
QStringList modelLabels = QString(model.labels).split(',',QString::SkipEmptyParts);
int ind = modelLabels.indexOf(csvFrom);
if(ind != -1) {
if (ind != -1) {
modelLabels.replace(ind, csvTo);
QString outputcsv = QString(modelLabels.join(','));
if(outputcsv.toLocal8Bit().size() < (int)sizeof(model.labels));
strcpy(model.labels, outputcsv.toLocal8Bit().data());
if (outputcsv.toUtf8().size() < (int)sizeof(model.labels)) {
strcpy(model.labels, outputcsv.toUtf8().data());
} else { // Shouldn't ever get here, from check above
success = false;
throw std::length_error(model.name);
break;
}
}
}
int ind = labels.indexOf(from);
if(ind != -1) {
if (ind != -1) {
labels.replace(ind, to);
}
}
@@ -184,42 +198,51 @@ bool RadioData::renameLabel(QString from, QString to)
bool RadioData::renameLabel(int index, QString to)
{
if(index >= labels.size()) return false;
if (index >= labels.size()) return false;
QString from = labels.at(index);
return renameLabel(from, to);
}
void RadioData::swapLabel(int indFrom, int indTo)
{
if(abs(indFrom - indTo) > 1 ||
indFrom >= labels.size() ||
indTo >= labels.size() ||
indFrom < 0 ||
indTo < 0)
return;
QString tmplbl = labels.at(indFrom);
labels.replace(indFrom, labels.at(indTo));
labels.replace(indTo, tmplbl);
}
bool RadioData::addLabelToModel(int index, QString label)
{
if(index >= models.size()) return false;
label.replace("/","//");
label.replace(",","/c");
if (index >= models.size()) return false;
label = escapeCSV(label);
char *modelLabelCsv = models[index].labels;
// Make sure it will fit
if(strlen(modelLabelCsv) + label.size() + 1 < sizeof(models[index].labels)-1) {
QStringList modelLabels = QString(modelLabelCsv).split(',',QString::SkipEmptyParts);
if(modelLabels.indexOf(label) == -1) {
if (strlen(modelLabelCsv) + label.size() + 1 < sizeof(models[index].labels)-1) {
QStringList modelLabels = QString::fromUtf8(modelLabelCsv).split(',',QString::SkipEmptyParts);
if (modelLabels.indexOf(label) == -1) {
modelLabels.append(label);
strcpy(models[index].labels, QString(modelLabels.join(',')).toLocal8Bit().data());
strcpy(models[index].labels, QString(modelLabels.join(',')).toUtf8().data());
return true;
}
}
throw std::length_error(models[index].name);
return false;
}
bool RadioData::removeLabelFromModel(int index, QString label)
{
if(index >= models.size()) return false;
label.replace("/","//");
label.replace(",","/c");
if (index >= models.size()) return false;
char *modelLabelCsv = models[index].labels;
QStringList modelLabels = QString(modelLabelCsv).split(',',QString::SkipEmptyParts);
if(modelLabels.indexOf(label) >= 0) {
modelLabels.removeAll(label);
strcpy(models[index].labels, QString(modelLabels.join(',')).toLocal8Bit().data());
QStringList lbls = fromCSV(QString::fromUtf8(models[index].labels));
if (lbls.indexOf(label) >= 0) {
lbls.removeAll(label);
strcpy(models[index].labels, toCSV(lbls).toUtf8().data());
return true;
}
return false;
@@ -234,3 +257,34 @@ void RadioData::addLabelsFromModels()
}
}
}
QStringList RadioData::fromCSV(const QString &csv)
{
QStringList lbls = QString(csv).split(',',QString::SkipEmptyParts);
for(QString &label: lbls) {
label = unEscapeCSV(label);
}
return lbls;
}
QString RadioData::toCSV(QStringList lbls)
{
for(QString &label: lbls) {
label = escapeCSV(label);
}
return lbls.join(',');
}
QString RadioData::escapeCSV(QString str)
{
str.replace("/","//");
str.replace(",","/c");
return str;
}
QString RadioData::unEscapeCSV(QString str)
{
str.replace("/c",",");
str.replace("//","/");
return str;
}
+7
View File
@@ -27,10 +27,16 @@ class RadioData {
bool deleteLabel(int index);
bool renameLabel(QString from, QString to);
bool renameLabel(int index, QString to);
void swapLabel(int indFrom, int indTo);
bool addLabelToModel(int index, QString label);
bool removeLabelFromModel(int index, QString label);
void addLabelsFromModels();
static QStringList fromCSV(const QString &csv);
static QString toCSV(QStringList lbls);
static QString escapeCSV(QString str);
static QString unEscapeCSV(QString str);
void setCurrentModel(unsigned int index);
void fixModelFilenames();
QString getNextModelFilename();
@@ -41,4 +47,5 @@ class RadioData {
protected:
void fixModelFilename(unsigned int index);
};
+83 -112
View File
@@ -22,12 +22,12 @@ Qt::ItemFlags LabelsModel::flags(const QModelIndex &index) const
{
Qt::ItemFlags flags = Qt::ItemIsEnabled;
if(index.column() == 0) {
if (index.column() == 0) {
flags |= Qt::ItemIsUserCheckable;
flags |= Qt::ItemIsSelectable;
flags |= Qt::ItemIsDropEnabled;
flags |= Qt::ItemIsEditable;
if(index.isValid())
if (index.isValid())
flags |= Qt::ItemIsDragEnabled;
}
return flags;
@@ -35,33 +35,48 @@ Qt::ItemFlags LabelsModel::flags(const QModelIndex &index) const
bool LabelsModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if(!index.isValid() || index.column() != 0 ||
if (!index.isValid() || index.column() != 0 ||
index.row() >= radioData->labels.size())
return false;
if(role == Qt::CheckStateRole) {
if(value==Qt::Unchecked && selectedModel != -1) {
if(radioData->removeLabelFromModel(selectedModel, radioData->labels.at(index.row())))
if (role == Qt::CheckStateRole) {
if (value==Qt::Unchecked && selectedModel != -1) {
if (radioData->removeLabelFromModel(selectedModel, radioData->labels.at(index.row())))
emit modelChanged(selectedModel);
} else {
if(radioData->addLabelToModel(selectedModel, radioData->labels.at(index.row())))
try{
if (radioData->addLabelToModel(selectedModel, radioData->labels.at(index.row())))
emit modelChanged(selectedModel);
} catch(const std::length_error& le) {
emit labelsFault(tr("Unable to add label \"%1\" to model \"%2\" not enough room")\
.arg(radioData->labels.at(index.row())).arg(le.what()));
}
}
emit dataChanged(this->index(index.row(), 0),
this->index(index.row(), 0));
return true;
} else if(role == Qt::EditRole) {
} else if (role == Qt::EditRole) {
QString replFrom = labels[index.row()].label;
QString replTo = value.toString();
if(radioData->labels.indexOf(replTo) == -1) { // Don't allow duplicates
bool modelsChanged = radioData->renameLabel(replFrom,replTo);
if (replFrom == replTo) // User exits edit without changing
return true;
if (radioData->labels.indexOf(replTo) == -1) { // Don't allow duplicates
bool modelsChanged = false;
try{
modelsChanged = radioData->renameLabel(replFrom,replTo);
} catch(const std::length_error& le) {
emit labelsFault(tr("Unable to rename \"%1\" to \"%2\" not enough room in model %3")\
.arg(replFrom).arg(replTo).arg(le.what()));
return false;
}
labels[index.row()].label = replTo;
emit dataChanged(this->index(index.row(), 0),
this->index(index.row(), 0));
if(selectedModel != -1 && modelsChanged)
if (selectedModel != -1 && modelsChanged)
emit modelChanged(selectedModel);
} else {
emit renameFault(tr("Unable to rename \"%1\" to \"%2\" the label already exists").arg(replFrom).arg(replTo));
emit labelsFault(tr("Unable to rename \"%1\" to \"%2\" the label already exists")\
.arg(replFrom).arg(replTo));
}
return true;
}
@@ -70,22 +85,21 @@ bool LabelsModel::setData(const QModelIndex &index, const QVariant &value, int r
QVariant LabelsModel::data(const QModelIndex &index, int role) const
{
if(index.row() >= labels.size() || !index.isValid() )
if (index.row() >= labels.size() || !index.isValid() )
return QVariant();
QString label = radioData->labels.at(index.row());
if(role == Qt::DisplayRole || role == Qt::EditRole) {
if(index.column() == 0) {
if (role == Qt::DisplayRole || role == Qt::EditRole) {
if (index.column() == 0) {
return labels.at(index.row()).label;
//return label;
}
} else if (role == Qt::CheckStateRole) {
if(index.column() == 0 && selectedModel >= 0 &&
if (index.column() == 0 && selectedModel >= 0 &&
selectedModel < (int)radioData->models.size()) {
QStringList modelLabels = QString(radioData->models.at(selectedModel).labels).split(',',QString::SkipEmptyParts);
label.replace("/","//");
label.replace(",","/c");
label = RadioData::escapeCSV(label);
return modelLabels.indexOf(label)==-1?Qt::Unchecked:Qt::Checked;
} else if (index.column() == 0 && selectedModel == -1) {
return Qt::Unchecked;
@@ -98,7 +112,7 @@ QModelIndex LabelsModel::index(int row, int column, const QModelIndex &parent) c
{
Q_UNUSED(parent)
if(row < labels.size())
if (row < labels.size())
return createIndex(row,0);
return QModelIndex();
@@ -123,94 +137,13 @@ int LabelsModel::columnCount(const QModelIndex &parent) const
QVariant LabelsModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if(role != Qt::DisplayRole ||
if (role != Qt::DisplayRole ||
orientation != Qt::Horizontal ||
section != 0)
return QVariant();
return tr("Labels");
}
Qt::DropActions LabelsModel::supportedDropActions() const
{
return Qt::MoveAction;
}
QStringList LabelsModel::mimeTypes() const
{
QStringList types;
types << "application/edglbl.text.list";
return types;
}
QMimeData *LabelsModel::mimeData(const QModelIndexList &indexes) const
{
QMimeData *mimeData = new QMimeData;
QByteArray encodedData;
QDataStream stream(&encodedData, QIODevice::WriteOnly);
for (const QModelIndex &index : indexes) {
if (index.isValid()) {
QString text = data(index, Qt::DisplayRole).toString();
stream << text;
}
}
mimeData->setData("application/edglbl.text.list", encodedData);
return mimeData;
}
bool LabelsModel::canDropMimeData(const QMimeData *data, Qt::DropAction action,
int row, int column, const QModelIndex &parent) const
{
Q_UNUSED(action);
Q_UNUSED(row);
Q_UNUSED(parent);
if (!data->hasFormat("application/edglbl.text.list"))
return false;
if (column > 0)
return false;
return true;
}
bool LabelsModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
{
// TODO: This needs to be completed
if (!canDropMimeData(data, action, row, column, parent))
return false;
if(row < 0) return false;
if (action == Qt::IgnoreAction)
return true;
else if (action != Qt::MoveAction)
return false;
QByteArray encodedData = data->data("application/edglbl.text.list");
QDataStream stream(&encodedData, QIODevice::ReadOnly);
QStringList newItems;
int rows = 0;
while (!stream.atEnd()) {
QString text;
stream >> text;
newItems << text;
++rows;
}
/*insertRows(row, rows, QModelIndex());
for (const QString &text : qAsConst(newItems))
{
QModelIndex idx = index(row, 0, QModelIndex());
row++;
}*/
return true;
}
bool LabelsModel::insertRows(int row, int count, const QModelIndex &parent)
{
if (parent.isValid())
@@ -218,16 +151,16 @@ bool LabelsModel::insertRows(int row, int count, const QModelIndex &parent)
// Find a New Number
for (int i = 0; i < count; i++) {
int newno=0;
QString newstr;
int newNo=0;
QString newStr;
do {
newstr = QString(tr("New%1").arg(newno));
if(newno == 0)
newstr = QString(tr("New"));
newno++;
} while(radioData->labels.indexOf(newstr) >= 0);
newStr = QString(tr("New%1").arg(newNo));
if (newNo == 0)
newStr = QString(tr("New"));
newNo++;
} while(radioData->labels.indexOf(newStr) >= 0);
// Add it to radioData
radioData->labels.insert(row+i, newstr);
radioData->labels.insert(row+i, newStr);
}
buildLabelsList();
return true;
@@ -240,12 +173,12 @@ bool LabelsModel::removeRows(int row, int count, const QModelIndex &parent)
bool deleted=false;
beginRemoveRows(parent, row, row + count - 1);
for (int i = 0; i != count; ++i)
if(radioData->deleteLabel(row+i)) {
if (radioData->deleteLabel(row+i)) {
deleted = true;
}
endRemoveRows();
// Refresh all
if(deleted)
if (deleted)
emit modelChanged(-1);
buildLabelsList();
return true;
@@ -273,7 +206,7 @@ void LabelsModel::modelsSelectionChanged()
QModelIndex index = modelsSelection->currentIndex();
if (index.isValid()) {
int mi = modelsSelection->currentIndex().row();
if(mi < (int)radioData->models.size()) {
if (mi < (int)radioData->models.size()) {
selectedModel = mi;
buildLabelsList();
}
@@ -281,3 +214,41 @@ void LabelsModel::modelsSelectionChanged()
else
selectedModel = -1;
}
QValidator::State LabelValidator::validate(QString &label, int &pos) const
{
Q_UNUSED(pos)
QString lbl = RadioData::escapeCSV(label);
if (lbl.toUtf8().size() > LABEL_LENGTH)
return QValidator::Invalid;
if(lbl.contains('\\') || // TODO: Fix me to allow all, requires FW changes
lbl.contains('\"') ||
lbl.contains(':') ||
lbl.contains('-') ||
lbl.contains('\''))
return QValidator::Invalid;
if(lbl.size() == 0)
return QValidator::Intermediate;
return QValidator::Acceptable;
}
void LabelValidator::fixup(QString &input) const
{
QByteArray output = input.toUtf8();
if (output.size() > LABEL_LENGTH) {
int truncateAt = 0;
for (int i = LABEL_LENGTH; i > 0; i--) {
if ((output[i] & 0xC0) != 0x80) {
truncateAt = i;
break;
}
}
output.truncate(truncateAt);
}
input = QString(output);
input.remove('\\'); // TODO: Fix me to allow all, requires FW changes
input.remove('\"');
input.remove(':');
input.remove('-');
input.remove('\'');
}
+28 -6
View File
@@ -4,6 +4,9 @@
#include <QList>
#include <QAbstractItemModel>
#include <QItemSelectionModel>
#include <QValidator>
#include <QLineEdit>
#include <QStyledItemDelegate>
#include "radiodata.h"
@@ -29,11 +32,6 @@ public:
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
Qt::DropActions supportedDropActions() const override;
QStringList mimeTypes() const override;
QMimeData *mimeData(const QModelIndexList &indexes) const override;
bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const override;
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override;
bool insertRows(int row, int count, const QModelIndex &parent) override;
bool removeRows(int row, int count, const QModelIndex &parent) override;
@@ -45,7 +43,7 @@ private slots:
signals:
void modelChanged(int index);
void renameFault(QString msg);
void labelsFault(QString msg);
private:
QItemSelectionModel *modelsSelection;
@@ -54,3 +52,27 @@ private:
QList<QModelIndex> modelIndices;
QList<LabelItem> labels;
};
class LabelValidator : public QValidator
{
Q_OBJECT
public:
QValidator::State validate(QString &label, int &pos) const;
void fixup(QString &input) const;
};
class LabelEditTextDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
LabelEditTextDelegate(QObject *parent = nullptr) : QStyledItemDelegate(parent) {}
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
QLineEdit *editor = new QLineEdit(parent);
editor->setValidator(new LabelValidator);
return editor;
}
};
+59 -12
View File
@@ -221,7 +221,10 @@ void MdiChild::setupNavigation()
addAct(ACT_MDL_WIZ, "wizard.png", SLOT(wizardEdit()), tr("Alt+W"));
addAct(ACT_LBL_ADD, "add.png", SLOT(labelAdd()), tr("Alt-L"));
addAct(ACT_LBL_DEL, "clear.png", SLOT(labelDelete()), tr("Alt-L"));
addAct(ACT_LBL_DEL, "clear.png", SLOT(labelDelete()), tr("Alt-L"));
addAct(ACT_LBL_REN, "edit.png", SLOT(labelRename()), tr("Alt-R"));
addAct(ACT_LBL_MVU, "moveup.png", SLOT(labelMoveUp()), tr("Alt-+"));
addAct(ACT_LBL_MVD, "movedown.png", SLOT(labelMoveDown()), tr("Alt--"));
addAct(ACT_MDL_DFT, "currentmodel.png", SLOT(setDefault()), tr("Alt+U"));
addAct(ACT_MDL_PRT, "print.png", SLOT(print()), QKeySequence::Print);
@@ -247,7 +250,7 @@ void MdiChild::setupNavigation()
// Add labels Label to bottom layout
if(lblLabels)
lblLabels->deleteLater();
lblLabels = new QLabel(tr("Labels"));
lblLabels = new QLabel(tr("Labels Management"));
lblLabels->setStyleSheet("font-weight: bold");
ui->bottomLayout->addWidget(lblLabels);
@@ -261,6 +264,9 @@ void MdiChild::setupNavigation()
labelsToolbar->setStyleSheet(tbCss);
labelsToolbar->addAction(getAction(ACT_LBL_ADD));
labelsToolbar->addAction(getAction(ACT_LBL_DEL));
labelsToolbar->addAction(getAction(ACT_LBL_REN));
labelsToolbar->addAction(getAction(ACT_LBL_MVU));
labelsToolbar->addAction(getAction(ACT_LBL_MVD));
ui->bottomLayout->addWidget(labelsToolbar);
if (radioToolbar)
@@ -353,8 +359,11 @@ void MdiChild::retranslateUi()
action[ACT_ITM_EDT]->setText(tr("Edit Model"));
action[ACT_ITM_DEL]->setText(tr("Delete"));
action[ACT_LBL_ADD]->setText(tr("Add Label"));
action[ACT_LBL_DEL]->setText(tr("Delete Label"));
action[ACT_LBL_ADD]->setText(tr("Add"));
action[ACT_LBL_DEL]->setText(tr("Delete"));
action[ACT_LBL_REN]->setText(tr("Rename"));
action[ACT_LBL_MVU]->setText(tr("Move Up"));
action[ACT_LBL_MVD]->setText(tr("Move Down"));
action[ACT_MDL_ADD]->setText(tr("Add Model"));
action[ACT_MDL_ADD]->setIconText(tr("Model"));
@@ -369,6 +378,7 @@ void MdiChild::retranslateUi()
radioToolbar->setWindowTitle(tr("Show Radio Actions Toolbar"));
modelsToolbar->setWindowTitle(tr("Show Model Actions Toolbar"));
labelsToolbar->setWindowTitle(tr("Show Labels Actions Toolbar"));
}
QList<QAction *> MdiChild::getGeneralActions()
@@ -416,6 +426,9 @@ QList<QAction *> MdiChild::getLabelsActions()
QList<QAction *> actGrp;
actGrp.append(getAction(ACT_LBL_ADD));
actGrp.append(getAction(ACT_LBL_DEL));
actGrp.append(getAction(ACT_LBL_REN));
actGrp.append(getAction(ACT_LBL_MVU));
actGrp.append(getAction(ACT_LBL_MVD));
return actGrp;
}
@@ -457,6 +470,9 @@ void MdiChild::showLabelsContextMenu(const QPoint &pos)
contextMenu.addAction(action[ACT_LBL_ADD]);
contextMenu.addAction(action[ACT_LBL_DEL]);
contextMenu.addAction(action[ACT_LBL_REN]);
contextMenu.addAction(action[ACT_LBL_MVU]);
contextMenu.addAction(action[ACT_LBL_MVD]);
if (!contextMenu.isEmpty())
contextMenu.exec(ui->lstLabels->mapToGlobal(pos));
@@ -467,6 +483,8 @@ void MdiChild::showContextMenu(const QPoint & pos)
QMenu contextMenu;
contextMenu.addAction(modelsToolbar->toggleViewAction());
contextMenu.addAction(radioToolbar->toggleViewAction());
if(firmware->getCapability(Capability::HasModelLabels))
contextMenu.addAction(labelsToolbar->toggleViewAction());
if (!contextMenu.isEmpty())
contextMenu.exec(mapToGlobal(pos));
}
@@ -509,15 +527,11 @@ void MdiChild::initModelsList()
labelsListModel = new LabelsModel(ui->modelsList->selectionModel(),
&radioData, this);
connect(labelsListModel, &LabelsModel::modelChanged, this, &MdiChild::modelLabelsChanged);
connect(labelsListModel, &LabelsModel::renameFault, this, &MdiChild::labelRenameFault);
connect(labelsListModel, &LabelsModel::labelsFault, this, &MdiChild::labelsFault);
ui->lstLabels->setModel(labelsListModel);
ui->lstLabels->setSelectionMode(QAbstractItemView::SingleSelection);
ui->lstLabels->setDragEnabled(true);
ui->lstLabels->setAcceptDrops(true);
ui->lstLabels->setDropIndicatorShown(true);
ui->lstLabels->setDragDropOverwriteMode(false);
ui->lstLabels->setDragDropMode(QAbstractItemView::InternalMove);
ui->lstLabels->setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::EditKeyPressed);
ui->lstLabels->setItemDelegate(new LabelEditTextDelegate);
ui->modelsList->setIndentation(0);
@@ -1634,23 +1648,56 @@ void MdiChild::modelExport()
void MdiChild::labelAdd()
{
labelsListModel->insertRow(0);
QModelIndex newind = labelsListModel->index(0,0);
ui->lstLabels->setCurrentIndex(newind);
ui->lstLabels->edit(newind);
setWindowModified(true);
}
void MdiChild::labelDelete()
{
int row = ui->lstLabels->selectionModel()->currentIndex().row();
if(row < 0) return;
labelsListModel->removeRow(row);
setWindowModified(true);
}
void MdiChild::modelLabelsChanged()
void MdiChild::labelRename()
{
int row = ui->lstLabels->selectionModel()->currentIndex().row();
if(row < 0) return;
QModelIndex newind = labelsListModel->index(row,0);
ui->lstLabels->setCurrentIndex(newind);
ui->lstLabels->edit(newind);
}
void MdiChild::labelMoveUp()
{
int row = ui->lstLabels->selectionModel()->currentIndex().row();
if(row == 0) return;
radioData.swapLabel(row, row-1);
labelsListModel->buildLabelsList();
ui->lstLabels->selectionModel()->setCurrentIndex(labelsListModel->index(row-1,0), QItemSelectionModel::ClearAndSelect);
}
void MdiChild::labelMoveDown()
{
int row = ui->lstLabels->selectionModel()->currentIndex().row();
if(row == labelsListModel->rowCount() -1) return;
radioData.swapLabel(row, row+1);
labelsListModel->buildLabelsList();
ui->lstLabels->selectionModel()->setCurrentIndex(labelsListModel->index(row+1,0), QItemSelectionModel::ClearAndSelect);
}
void MdiChild::modelLabelsChanged(int row)
{
setWindowModified(true);
refresh();
ui->modelsList->selectionModel()->select(modelsListModel->index(row,0), QItemSelectionModel::ClearAndSelect |
QItemSelectionModel::Rows);
}
void MdiChild::labelRenameFault(QString msg)
void MdiChild::labelsFault(QString msg)
{
QMessageBox::warning(this, CPN_STR_TTL_WARNING, msg);
}
+8 -2
View File
@@ -56,6 +56,9 @@ class MdiChild : public QWidget
ACT_ITM_DEL, // delete model or cat
ACT_LBL_ADD,
ACT_LBL_DEL,
ACT_LBL_MVU, // Move up
ACT_LBL_MVD, // Move down
ACT_LBL_REN, // Move down
ACT_MDL_ADD, // model actions...
ACT_MDL_CPY,
ACT_MDL_CUT,
@@ -140,8 +143,11 @@ class MdiChild : public QWidget
void modelExport();
void labelAdd();
void labelDelete();
void modelLabelsChanged();
void labelRenameFault(QString msg);
void labelRename();
void labelMoveUp();
void labelMoveDown();
void modelLabelsChanged(int row);
void labelsFault(QString msg);
void wizardEdit();
void modelDuplicate();
+2 -1
View File
@@ -682,7 +682,8 @@ void ModelsListModel::refresh()
current->setData(currentColumn++, rxs);
}
if (hasLabels) {
current->setData(currentColumn++, QString(model.labels));
QStringList labels = RadioData::fromCSV(QString::fromUtf8(model.labels));
current->setData(currentColumn++, labels.join(QChar(0x2022)));
}
}
}