#include "veditsnippetdialog.h" #include #include "utils/vutils.h" #include "vmetawordlineedit.h" #include "vconfigmanager.h" #include "utils/vmetawordmanager.h" extern VMetaWordManager *g_mwMgr; extern VConfigManager *g_config; VEditSnippetDialog::VEditSnippetDialog(const QString &p_title, const QString &p_info, const QVector &p_snippets, const VSnippet &p_snippet, QWidget *p_parent) : QDialog(p_parent), m_snippets(p_snippets), m_snippet(p_snippet) { setupUI(p_title, p_info); handleInputChanged(); } void VEditSnippetDialog::setupUI(const QString &p_title, const QString &p_info) { QLabel *infoLabel = NULL; if (!p_info.isEmpty()) { infoLabel = new QLabel(p_info); infoLabel->setWordWrap(true); } // Name. m_nameEdit = new VMetaWordLineEdit(m_snippet.getName()); QValidator *validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp), m_nameEdit); m_nameEdit->setValidator(validator); // Type. m_typeCB = VUtils::getComboBox(); for (int i = 0; i < VSnippet::Type::Invalid; ++i) { m_typeCB->addItem(VSnippet::typeStr(static_cast(i)), i); } int typeIdx = m_typeCB->findData((int)m_snippet.getType()); Q_ASSERT(typeIdx > -1); m_typeCB->setCurrentIndex(typeIdx); // Shortcut. m_shortcutCB = VUtils::getComboBox(); m_shortcutCB->addItem(tr("None"), QChar()); auto shortcuts = getAvailableShortcuts(); for (auto it : shortcuts) { m_shortcutCB->addItem(it, it); } QChar sh = m_snippet.getShortcut(); if (sh.isNull()) { m_shortcutCB->setCurrentIndex(0); } else { int shortcutIdx = m_shortcutCB->findData(sh); m_shortcutCB->setCurrentIndex(shortcutIdx < 0 ? 0 : shortcutIdx); } // Cursor mark. m_cursorMarkEdit = new QLineEdit(m_snippet.getCursorMark()); m_cursorMarkEdit->setToolTip(tr("String in the content to mark the cursor position")); // Selection mark. m_selectionMarkEdit = new QLineEdit(m_snippet.getSelectionMark()); m_selectionMarkEdit->setToolTip(tr("String in the content to be replaced with selected text")); // Auto Indent. m_autoIndentCB = new QCheckBox(tr("Auto indent"), this); m_autoIndentCB->setToolTip(tr("Auto indent the content according to the first line")); m_autoIndentCB->setChecked(m_snippet.getAutoIndent()); // Content. m_contentEdit = new QTextEdit(); m_contentEdit->setProperty("LineEdit", true); setContentEditByType(); QFormLayout *topLayout = new QFormLayout(); topLayout->addRow(tr("Snippet &name:"), m_nameEdit); topLayout->addRow(tr("Snippet &type:"), m_typeCB); topLayout->addRow(tr("Shortc&ut:"), m_shortcutCB); topLayout->addRow(tr("Cursor &mark:"), m_cursorMarkEdit); topLayout->addRow(tr("&Selection mark:"), m_selectionMarkEdit); topLayout->addWidget(m_autoIndentCB); topLayout->addRow(tr("&Content:"), m_contentEdit); m_warnLabel = new QLabel(); m_warnLabel->setWordWrap(true); m_warnLabel->hide(); // Ok is the default button. m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); connect(m_btnBox, &QDialogButtonBox::accepted, this, &QDialog::accept); connect(m_btnBox, &QDialogButtonBox::rejected, this, &QDialog::reject); QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); okBtn->setProperty("SpecialBtn", true); m_nameEdit->setMinimumWidth(okBtn->sizeHint().width() * 3); QVBoxLayout *mainLayout = new QVBoxLayout(); if (infoLabel) { mainLayout->addWidget(infoLabel); } mainLayout->addLayout(topLayout); mainLayout->addWidget(m_warnLabel); mainLayout->addWidget(m_btnBox); mainLayout->setSizeConstraint(QLayout::SetFixedSize); setLayout(mainLayout); setWindowTitle(p_title); connect(m_nameEdit, &QLineEdit::textChanged, this, &VEditSnippetDialog::handleInputChanged); connect(m_typeCB, static_cast(&QComboBox::currentIndexChanged), this, &VEditSnippetDialog::handleInputChanged); connect(m_cursorMarkEdit, &QLineEdit::textChanged, this, &VEditSnippetDialog::handleInputChanged); connect(m_selectionMarkEdit, &QLineEdit::textChanged, this, &VEditSnippetDialog::handleInputChanged); connect(m_contentEdit, &QTextEdit::textChanged, this, &VEditSnippetDialog::handleInputChanged); } void VEditSnippetDialog::handleInputChanged() { bool showWarnLabel = false; QString name = m_nameEdit->getEvaluatedText(); bool nameOk = !name.isEmpty(); if (nameOk && name != m_snippet.getName()) { // Check if the name conflicts with existing snippet name. // Case-insensitive. QString lowerName = name.toLower(); bool conflicted = false; for (auto const & item : m_snippets) { if (item.getName() == name) { conflicted = true; break; } } QString warnText; if (conflicted) { nameOk = false; warnText = tr("WARNING: " "Name (case-insensitive) %3 already exists. " "Please choose another name.") .arg(g_config->c_warningTextStyle) .arg(g_config->c_dataTextStyle) .arg(name); } else if (!VUtils::checkFileNameLegal(name)) { // Check if evaluated name contains illegal characters. nameOk = false; warnText = tr("WARNING: " "Name %3 contains illegal characters " "(after magic word evaluation).") .arg(g_config->c_warningTextStyle) .arg(g_config->c_dataTextStyle) .arg(name); } if (!nameOk) { showWarnLabel = true; m_warnLabel->setText(warnText); } } QString cursorMark = m_cursorMarkEdit->text(); bool cursorMarkOk = true; if (nameOk && !cursorMark.isEmpty()) { // Check if the mark appears more than once in the content. QString selectionMark = m_selectionMarkEdit->text(); QString content = getContentEditByType(); content = g_mwMgr->evaluate(content); QString warnText; if (content.count(cursorMark) > 1) { cursorMarkOk = false; warnText = tr("WARNING: " "Cursor mark %3 occurs more than once " "in the content (after magic word evaluation). " "Please choose another mark.") .arg(g_config->c_warningTextStyle) .arg(g_config->c_dataTextStyle) .arg(cursorMark); } else if ((cursorMark == selectionMark || cursorMark.contains(selectionMark) || selectionMark.contains(cursorMark)) && !selectionMark.isEmpty()) { cursorMarkOk = false; warnText = tr("WARNING: " "Cursor mark %3 conflicts with selection mark. " "Please choose another mark.") .arg(g_config->c_warningTextStyle) .arg(g_config->c_dataTextStyle) .arg(cursorMark); } if (!cursorMarkOk) { showWarnLabel = true; m_warnLabel->setText(warnText); } } m_warnLabel->setVisible(showWarnLabel); QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); okBtn->setEnabled(nameOk && cursorMarkOk); } void VEditSnippetDialog::setContentEditByType() { switch (m_snippet.getType()) { case VSnippet::Type::PlainText: m_contentEdit->setPlainText(m_snippet.getContent()); break; case VSnippet::Type::Html: m_contentEdit->setHtml(m_snippet.getContent()); break; default: m_contentEdit->setPlainText(m_snippet.getContent()); break; } } QString VEditSnippetDialog::getContentEditByType() const { if (m_typeCB->currentIndex() == -1) { return QString(); } switch (static_cast(m_typeCB->currentData().toInt())) { case VSnippet::Type::PlainText: return m_contentEdit->toPlainText(); case VSnippet::Type::Html: return m_contentEdit->toHtml(); default: return m_contentEdit->toPlainText(); } } QString VEditSnippetDialog::getNameInput() const { return m_nameEdit->getEvaluatedText(); } VSnippet::Type VEditSnippetDialog::getTypeInput() const { return static_cast(m_typeCB->currentData().toInt()); } QString VEditSnippetDialog::getCursorMarkInput() const { return m_cursorMarkEdit->text(); } QString VEditSnippetDialog::getSelectionMarkInput() const { return m_selectionMarkEdit->text(); } QString VEditSnippetDialog::getContentInput() const { return getContentEditByType(); } QChar VEditSnippetDialog::getShortcutInput() const { return m_shortcutCB->currentData().toChar(); } bool VEditSnippetDialog::getAutoIndentInput() const { return m_autoIndentCB->isChecked(); } QVector VEditSnippetDialog::getAvailableShortcuts() const { QVector ret = VSnippet::getAllShortcuts(); QChar curCh = m_snippet.getShortcut(); // Remove those have already been assigned to snippets. for (auto const & snip : m_snippets) { QChar ch = snip.getShortcut(); if (ch.isNull()) { continue; } if (ch != curCh) { ret.removeOne(ch); } } return ret; }