Libksieve

sievescriptblockwidget.cpp
1 /*
2  Copyright (C) 2013-2020 Laurent Montel <[email protected]>
3 
4  This library is free software; you can redistribute it and/or
5  modify it under the terms of the GNU Library General Public
6  License as published by the Free Software Foundation; either
7  version 2 of the License, or (at your option) any later version.
8 
9  This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  Library General Public License for more details.
13 
14  You should have received a copy of the GNU Library General Public License
15  along with this library; see the file COPYING.LIB. If not, write to
16  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  Boston, MA 02110-1301, USA.
18 */
19 
20 #include "sievescriptblockwidget.h"
21 #include "sieveactionwidgetlister.h"
22 #include "sieveconditionwidgetlister.h"
23 #include "autocreatescriptutil_p.h"
24 
25 #include <KLocalizedString>
26 #include <QComboBox>
27 #include <QPushButton>
28 #include <QIcon>
29 
30 #include <QXmlStreamReader>
31 #include <QVBoxLayout>
32 #include <QGroupBox>
33 #include <QButtonGroup>
34 #include <QRadioButton>
35 #include <QLabel>
36 #include "libksieve_debug.h"
37 
38 using namespace KSieveUi;
39 
40 SieveScriptBlockWidget::SieveScriptBlockWidget(SieveEditorGraphicalModeWidget *graphicalModeWidget, QWidget *parent)
41  : SieveWidgetPageAbstract(parent)
42  , mMatchCondition(AndCondition)
43  , mSieveGraphicalModeWidget(graphicalModeWidget)
44 {
45  QVBoxLayout *topLayout = new QVBoxLayout(this);
46  topLayout->setContentsMargins(0, 0, 0, 0);
47 
48  mConditions = new QGroupBox(i18n("Conditions"));
49  QVBoxLayout *vbox = new QVBoxLayout;
50 
51  mAllMessageRBtn = new QRadioButton(i18n("Match all messages"), this);
52  mMatchAll = new QRadioButton(i18n("Match a&ll of the following"), this);
53  mMatchAny = new QRadioButton(i18n("Match an&y of the following"), this);
54 
55  vbox->addWidget(mMatchAll);
56  vbox->addWidget(mMatchAny);
57  vbox->addWidget(mAllMessageRBtn);
58  mMatchAll->setChecked(true);
59  mMatchAny->setChecked(false);
60  mAllMessageRBtn->setChecked(false);
61 
62  QButtonGroup *bg = new QButtonGroup(this);
63  bg->addButton(mMatchAll);
64  bg->addButton(mMatchAny);
65  bg->addButton(mAllMessageRBtn);
66 
67  connect(bg, QOverload<QAbstractButton *>::of(&QButtonGroup::buttonClicked), this, &SieveScriptBlockWidget::slotRadioClicked);
68  mConditions->setLayout(vbox);
69 
70  mScriptConditionLister = new SieveConditionWidgetLister(mSieveGraphicalModeWidget, this);
71  connect(mScriptConditionLister, &SieveConditionWidgetLister::valueChanged, this, &SieveScriptBlockWidget::valueChanged);
72  vbox->addWidget(mScriptConditionLister);
73 
74  topLayout->addWidget(mConditions, 0, Qt::AlignTop);
75 
76  QGroupBox *actions = new QGroupBox(i18n("Actions"));
77  vbox = new QVBoxLayout;
78  actions->setLayout(vbox);
79  mScriptActionLister = new SieveActionWidgetLister(mSieveGraphicalModeWidget, this);
80  connect(mScriptActionLister, &SieveActionWidgetLister::valueChanged, this, &SieveScriptBlockWidget::valueChanged);
81  vbox->addWidget(mScriptActionLister, 0, Qt::AlignTop);
82  topLayout->addWidget(actions);
83 
84  QHBoxLayout *newBlockLayout = new QHBoxLayout;
85  QLabel *lab = new QLabel(i18n("Add new block:"));
86  newBlockLayout->addWidget(lab);
87  mNewBlockType = new QComboBox;
88  newBlockLayout->addWidget(mNewBlockType);
89  mNewBlockType->addItem(i18n("\"elsif\" block"));
90  mNewBlockType->addItem(i18n("\"else\" block"));
91 
92  mAddBlockType = new QPushButton;
93  mAddBlockType->setIcon(QIcon::fromTheme(QStringLiteral("list-add")));
94  mAddBlockType->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
95  newBlockLayout->addWidget(mAddBlockType);
96  connect(mAddBlockType, &QPushButton::clicked, this, &SieveScriptBlockWidget::slotAddBlock);
97 
98  topLayout->addLayout(newBlockLayout);
99 }
100 
101 SieveScriptBlockWidget::~SieveScriptBlockWidget()
102 {
103 }
104 
105 void SieveScriptBlockWidget::slotAddBlock()
106 {
107  KSieveUi::SieveWidgetPageAbstract::PageType type = BlockElsIf;
108  switch (mNewBlockType->currentIndex()) {
109  case 0:
110  type = BlockElsIf;
111  break;
112  case 1:
113  type = BlockElse;
114  break;
115  }
116 
117  Q_EMIT valueChanged();
118  Q_EMIT addNewBlock(this, type);
119 }
120 
121 void SieveScriptBlockWidget::setPageType(PageType type)
122 {
123  if (pageType() != type) {
124  SieveWidgetPageAbstract::setPageType(type);
125  switch (type) {
126  case BlockIf:
127  mAllMessageRBtn->show();
128  mConditions->show();
129  mAddBlockType->setEnabled(true);
130  mNewBlockType->setEnabled(true);
131  break;
132  case BlockElsIf:
133  mAllMessageRBtn->hide();
134  mConditions->show();
135  mAddBlockType->setEnabled(true);
136  mNewBlockType->setEnabled(true);
137  break;
138  case BlockElse:
139  mAllMessageRBtn->hide();
140  mConditions->hide();
141  mAddBlockType->setEnabled(false);
142  mNewBlockType->setEnabled(false);
143  break;
144  default:
145  break;
146  }
147  }
148 }
149 
150 SieveScriptBlockWidget::MatchCondition SieveScriptBlockWidget::matchCondition() const
151 {
152  return mMatchCondition;
153 }
154 
155 void SieveScriptBlockWidget::slotRadioClicked(QAbstractButton *button)
156 {
157  if (button == mMatchAll) {
158  mMatchCondition = AndCondition;
159  } else if (button == mMatchAny) {
160  mMatchCondition = OrCondition;
161  } else {
162  mMatchCondition = AllCondition;
163  }
164  Q_EMIT valueChanged();
165  updateWidget();
166 }
167 
168 void SieveScriptBlockWidget::updateWidget()
169 {
170  mScriptConditionLister->setEnabled(mMatchCondition != AllCondition);
171  mNewBlockType->setEnabled(mMatchCondition != AllCondition);
172  mAddBlockType->setEnabled(mMatchCondition != AllCondition);
173 }
174 
175 void SieveScriptBlockWidget::generatedScript(QString &script, QStringList &required, bool inForEveryPartLoop)
176 {
177  QString indentation;
178  if (inForEveryPartLoop) {
179  indentation = AutoCreateScriptUtil::indentation();
180  }
181  bool onlyActions = false;
182  if (mMatchCondition == AllCondition) {
183  onlyActions = true;
184  //Just actions type
185  } else if (pageType() == BlockElse) {
186  script += QLatin1String("else {\n");
187  } else {
188  QString conditionStr;
189  int numberOfCondition = 0;
190  mScriptConditionLister->generatedScript(conditionStr, numberOfCondition, required, inForEveryPartLoop);
191  const bool hasUniqCondition = (numberOfCondition == 1);
192  QString filterStr;
193  QString blockStr;
194  switch (pageType()) {
195  case BlockIf:
196  blockStr = indentation + QStringLiteral("if ");
197  break;
198  case BlockElsIf:
199  blockStr = QStringLiteral("elsif ");
200  break;
201  case BlockElse:
202  break;
203  default:
204  //We can got here.
205  break;
206  }
207 
208  if (hasUniqCondition == 1) {
209  filterStr += blockStr;
210  } else if (mMatchCondition == AndCondition) {
211  filterStr += blockStr + QLatin1String("allof (");
212  } else if (mMatchCondition == OrCondition) {
213  filterStr += blockStr + QLatin1String("anyof (");
214  }
215 
216  if (conditionStr.isEmpty()) {
217  return;
218  } else {
219  script += filterStr + conditionStr;
220  }
221  if (hasUniqCondition) {
222  script += indentation + QLatin1String("{\n");
223  } else {
224  script += indentation + QStringLiteral(")\n%1{\n").arg(indentation);
225  }
226  }
227  mScriptActionLister->generatedScript(script, required, onlyActions, inForEveryPartLoop);
228  if (!onlyActions) {
229  script += indentation + QLatin1String("} ");
230  }
231 }
232 
233 void SieveScriptBlockWidget::updateCondition()
234 {
235  switch (mMatchCondition) {
236  case AndCondition:
237  mMatchAll->setChecked(true);
238  break;
239  case OrCondition:
240  mMatchAny->setChecked(true);
241  break;
242  case AllCondition:
243  mAllMessageRBtn->setChecked(true);
244  break;
245  }
246  updateWidget();
247 }
248 
249 void SieveScriptBlockWidget::loadLocalVariable(const SieveGlobalVariableActionWidget::VariableElement &var)
250 {
251  mScriptActionLister->loadLocalVariable(var);
252  mMatchCondition = AllCondition;
253  updateCondition();
254 }
255 
256 void SieveScriptBlockWidget::loadScript(QXmlStreamReader &element, bool onlyActions, QString &error)
257 {
258  if (onlyActions) {
259  mScriptActionLister->loadScript(element, true, error);
260  mMatchCondition = AllCondition;
261  updateCondition();
262  } else {
263  bool uniqueTest = false;
264  while (element.readNextStartElement()) {
265  const QStringRef tagName = element.name();
266  if (tagName == QLatin1String("test")) {
267  bool notCondition = false;
268  if (element.attributes().hasAttribute(QLatin1String("name"))) {
269  const QString typeCondition = element.attributes().value(QLatin1String("name")).toString();
270  if (typeCondition == QLatin1String("anyof")) {
271  mMatchCondition = OrCondition;
272  } else if (typeCondition == QLatin1String("allof")) {
273  mMatchAll->setChecked(true);
274  } else {
275  if (typeCondition == QLatin1String("not")) {
276  notCondition = true;
277  }
278  uniqueTest = true;
279  mMatchCondition = OrCondition;
280  }
281  updateCondition();
282  }
283  mScriptConditionLister->loadScript(element, uniqueTest, notCondition, error);
284  } else if (tagName == QLatin1String("block")) {
285  mScriptActionLister->loadScript(element, false, error);
286  } else {
287  if (tagName != QLatin1String("crlf")) {
288  qCDebug(LIBKSIEVE_LOG) << " e.tag" << tagName;
289  } else {
290  element.skipCurrentElement();
291  }
292  }
293  }
294  }
295 }
bool readNextStartElement()
void setContentsMargins(int left, int top, int right, int bottom)
void addButton(QAbstractButton *button, int id)
void buttonClicked(QAbstractButton *button)
QString toString() const const
QStringRef value(const QString &namespaceUri, const QString &name) const const
void setIcon(const QIcon &icon)
void skipCurrentElement()
void addWidget(QWidget *widget, int stretch, Qt::Alignment alignment)
void setLayout(QLayout *layout)
Type type(const QSqlDatabase &db)
bool isEmpty() const const
void clicked(bool checked)
bool hasAttribute(const QString &qualifiedName) const const
QString i18n(const char *text, const TYPE &arg...)
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
QXmlStreamAttributes attributes() const const
QIcon fromTheme(const QString &name)
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QStringRef name() const const
Q_EMITQ_EMIT
void addLayout(QLayout *layout, int stretch)
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Sun May 31 2020 22:46:48 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.