File indexing completed on 2024-12-29 04:54:44
0001 /* 0002 SPDX-FileCopyrightText: 2013-2024 Laurent Montel <montel@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "sieveglobalvariablewidget.h" 0008 #include "autocreatescriptutil_p.h" 0009 #include "commonwidgets/sievehelpbutton.h" 0010 #include "editor/sieveeditorutil.h" 0011 #include "sievescriptblockwidget.h" 0012 #include "widgets/lineeditvalidator.h" 0013 0014 #include <KLineEditEventHandler> 0015 #include <KLocalizedString> 0016 #include <QIcon> 0017 #include <QLineEdit> 0018 #include <QPushButton> 0019 0020 #include "libksieveui_debug.h" 0021 #include <QCheckBox> 0022 #include <QGridLayout> 0023 #include <QLabel> 0024 #include <QScrollArea> 0025 #include <QWhatsThis> 0026 #include <QXmlStreamReader> 0027 0028 using namespace KSieveUi; 0029 static const int MINIMUMGLOBALVARIABLEACTION = 1; 0030 static const int MAXIMUMGLOBALVARIABLEACTION = 15; 0031 0032 SieveGlobalVariableActionWidget::SieveGlobalVariableActionWidget(QWidget *parent) 0033 : QWidget(parent) 0034 { 0035 initWidget(); 0036 } 0037 0038 SieveGlobalVariableActionWidget::~SieveGlobalVariableActionWidget() = default; 0039 0040 void SieveGlobalVariableActionWidget::generatedScript(QString &script) 0041 { 0042 const QString variableName = mVariableName->text(); 0043 if (variableName.trimmed().isEmpty()) { 0044 return; 0045 } 0046 script += QLatin1StringView("global "); 0047 script += QStringLiteral("\"%1\";\n").arg(variableName); 0048 if (mSetValueTo->isChecked() && !mVariableValue->text().isEmpty()) { 0049 script += QStringLiteral("set \"%1\" \"%2\";\n").arg(variableName, mVariableValue->text()); 0050 } 0051 } 0052 0053 void SieveGlobalVariableActionWidget::initWidget() 0054 { 0055 mLayout = new QGridLayout(this); 0056 mLayout->setContentsMargins({}); 0057 0058 auto lab = new QLabel(i18n("Variable name:"), this); 0059 mLayout->addWidget(lab, 1, 0); 0060 0061 mVariableName = new LineEditValidator(this); 0062 connect(mVariableName, &QLineEdit::textChanged, this, &SieveGlobalVariableActionWidget::valueChanged); 0063 mLayout->addWidget(mVariableName, 1, 1); 0064 0065 mSetValueTo = new QCheckBox(i18n("Set value to:"), this); 0066 connect(mSetValueTo, &QCheckBox::toggled, this, &SieveGlobalVariableActionWidget::valueChanged); 0067 mLayout->addWidget(mSetValueTo, 1, 2); 0068 mSetValueTo->setChecked(false); 0069 0070 mVariableValue = new QLineEdit(this); 0071 KLineEditEventHandler::catchReturnKey(mVariableValue); 0072 connect(mVariableValue, &QLineEdit::textChanged, this, &SieveGlobalVariableActionWidget::valueChanged); 0073 mVariableValue->setEnabled(false); 0074 mLayout->addWidget(mVariableValue, 1, 3); 0075 0076 connect(mSetValueTo, &QCheckBox::clicked, mVariableValue, &QLineEdit::setEnabled); 0077 0078 mAdd = new QPushButton(this); 0079 mAdd->setIcon(QIcon::fromTheme(QStringLiteral("list-add"))); 0080 mAdd->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); 0081 0082 mRemove = new QPushButton(this); 0083 mRemove->setIcon(QIcon::fromTheme(QStringLiteral("list-remove"))); 0084 mRemove->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); 0085 mLayout->addWidget(mAdd, 1, 4); 0086 mLayout->addWidget(mRemove, 1, 5); 0087 0088 connect(mAdd, &QPushButton::clicked, this, &SieveGlobalVariableActionWidget::slotAddWidget); 0089 connect(mRemove, &QPushButton::clicked, this, &SieveGlobalVariableActionWidget::slotRemoveWidget); 0090 } 0091 0092 void SieveGlobalVariableActionWidget::clear() 0093 { 0094 mVariableName->clear(); 0095 mSetValueTo->setChecked(false); 0096 mVariableValue->setEnabled(false); 0097 mVariableValue->clear(); 0098 } 0099 0100 bool SieveGlobalVariableActionWidget::isInitialized() const 0101 { 0102 return !mVariableName->text().isEmpty(); 0103 } 0104 0105 QString SieveGlobalVariableActionWidget::variableName() const 0106 { 0107 const QString varName = mVariableName->text(); 0108 if (varName.trimmed().isEmpty()) { 0109 return {}; 0110 } 0111 return varName; 0112 } 0113 0114 void SieveGlobalVariableActionWidget::setVariableValue(const QString &name) 0115 { 0116 mSetValueTo->setChecked(true); 0117 mVariableValue->setText(name); 0118 mVariableValue->setEnabled(true); 0119 } 0120 0121 void SieveGlobalVariableActionWidget::loadScript(QXmlStreamReader &element, QString &error) 0122 { 0123 while (element.readNextStartElement()) { 0124 const QStringView tagName = element.name(); 0125 if (tagName == QLatin1StringView("str")) { 0126 mVariableName->setText(element.readElementText()); 0127 } else { 0128 const QString result = tagName.toString(); 0129 error += i18n("Unknown tag \"%1\" during loading of variables.", result) + QLatin1Char('\n'); 0130 qCDebug(LIBKSIEVEUI_LOG) << " SieveGlobalVariableActionWidget::loadScript unknown tagName " << tagName; 0131 } 0132 } 0133 } 0134 0135 void SieveGlobalVariableActionWidget::slotAddWidget() 0136 { 0137 Q_EMIT addWidget(this); 0138 Q_EMIT valueChanged(); 0139 } 0140 0141 void SieveGlobalVariableActionWidget::slotRemoveWidget() 0142 { 0143 Q_EMIT removeWidget(this); 0144 Q_EMIT valueChanged(); 0145 } 0146 0147 void SieveGlobalVariableActionWidget::updateAddRemoveButton(bool addButtonEnabled, bool removeButtonEnabled) 0148 { 0149 mAdd->setEnabled(addButtonEnabled); 0150 mRemove->setEnabled(removeButtonEnabled); 0151 } 0152 0153 SieveGlobalVariableWidget::SieveGlobalVariableWidget(QWidget *parent) 0154 : SieveWidgetPageAbstract(parent) 0155 { 0156 auto lay = new QVBoxLayout(this); 0157 mHelpButton = new SieveHelpButton(this); 0158 lay->addWidget(mHelpButton); 0159 connect(mHelpButton, &SieveHelpButton::clicked, this, &SieveGlobalVariableWidget::slotHelp); 0160 0161 mGlobalVariableLister = new SieveGlobalVariableLister(this); 0162 connect(mGlobalVariableLister, &SieveGlobalVariableLister::valueChanged, this, &SieveGlobalVariableWidget::valueChanged); 0163 0164 auto scrollArea = new QScrollArea(this); 0165 scrollArea->setAutoFillBackground(false); 0166 scrollArea->setWidget(mGlobalVariableLister); 0167 scrollArea->setWidgetResizable(true); 0168 scrollArea->setAlignment(Qt::AlignTop); 0169 lay->addWidget(scrollArea); 0170 0171 setPageType(KSieveUi::SieveScriptBlockWidget::GlobalVariable); 0172 } 0173 0174 SieveGlobalVariableWidget::~SieveGlobalVariableWidget() = default; 0175 0176 void SieveGlobalVariableWidget::slotHelp() 0177 { 0178 const QString help = i18n( 0179 "A variable has global scope in all scripts that have declared it with the \"global\" command. If a script uses that variable name without declaring " 0180 "it global, the name specifies a separate, non-global variable within that script."); 0181 const QUrl href = KSieveUi::SieveEditorUtil::helpUrl(KSieveUi::SieveEditorUtil::GlobalVariable); 0182 const QString fullWhatsThis = AutoCreateScriptUtil::createFullWhatsThis(help, href.toString()); 0183 QWhatsThis::showText(QCursor::pos(), fullWhatsThis, mHelpButton); 0184 } 0185 0186 void SieveGlobalVariableWidget::generatedScript(QString &script, QStringList &requireModules, bool inForEveryPartLoop) 0187 { 0188 Q_UNUSED(inForEveryPartLoop) 0189 QString result; 0190 QStringList lst; 0191 mGlobalVariableLister->generatedScript(result, lst); 0192 if (!result.isEmpty()) { 0193 script += result; 0194 requireModules << lst; 0195 } 0196 } 0197 0198 void SieveGlobalVariableWidget::loadScript(QXmlStreamReader &element, QString &error) 0199 { 0200 mGlobalVariableLister->loadScript(element, error); 0201 } 0202 0203 SieveGlobalVariableActionWidget::VariableElement SieveGlobalVariableWidget::loadSetVariable(QXmlStreamReader &element, QString &error) 0204 { 0205 return mGlobalVariableLister->loadSetVariable(element, error); 0206 } 0207 0208 SieveGlobalVariableLister::SieveGlobalVariableLister(QWidget *parent) 0209 : KPIM::KWidgetLister(false, MINIMUMGLOBALVARIABLEACTION, MAXIMUMGLOBALVARIABLEACTION, parent) 0210 { 0211 slotClear(); 0212 updateAddRemoveButton(); 0213 } 0214 0215 SieveGlobalVariableLister::~SieveGlobalVariableLister() = default; 0216 0217 void SieveGlobalVariableLister::slotAddWidget(QWidget *w) 0218 { 0219 addWidgetAfterThisWidget(w); 0220 updateAddRemoveButton(); 0221 } 0222 0223 void SieveGlobalVariableLister::slotRemoveWidget(QWidget *w) 0224 { 0225 removeWidget(w); 0226 updateAddRemoveButton(); 0227 } 0228 0229 void SieveGlobalVariableLister::updateAddRemoveButton() 0230 { 0231 QList<QWidget *> widgetList = widgets(); 0232 const int numberOfWidget(widgetList.count()); 0233 bool addButtonEnabled = false; 0234 bool removeButtonEnabled = false; 0235 if (numberOfWidget <= widgetsMinimum()) { 0236 addButtonEnabled = true; 0237 removeButtonEnabled = false; 0238 } else if (numberOfWidget >= widgetsMaximum()) { 0239 addButtonEnabled = false; 0240 removeButtonEnabled = true; 0241 } else { 0242 addButtonEnabled = true; 0243 removeButtonEnabled = true; 0244 } 0245 QList<QWidget *>::ConstIterator wIt = widgetList.constBegin(); 0246 QList<QWidget *>::ConstIterator wEnd = widgetList.constEnd(); 0247 for (; wIt != wEnd; ++wIt) { 0248 auto w = qobject_cast<SieveGlobalVariableActionWidget *>(*wIt); 0249 w->updateAddRemoveButton(addButtonEnabled, removeButtonEnabled); 0250 } 0251 } 0252 0253 void SieveGlobalVariableLister::generatedScript(QString &script, QStringList &requireModules) 0254 { 0255 requireModules << QStringLiteral("include"); 0256 const QList<QWidget *> widgetList = widgets(); 0257 QList<QWidget *>::ConstIterator wIt = widgetList.constBegin(); 0258 QList<QWidget *>::ConstIterator wEnd = widgetList.constEnd(); 0259 for (; wIt != wEnd; ++wIt) { 0260 auto w = qobject_cast<SieveGlobalVariableActionWidget *>(*wIt); 0261 w->generatedScript(script); 0262 } 0263 } 0264 0265 void SieveGlobalVariableLister::reconnectWidget(SieveGlobalVariableActionWidget *w) 0266 { 0267 connect(w, &SieveGlobalVariableActionWidget::addWidget, this, &SieveGlobalVariableLister::slotAddWidget, Qt::UniqueConnection); 0268 connect(w, &SieveGlobalVariableActionWidget::removeWidget, this, &SieveGlobalVariableLister::slotRemoveWidget, Qt::UniqueConnection); 0269 connect(w, &SieveGlobalVariableActionWidget::valueChanged, this, &SieveGlobalVariableLister::valueChanged, Qt::UniqueConnection); 0270 } 0271 0272 void SieveGlobalVariableLister::clearWidget(QWidget *aWidget) 0273 { 0274 if (aWidget) { 0275 auto widget = static_cast<SieveGlobalVariableActionWidget *>(aWidget); 0276 widget->clear(); 0277 updateAddRemoveButton(); 0278 } 0279 Q_EMIT valueChanged(); 0280 } 0281 0282 QWidget *SieveGlobalVariableLister::createWidget(QWidget *parent) 0283 { 0284 auto w = new SieveGlobalVariableActionWidget(parent); 0285 reconnectWidget(w); 0286 return w; 0287 } 0288 0289 void SieveGlobalVariableLister::loadScript(QXmlStreamReader &element, QString &error) 0290 { 0291 SieveGlobalVariableActionWidget *w = static_cast<SieveGlobalVariableActionWidget *>(widgets().constLast()); 0292 if (w->isInitialized()) { 0293 addWidgetAfterThisWidget(widgets().constLast()); 0294 w = static_cast<SieveGlobalVariableActionWidget *>(widgets().constLast()); 0295 } 0296 w->loadScript(element, error); 0297 } 0298 0299 SieveGlobalVariableActionWidget::VariableElement SieveGlobalVariableLister::loadSetVariable(QXmlStreamReader &element, QString & /*error*/) 0300 { 0301 SieveGlobalVariableActionWidget::VariableElement var; 0302 QString variableName; 0303 QString variableValue; 0304 int index = 0; 0305 while (element.readNextStartElement()) { 0306 const QStringView tagName = element.name(); 0307 if (tagName == QLatin1StringView("str")) { 0308 if (index == 0) { 0309 variableName = element.readElementText(); 0310 } else if (index == 1) { 0311 variableValue = element.readElementText(); 0312 } else { 0313 qCDebug(LIBKSIEVEUI_LOG) << " SieveGlobalVariableLister::loadSetVariable too many argument:" << index; 0314 } 0315 ++index; 0316 } else { 0317 qCDebug(LIBKSIEVEUI_LOG) << " SieveGlobalVariableLister::loadSetVariable unknown tagName " << tagName; 0318 } 0319 } 0320 0321 const QList<QWidget *> lstWidget = widgets(); 0322 bool globalVariableFound = false; 0323 for (QWidget *widget : lstWidget) { 0324 auto w = static_cast<SieveGlobalVariableActionWidget *>(widget); 0325 if (w->variableName() == variableName) { 0326 w->setVariableValue(variableValue); 0327 globalVariableFound = true; 0328 } 0329 } 0330 if (!globalVariableFound) { 0331 var.variableName = variableName; 0332 var.variableValue = variableValue; 0333 } 0334 return var; 0335 } 0336 0337 #include "moc_sieveglobalvariablewidget.cpp"