#ifndef SINGLERELAY_H #define SINGLERELAY_H #include #include #include #include #include "data_config.h" #include "config_mgr.h" #include "singlerelay_data.h" namespace Ui { class SingleRelay; } class DropTextEdit : public QTextEdit { Q_OBJECT public: DropTextEdit(QWidget *parent = nullptr) : QTextEdit(parent) { setAcceptDrops(true); } public slots: void removeLastElement() { QString html = this->toHtml(); // 匹配 元素 QRegularExpression spanRe(R"(]*>[^<]*)"); QRegularExpressionMatchIterator spanIt = spanRe.globalMatch(html); // 匹配符号元素(注意符号两边可能有空格) QRegularExpression symbolRe(R"((\s?[+*()]\s?))"); QRegularExpressionMatchIterator symbolIt = symbolRe.globalMatch(html); // 保存所有匹配结果:位置 + 匹配内容 struct Match { int start; int length; }; QList matches; while (spanIt.hasNext()) { auto m = spanIt.next(); matches.append({ m.capturedStart(), m.capturedLength() }); } while (symbolIt.hasNext()) { auto m = symbolIt.next(); matches.append({ m.capturedStart(), m.capturedLength() }); } if (matches.isEmpty()) return; // 找出最后出现的元素 std::sort(matches.begin(), matches.end(), [](const Match &a, const Match &b) { return a.start < b.start; }); // 删除最后一个匹配 Match last = matches.last(); html.remove(last.start, last.length); this->setHtml(html); // 保持光标在末尾 QTextCursor cursor = this->textCursor(); cursor.movePosition(QTextCursor::End); this->setTextCursor(cursor); } protected: void dragEnterEvent(QDragEnterEvent *event) override { if (event->mimeData()->hasFormat("application/x-custom")) { event->acceptProposedAction(); } else { event->ignore(); } } void dragMoveEvent(QDragMoveEvent *event) override { if (event->mimeData()->hasFormat("application/x-custom")) { event->acceptProposedAction(); } else { event->ignore(); } } void dropEvent(QDropEvent *event) override { if (!this->toPlainText().isEmpty()) { event->ignore(); return; } if (event->mimeData()->hasFormat("application/x-custom")) { QByteArray data = event->mimeData()->data("application/x-custom"); QString text = QString::fromUtf8(data); QTextCursor cursor = this->textCursor(); this->setTextCursor(cursor); QString html = QString( "%1" ).arg(text); cursor.insertHtml(html); event->acceptProposedAction(); } else { event->ignore(); } } }; class SingleRelay : public QDialog { Q_OBJECT public: explicit SingleRelay(int slot,int cardtype,QWidget *parent = nullptr); ~SingleRelay(); int slot_no; CardType car_type; private slots: void keyPressEvent(QKeyEvent *event); void on_pushButton_cancel_clicked(); void OnButtonGroup(QAbstractButton *); void on_pushButton_enter_clicked(); void on_pushButton_backspace_clicked(); void on_pushButton_clr_clicked(); void on_pushButton_confirm_clicked(); void onComboBoxIndexChanged(int index); private: Ui::SingleRelay *ui; QButtonGroup * btnGroup_slot = nullptr; DraggableListWidget *list_widget_available = nullptr; DropTextEdit *textEdit_relay = nullptr; std::shared_ptr single_relay_nok_data = nullptr; int current_index; void Init(); }; #endif // SINGLERELAY_H