Libksieve

sieveglobalvariablewidget.cpp
1 /*
2  SPDX-FileCopyrightText: 2013-2021 Laurent Montel <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 
7 #include "sieveglobalvariablewidget.h"
8 #include "autocreatescriptutil_p.h"
9 #include "commonwidgets/sievehelpbutton.h"
10 #include "editor/sieveeditorutil.h"
11 #include "sievescriptblockwidget.h"
12 #include "widgets/lineeditvalidator.h"
13 
14 #include <KLocalizedString>
15 #include <Libkdepim/LineEditCatchReturnKey>
16 #include <QIcon>
17 #include <QLineEdit>
18 #include <QPushButton>
19 
20 #include "libksieve_debug.h"
21 #include <QCheckBox>
22 #include <QGridLayout>
23 #include <QLabel>
24 #include <QWhatsThis>
25 #include <QXmlStreamReader>
26 
27 using namespace KSieveUi;
28 static const int MINIMUMGLOBALVARIABLEACTION = 1;
29 static const int MAXIMUMGLOBALVARIABLEACTION = 15;
30 
31 SieveGlobalVariableActionWidget::SieveGlobalVariableActionWidget(QWidget *parent)
32  : QWidget(parent)
33 {
34  initWidget();
35 }
36 
37 SieveGlobalVariableActionWidget::~SieveGlobalVariableActionWidget()
38 {
39 }
40 
41 void SieveGlobalVariableActionWidget::generatedScript(QString &script)
42 {
43  const QString variableName = mVariableName->text();
44  if (variableName.trimmed().isEmpty()) {
45  return;
46  }
47  script += QLatin1String("global ");
48  script += QStringLiteral("\"%1\";\n").arg(variableName);
49  if (mSetValueTo->isChecked() && !mVariableValue->text().isEmpty()) {
50  script += QStringLiteral("set \"%1\" \"%2\";\n").arg(variableName, mVariableValue->text());
51  }
52 }
53 
54 void SieveGlobalVariableActionWidget::initWidget()
55 {
56  mLayout = new QGridLayout(this);
57  mLayout->setContentsMargins({});
58 
59  auto lab = new QLabel(i18n("Variable name:"), this);
60  mLayout->addWidget(lab, 1, 0);
61 
62  mVariableName = new LineEditValidator(this);
63  connect(mVariableName, &QLineEdit::textChanged, this, &SieveGlobalVariableActionWidget::valueChanged);
64  mLayout->addWidget(mVariableName, 1, 1);
65 
66  mSetValueTo = new QCheckBox(i18n("Set value to:"), this);
67  connect(mSetValueTo, &QCheckBox::toggled, this, &SieveGlobalVariableActionWidget::valueChanged);
68  mLayout->addWidget(mSetValueTo, 1, 2);
69  mSetValueTo->setChecked(false);
70 
71  mVariableValue = new QLineEdit(this);
72  new KPIM::LineEditCatchReturnKey(mVariableValue, this);
73  connect(mVariableValue, &QLineEdit::textChanged, this, &SieveGlobalVariableActionWidget::valueChanged);
74  mVariableValue->setEnabled(false);
75  mLayout->addWidget(mVariableValue, 1, 3);
76 
77  connect(mSetValueTo, &QCheckBox::clicked, mVariableValue, &QLineEdit::setEnabled);
78 
79  mAdd = new QPushButton(this);
80  mAdd->setIcon(QIcon::fromTheme(QStringLiteral("list-add")));
81  mAdd->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
82 
83  mRemove = new QPushButton(this);
84  mRemove->setIcon(QIcon::fromTheme(QStringLiteral("list-remove")));
85  mRemove->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
86  mLayout->addWidget(mAdd, 1, 4);
87  mLayout->addWidget(mRemove, 1, 5);
88 
89  connect(mAdd, &QPushButton::clicked, this, &SieveGlobalVariableActionWidget::slotAddWidget);
90  connect(mRemove, &QPushButton::clicked, this, &SieveGlobalVariableActionWidget::slotRemoveWidget);
91 }
92 
93 void SieveGlobalVariableActionWidget::clear()
94 {
95  mVariableName->clear();
96  mSetValueTo->setChecked(false);
97  mVariableValue->setEnabled(false);
98  mVariableValue->clear();
99 }
100 
101 bool SieveGlobalVariableActionWidget::isInitialized() const
102 {
103  return !mVariableName->text().isEmpty();
104 }
105 
106 QString SieveGlobalVariableActionWidget::variableName() const
107 {
108  const QString varName = mVariableName->text();
109  if (varName.trimmed().isEmpty()) {
110  return {};
111  }
112  return varName;
113 }
114 
115 void SieveGlobalVariableActionWidget::setVariableValue(const QString &name)
116 {
117  mSetValueTo->setChecked(true);
118  mVariableValue->setText(name);
119  mVariableValue->setEnabled(true);
120 }
121 
122 void SieveGlobalVariableActionWidget::loadScript(QXmlStreamReader &element, QString &error)
123 {
124  while (element.readNextStartElement()) {
125  const QStringRef tagName = element.name();
126  if (tagName == QLatin1String("str")) {
127  mVariableName->setText(element.readElementText());
128  } else {
129  error += i18n("Unknown tag \"%1\" during loading of variables.", *tagName.string()) + QLatin1Char('\n');
130  qCDebug(LIBKSIEVE_LOG) << " SieveGlobalVariableActionWidget::loadScript unknown tagName " << tagName;
131  }
132  }
133 }
134 
135 void SieveGlobalVariableActionWidget::slotAddWidget()
136 {
137  Q_EMIT addWidget(this);
138  Q_EMIT valueChanged();
139 }
140 
141 void SieveGlobalVariableActionWidget::slotRemoveWidget()
142 {
143  Q_EMIT removeWidget(this);
144  Q_EMIT valueChanged();
145 }
146 
147 void SieveGlobalVariableActionWidget::updateAddRemoveButton(bool addButtonEnabled, bool removeButtonEnabled)
148 {
149  mAdd->setEnabled(addButtonEnabled);
150  mRemove->setEnabled(removeButtonEnabled);
151 }
152 
153 SieveGlobalVariableWidget::SieveGlobalVariableWidget(QWidget *parent)
154  : SieveWidgetPageAbstract(parent)
155 {
156  auto lay = new QVBoxLayout(this);
157  mHelpButton = new SieveHelpButton(this);
158  lay->addWidget(mHelpButton);
159  connect(mHelpButton, &SieveHelpButton::clicked, this, &SieveGlobalVariableWidget::slotHelp);
160 
161  mIncludeLister = new SieveGlobalVariableLister(this);
162  connect(mIncludeLister, &SieveGlobalVariableLister::valueChanged, this, &SieveGlobalVariableWidget::valueChanged);
163  lay->addWidget(mIncludeLister, 0, Qt::AlignTop);
164  setPageType(KSieveUi::SieveScriptBlockWidget::GlobalVariable);
165 }
166 
167 SieveGlobalVariableWidget::~SieveGlobalVariableWidget()
168 {
169 }
170 
171 void SieveGlobalVariableWidget::slotHelp()
172 {
173  const QString help = i18n(
174  "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 "
175  "it global, the name specifies a separate, non-global variable within that script.");
176  const QUrl href = KSieveUi::SieveEditorUtil::helpUrl(KSieveUi::SieveEditorUtil::GlobalVariable);
177  const QString fullWhatsThis = AutoCreateScriptUtil::createFullWhatsThis(help, href.toString());
178  QWhatsThis::showText(QCursor::pos(), fullWhatsThis, mHelpButton);
179 }
180 
181 void SieveGlobalVariableWidget::generatedScript(QString &script, QStringList &requireModules, bool inForEveryPartLoop)
182 {
183  Q_UNUSED(inForEveryPartLoop)
184  QString result;
185  QStringList lst;
186  mIncludeLister->generatedScript(result, lst);
187  if (!result.isEmpty()) {
188  script += result;
189  requireModules << lst;
190  }
191 }
192 
193 void SieveGlobalVariableWidget::loadScript(QXmlStreamReader &element, QString &error)
194 {
195  mIncludeLister->loadScript(element, error);
196 }
197 
198 SieveGlobalVariableActionWidget::VariableElement SieveGlobalVariableWidget::loadSetVariable(QXmlStreamReader &element, QString &error)
199 {
200  return mIncludeLister->loadSetVariable(element, error);
201 }
202 
203 SieveGlobalVariableLister::SieveGlobalVariableLister(QWidget *parent)
204  : KPIM::KWidgetLister(false, MINIMUMGLOBALVARIABLEACTION, MAXIMUMGLOBALVARIABLEACTION, parent)
205 {
206  slotClear();
207  updateAddRemoveButton();
208 }
209 
210 SieveGlobalVariableLister::~SieveGlobalVariableLister()
211 {
212 }
213 
214 void SieveGlobalVariableLister::slotAddWidget(QWidget *w)
215 {
216  addWidgetAfterThisWidget(w);
217  updateAddRemoveButton();
218 }
219 
220 void SieveGlobalVariableLister::slotRemoveWidget(QWidget *w)
221 {
222  removeWidget(w);
223  updateAddRemoveButton();
224 }
225 
226 void SieveGlobalVariableLister::updateAddRemoveButton()
227 {
228  QList<QWidget *> widgetList = widgets();
229  const int numberOfWidget(widgetList.count());
230  bool addButtonEnabled = false;
231  bool removeButtonEnabled = false;
232  if (numberOfWidget <= widgetsMinimum()) {
233  addButtonEnabled = true;
234  removeButtonEnabled = false;
235  } else if (numberOfWidget >= widgetsMaximum()) {
236  addButtonEnabled = false;
237  removeButtonEnabled = true;
238  } else {
239  addButtonEnabled = true;
240  removeButtonEnabled = true;
241  }
242  QList<QWidget *>::ConstIterator wIt = widgetList.constBegin();
243  QList<QWidget *>::ConstIterator wEnd = widgetList.constEnd();
244  for (; wIt != wEnd; ++wIt) {
245  auto w = qobject_cast<SieveGlobalVariableActionWidget *>(*wIt);
246  w->updateAddRemoveButton(addButtonEnabled, removeButtonEnabled);
247  }
248 }
249 
250 void SieveGlobalVariableLister::generatedScript(QString &script, QStringList &requireModules)
251 {
252  requireModules << QStringLiteral("include");
253  const QList<QWidget *> widgetList = widgets();
254  QList<QWidget *>::ConstIterator wIt = widgetList.constBegin();
255  QList<QWidget *>::ConstIterator wEnd = widgetList.constEnd();
256  for (; wIt != wEnd; ++wIt) {
257  auto w = qobject_cast<SieveGlobalVariableActionWidget *>(*wIt);
258  w->generatedScript(script);
259  }
260 }
261 
262 void SieveGlobalVariableLister::reconnectWidget(SieveGlobalVariableActionWidget *w)
263 {
264  connect(w, &SieveGlobalVariableActionWidget::addWidget, this, &SieveGlobalVariableLister::slotAddWidget, Qt::UniqueConnection);
265  connect(w, &SieveGlobalVariableActionWidget::removeWidget, this, &SieveGlobalVariableLister::slotRemoveWidget, Qt::UniqueConnection);
266  connect(w, &SieveGlobalVariableActionWidget::valueChanged, this, &SieveGlobalVariableLister::valueChanged, Qt::UniqueConnection);
267 }
268 
269 void SieveGlobalVariableLister::clearWidget(QWidget *aWidget)
270 {
271  if (aWidget) {
272  auto widget = static_cast<SieveGlobalVariableActionWidget *>(aWidget);
273  widget->clear();
274  }
275  Q_EMIT valueChanged();
276 }
277 
278 QWidget *SieveGlobalVariableLister::createWidget(QWidget *parent)
279 {
280  auto w = new SieveGlobalVariableActionWidget(parent);
281  reconnectWidget(w);
282  return w;
283 }
284 
285 void SieveGlobalVariableLister::loadScript(QXmlStreamReader &element, QString &error)
286 {
287  SieveGlobalVariableActionWidget *w = static_cast<SieveGlobalVariableActionWidget *>(widgets().constLast());
288  if (w->isInitialized()) {
289  addWidgetAfterThisWidget(widgets().constLast());
290  w = static_cast<SieveGlobalVariableActionWidget *>(widgets().constLast());
291  }
292  w->loadScript(element, error);
293 }
294 
295 SieveGlobalVariableActionWidget::VariableElement SieveGlobalVariableLister::loadSetVariable(QXmlStreamReader &element, QString & /*error*/)
296 {
297  SieveGlobalVariableActionWidget::VariableElement var;
298  QString variableName;
299  QString variableValue;
300  int index = 0;
301  while (element.readNextStartElement()) {
302  const QStringRef tagName = element.name();
303  if (tagName == QLatin1String("str")) {
304  if (index == 0) {
305  variableName = element.readElementText();
306  } else if (index == 1) {
307  variableValue = element.readElementText();
308  } else {
309  qCDebug(LIBKSIEVE_LOG) << " SieveGlobalVariableLister::loadSetVariable too many argument:" << index;
310  }
311  ++index;
312  } else {
313  qCDebug(LIBKSIEVE_LOG) << " SieveGlobalVariableLister::loadSetVariable unknown tagName " << tagName;
314  }
315  }
316 
317  const QList<QWidget *> lstWidget = widgets();
318  bool globalVariableFound = false;
319  for (QWidget *widget : lstWidget) {
320  auto w = static_cast<SieveGlobalVariableActionWidget *>(widget);
321  if (w->variableName() == variableName) {
322  w->setVariableValue(variableValue);
323  globalVariableFound = true;
324  }
325  }
326  if (!globalVariableFound) {
327  var.variableName = variableName;
328  var.variableValue = variableValue;
329  }
330  return var;
331 }
void showText(const QPoint &pos, const QString &text, QWidget *w)
bool readNextStartElement()
void textChanged(const QString &text)
QString toString(QUrl::FormattingOptions options) const const
AlignTop
void setEnabled(bool)
int count(const T &value) const const
const QList< QKeySequence > & help()
QString readElementText(QXmlStreamReader::ReadElementTextBehaviour behaviour)
bool isEmpty() const const
QString trimmed() const const
void clicked(bool checked)
QString i18n(const char *text, const TYPE &arg...)
QPoint pos()
const QString * string() const const
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
void toggled(bool checked)
QIcon fromTheme(const QString &name)
QList::const_iterator constEnd() const const
QList::const_iterator constBegin() const const
UniqueConnection
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
T qobject_cast(QObject *object)
QObject * parent() const const
QStringRef name() const const
Q_EMITQ_EMIT
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Fri Apr 16 2021 23:09:34 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.