File indexing completed on 2024-05-05 05:52:18
0001 /* This file is part of the Kate project. 0002 * Based on the snippet plugin from KDevelop 4. 0003 * 0004 * SPDX-FileCopyrightText: 2007 Robert Gruber <rgruber@users.sourceforge.net> 0005 * SPDX-FileCopyrightText: 2010 Milian Wolff <mail@milianw.de> 0006 * SPDX-FileCopyrightText: 2012 Christoph Cullmann <cullmann@kde.org> 0007 * 0008 * SPDX-License-Identifier: LGPL-2.0-or-later 0009 */ 0010 0011 #include "editsnippet.h" 0012 0013 #include "ui_editsnippet.h" 0014 0015 #include "snippet.h" 0016 #include "snippetrepository.h" 0017 #include "snippetstore.h" 0018 0019 #include <KConfigGroup> 0020 #include <KLocalizedString> 0021 #include <KMessageBox> 0022 #include <KSharedConfig> 0023 0024 #include <QAction> 0025 #include <QPushButton> 0026 #include <QWhatsThis> 0027 0028 #include <KTextEditor/Document> 0029 #include <KTextEditor/Editor> 0030 #include <KTextEditor/View> 0031 0032 static const char s_configFile[] = "kate-snippetsrc"; 0033 0034 KTextEditor::View *createView(QWidget *tabWidget) 0035 { 0036 auto document = KTextEditor::Editor::instance()->createDocument(tabWidget); 0037 auto view = document->createView(tabWidget); 0038 0039 view->action(QStringLiteral("file_save"))->setEnabled(false); 0040 tabWidget->layout()->addWidget(view); 0041 view->setStatusBarEnabled(false); 0042 return view; 0043 } 0044 0045 EditSnippet::EditSnippet(SnippetRepository *repository, Snippet *snippet, QWidget *parent) 0046 : QDialog(parent) 0047 , m_ui(std::make_unique<Ui::EditSnippetBase>()) 0048 , m_repo(repository) 0049 , m_snippet(snippet) 0050 , m_topBoxModified(false) 0051 { 0052 Q_ASSERT(m_repo); 0053 m_ui->setupUi(this); 0054 0055 connect(this, &QDialog::accepted, this, &EditSnippet::save); 0056 0057 m_okButton = m_ui->buttons->button(QDialogButtonBox::Ok); 0058 KGuiItem::assign(m_okButton, KStandardGuiItem::ok()); 0059 m_ui->buttons->addButton(m_okButton, QDialogButtonBox::AcceptRole); 0060 connect(m_okButton, &QPushButton::clicked, this, &QDialog::accept); 0061 0062 auto cancelButton = m_ui->buttons->button(QDialogButtonBox::Cancel); 0063 KGuiItem::assign(cancelButton, KStandardGuiItem::cancel()); 0064 m_ui->buttons->addButton(cancelButton, QDialogButtonBox::RejectRole); 0065 connect(cancelButton, &QPushButton::clicked, this, &QDialog::reject); 0066 0067 m_snippetView = createView(m_ui->snippetTab); 0068 if (!m_repo->fileTypes().isEmpty()) { 0069 m_snippetView->document()->setMode(m_repo->fileTypes().first()); 0070 } 0071 0072 m_scriptsView = createView(m_ui->scriptTab); 0073 m_scriptsView->document()->setMode(QStringLiteral("JavaScript")); 0074 m_scriptsView->document()->setText(m_repo->script()); 0075 m_scriptsView->document()->setModified(false); 0076 0077 // view for testing the snippet 0078 m_testView = createView(m_ui->testWidget); 0079 // splitter default size ratio 0080 m_ui->splitter->setSizes(QList<int>() << 400 << 150); 0081 connect(m_ui->dotest_button, &QPushButton::clicked, this, &EditSnippet::test); 0082 0083 // modified notification stuff 0084 connect(m_ui->snippetNameEdit, &QLineEdit::textEdited, this, &EditSnippet::topBoxModified); 0085 connect(m_ui->snippetNameEdit, &QLineEdit::textEdited, this, &EditSnippet::validate); 0086 connect(m_ui->snippetShortcut, &KKeySequenceWidget::keySequenceChanged, this, &EditSnippet::topBoxModified); 0087 connect(m_snippetView->document(), &KTextEditor::Document::textChanged, this, &EditSnippet::validate); 0088 0089 auto showHelp = [](const QString &text) { 0090 QWhatsThis::showText(QCursor::pos(), text); 0091 }; 0092 connect(m_ui->snippetLabel, &QLabel::linkActivated, showHelp); 0093 connect(m_ui->scriptLabel, &QLabel::linkActivated, showHelp); 0094 0095 // if we edit a snippet, add all existing data 0096 if (m_snippet) { 0097 setWindowTitle(i18n("Edit Snippet %1 in %2", m_snippet->text(), m_repo->text())); 0098 0099 m_snippetView->document()->setText(m_snippet->snippet()); 0100 m_ui->snippetNameEdit->setText(m_snippet->text()); 0101 m_ui->snippetShortcut->setKeySequence(m_snippet->action()->shortcut()); 0102 0103 // unset modified flags 0104 m_snippetView->document()->setModified(false); 0105 m_topBoxModified = false; 0106 } else { 0107 setWindowTitle(i18n("Create New Snippet in Repository %1", m_repo->text())); 0108 } 0109 0110 m_ui->messageWidget->hide(); 0111 validate(); 0112 0113 m_ui->snippetNameEdit->setFocus(); 0114 setTabOrder(m_ui->snippetNameEdit, m_snippetView); 0115 0116 KSharedConfigPtr config = KSharedConfig::openConfig(QLatin1String(s_configFile)); 0117 KConfigGroup group = config->group(QStringLiteral("General")); 0118 const QSize savedSize = group.readEntry("Size", QSize()); 0119 if (savedSize.isValid()) { 0120 resize(savedSize); 0121 } 0122 } 0123 0124 void EditSnippet::test() 0125 { 0126 m_testView->document()->clear(); 0127 m_testView->insertTemplate(KTextEditor::Cursor(0, 0), m_snippetView->document()->text(), m_scriptsView->document()->text()); 0128 m_testView->setFocus(); 0129 } 0130 0131 EditSnippet::~EditSnippet() = default; 0132 0133 void EditSnippet::setSnippetText(const QString &text) 0134 { 0135 m_snippetView->document()->setText(text); 0136 validate(); 0137 } 0138 0139 void EditSnippet::validate() 0140 { 0141 const QString &name = m_ui->snippetNameEdit->text(); 0142 bool valid = !name.isEmpty() && !m_snippetView->document()->isEmpty(); 0143 // make sure the snippetname includes no spaces 0144 if (name.contains(QLatin1Char(' ')) || name.contains(QLatin1Char('\t'))) { 0145 m_ui->messageWidget->setText(i18n("Snippet name cannot contain spaces")); 0146 m_ui->messageWidget->animatedShow(); 0147 valid = false; 0148 } else { 0149 // hide message widget if snippet does not include spaces 0150 m_ui->messageWidget->animatedHide(); 0151 } 0152 if (valid) { 0153 m_ui->messageWidget->hide(); 0154 } 0155 m_okButton->setEnabled(valid); 0156 } 0157 0158 void EditSnippet::save() 0159 { 0160 Q_ASSERT(!m_ui->snippetNameEdit->text().isEmpty()); 0161 0162 if (!m_snippet) { 0163 // save as new snippet 0164 m_snippet = new Snippet(); 0165 m_snippet->action(); // ensure that the snippet's QAction is created before it is added to a widget by the rowsInserted() signal 0166 m_repo->appendRow(m_snippet); 0167 } 0168 m_snippet->setSnippet(m_snippetView->document()->text()); 0169 m_snippetView->document()->setModified(false); 0170 m_snippet->setText(m_ui->snippetNameEdit->text()); 0171 m_snippet->action()->setShortcut(m_ui->snippetShortcut->keySequence()); 0172 m_repo->setScript(m_scriptsView->document()->text()); 0173 m_scriptsView->document()->setModified(false); 0174 m_topBoxModified = false; 0175 m_repo->save(); 0176 0177 setWindowTitle(i18n("Edit Snippet %1 in %2", m_snippet->text(), m_repo->text())); 0178 0179 KSharedConfigPtr config = KSharedConfig::openConfig(QLatin1String(s_configFile)); 0180 KConfigGroup group = config->group(QStringLiteral("General")); 0181 group.writeEntry("Size", size()); 0182 group.sync(); 0183 } 0184 0185 void EditSnippet::reject() 0186 { 0187 if (m_topBoxModified || m_snippetView->document()->isModified() || m_scriptsView->document()->isModified()) { 0188 int ret = KMessageBox::warningContinueCancel(qApp->activeWindow(), 0189 i18n("The snippet contains unsaved changes. Do you want to continue and lose all changes?"), 0190 i18n("Warning - Unsaved Changes")); 0191 if (ret == KMessageBox::Cancel) { 0192 return; 0193 } 0194 } 0195 QDialog::reject(); 0196 } 0197 0198 void EditSnippet::topBoxModified() 0199 { 0200 m_topBoxModified = true; 0201 } 0202 0203 #include "moc_editsnippet.cpp"