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:
+83
-112
@@ -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('\'');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user