void TagConverter::applyPatternToColumns() { QList<int> columns; //QRegularExpression re = this->generatePattern2(fileToTagLineEdit); /// QString text = fileToTagLineEdit->text(); text = text.replace(':', '_'); // Remove and convert spaces according to columns for (int i = fileToTagLineEdit->tags().count() - 1; i >= 0; i--) { TagButton *tag = fileToTagLineEdit->tags().at(i); QString substitution = ':' + QString::number(tag->column()); columns.prepend(tag->column()); text.replace(tag->position(), tag->spaceCount(), substitution); } QString pattern = "^"; QString characterClass; // Depending on which detected columns, choose a sub-regex for (int i = 0; i < text.size(); i++) { QChar c = text.at(i); if (c == ':') { c = text.at(++i); switch (c.digitValue()) { case Miam::COL_Track: case Miam::COL_Year: case Miam::COL_Disc: characterClass = "[\\d]+"; // Digits break; default: characterClass = "[\\w\\W]+"; break; } pattern += "(" + characterClass + ")"; } else { pattern += QRegularExpression::escape(text.at(i)); } } pattern += "$"; QRegularExpression re(pattern, QRegularExpression::UseUnicodePropertiesOption); for (QModelIndex index : _tagEditor->selectionModel()->selectedRows()) { QString filename = index.data().toString(); filename = filename.left(filename.lastIndexOf(".")); QRegularExpressionMatch m = re.match(filename); if (!m.hasMatch()) { continue; } // The implicit capturing group with index 0 captures the result of the whole match. for (int i = 0; i < re.captureCount(); i++) { _tagEditor->updateCellData(index.row(), columns.at(i), m.captured(i + 1)); } } this->setVisible(false); _convertButton->setChecked(false); }
QString TagConverter::generatePattern(TagLineEdit *lineEdit) const { QString pattern = lineEdit->text(); pattern = pattern.replace(':', '_'); /// XXX code review needed // Proceed to substitutions in reverse order for (int i = lineEdit->tags().count() - 1; i >= 0; i--) { TagButton *tag = lineEdit->tags().at(i); QString substitution = ':' + QString::number(tag->column()); pattern.replace(tag->position(), tag->spaceCount(), substitution); } return pattern; }
/** Redefined to be able to move tag buttons. * Backspace method is not virtual in QLineEdit, therefore keyPressEvent must be intercepted and eaten. */ void TagLineEdit::backspace() { bool oneTagNeedToBeRemoved = false; TagButton *tag = nullptr; QPoint cursorCenter; cursorBackward(false); int dx = fontMetrics().width(text().at(cursorPosition())); for (TagButton *button : _tags) { cursorCenter = cursorRect().center(); // One tag button need to be removed if (button->frameGeometry().contains(cursorCenter)) { oneTagNeedToBeRemoved = true; tag = button; } // Tags need to be moved to the left if (button->x() > cursorCenter.x()) { button->move(button->x() - dx, 0); button->setPosition(cursorPosition()); } } cursorForward(false); if (oneTagNeedToBeRemoved) { for (int i = 0; i < tag->spaceCount(); i++) { LineEdit::backspace(); } dx = fontMetrics().width(" ") * tag->spaceCount(); for (TagButton *button : _tags) { if (button != tag && button->x() > cursorCenter.x()) { button->move(button->x() - dx, 0); button->setPosition(cursorPosition()); } } _tags.removeOne(tag); delete tag; /// FIXME //emit taglistHasChanged(this->toStringList()); } else { LineEdit::backspace(); } }
/** TagButton instances are converted with whitespaces in the LineEdit in order to move them. */ void TagLineEdit::insertSpaces() { TagButton *t = qobject_cast<TagButton*>(sender()); int cx = cursorRect().x(); t->setPosition(cursorPosition()); int numberOfSpace = 2; this->setText(this->text().insert(cursorPosition(), " ")); cursorForward(false, 2); while (t->frameGeometry().contains(cursorRect().center())) { this->setText(this->text().insert(cursorPosition(), " ")); cursorForward(false); numberOfSpace++; } t->setMinimumWidth(numberOfSpace * fontMetrics().width(" ") - 5); t->setSpaceCount(numberOfSpace); t->disconnect(); for (TagButton *tag : _tags) { //qDebug() << Q_FUNC_INFO << "trying to move tag"; if (t != tag && tag->frameGeometry().x() > cx) { //qDebug() << Q_FUNC_INFO << "moving tag" << tag->text(); tag->move(tag->x() + fontMetrics().width(" ") * numberOfSpace, 0); } } }
void TagLineEdit::addTag(const QString &tag, int column) { if (tag.trimmed().isEmpty()) { return; } for (TagButton *button : _tags) { if (button->text() == tag.trimmed().toLower()) { // It useless to add a tag more than once (IMHO) return; } } TagButton *t = new TagButton(tag.trimmed(), this); if (column != -1) { t->setColumn(column); } t->setMaximumHeight(this->height() - 2); // Move all tag buttons, next to the one that is about to be closed, to the left connect(t->closeButton(), &QToolButton::clicked, this, [=]() { this->closeTagButton(t); }); _tags.append(t); this->setFocus(); // Unfortunately, we have to wait that a QShowEvent is emitted to have correct size of the Widget connect(t, &TagButton::shown, this, &TagLineEdit::insertSpaces); t->move(cursorRect().right() + 1, 0); t->show(); }