File indexing completed on 2024-05-05 17:18:50
0001 /*************************************************************************** 0002 * SPDX-FileCopyrightText: 2022 S. MANKOWSKI stephane@mankowski.fr 0003 * SPDX-FileCopyrightText: 2022 G. DE BURE support@mankowski.fr 0004 * SPDX-License-Identifier: GPL-3.0-or-later 0005 ***************************************************************************/ 0006 /** @file 0007 * This file is a query creator for skrooge 0008 * 0009 * @author Stephane MANKOWSKI / Guillaume DE BURE 0010 */ 0011 #include "skgpredicatcreator.h" 0012 0013 #include <qapplication.h> 0014 #include <qcheckbox.h> 0015 #include <qdom.h> 0016 #include <qlineedit.h> 0017 #include <qtablewidget.h> 0018 0019 #include "skgcalculatoredit.h" 0020 #include "skgcombobox.h" 0021 #include "skgdateedit.h" 0022 #include "skgdocument.h" 0023 #include "skgmainpanel.h" 0024 #include "skgruleobject.h" 0025 #include "skgservices.h" 0026 0027 SKGPredicatCreator::SKGPredicatCreator(QWidget* iParent, SKGDocument* document, const QString& attribute, bool iModeUpdate, const QStringList& iListAtt) 0028 : QWidget(iParent), m_updateMode(iModeUpdate), m_kValue1(nullptr), m_kValue2(nullptr), m_kAttributes(nullptr) 0029 { 0030 SKGServices::AttributeType attType = SKGServices::TEXT; 0031 if (document != nullptr) { 0032 attType = document->getAttributeType(attribute); 0033 } 0034 0035 // Build 0036 this->setAutoFillBackground(true); 0037 this->resize(491, 25); 0038 auto horizontalLayout = new QHBoxLayout(this); 0039 horizontalLayout->setSpacing(2); 0040 horizontalLayout->setMargin(0); 0041 horizontalLayout->setObjectName(QStringLiteral("horizontalLayout")); 0042 m_kOperator = new SKGComboBox(this); 0043 m_kOperator->setObjectName(QStringLiteral("kOperator")); 0044 m_kOperator->setSizeAdjustPolicy(KComboBox::AdjustToContentsOnFirstShow); 0045 QSizePolicy newSizePolicy2(QSizePolicy::Fixed, QSizePolicy::Fixed); 0046 newSizePolicy2.setHorizontalStretch(0); 0047 newSizePolicy2.setVerticalStretch(0); 0048 newSizePolicy2.setHeightForWidth(m_kOperator->sizePolicy().hasHeightForWidth()); 0049 m_kOperator->setSizePolicy(newSizePolicy2); 0050 0051 horizontalLayout->addWidget(m_kOperator); 0052 int nbAtt = iListAtt.count(); 0053 if (nbAtt != 0) { 0054 m_kAttributes = new SKGComboBox(this); 0055 if (m_kAttributes != nullptr) { 0056 m_kAttributes->setObjectName(QStringLiteral("kAttributes")); 0057 m_kAttributes->setMinimumSize(QSize(100, 0)); 0058 m_kAttributes->setEditable(false); 0059 QSizePolicy newSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); 0060 newSizePolicy.setHorizontalStretch(0); 0061 newSizePolicy.setVerticalStretch(0); 0062 newSizePolicy.setHeightForWidth(m_kAttributes->sizePolicy().hasHeightForWidth()); 0063 m_kAttributes->setSizePolicy(newSizePolicy); 0064 0065 horizontalLayout->addWidget(m_kAttributes); 0066 0067 for (const auto& att : qAsConst(iListAtt)) { 0068 if (document != nullptr) { 0069 m_kAttributes->addItem(document->getIcon(att), document->getDisplay(att), att); 0070 } 0071 } 0072 } 0073 } 0074 if (attType == SKGServices::TEXT) { 0075 auto cmbVal1 = new SKGComboBox(this); 0076 if (cmbVal1 != nullptr) { 0077 cmbVal1->setObjectName(QStringLiteral("cmbVal1")); 0078 cmbVal1->setMinimumSize(QSize(100, 0)); 0079 cmbVal1->setEditable(true); 0080 QSizePolicy newSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); 0081 newSizePolicy.setHorizontalStretch(0); 0082 newSizePolicy.setVerticalStretch(0); 0083 newSizePolicy.setHeightForWidth(cmbVal1->sizePolicy().hasHeightForWidth()); 0084 cmbVal1->setSizePolicy(newSizePolicy); 0085 cmbVal1->lineEdit()->setPlaceholderText(i18n("Value")); 0086 0087 horizontalLayout->addWidget(cmbVal1); 0088 m_kValue1 = cmbVal1; 0089 } 0090 auto cmbVal2 = new SKGComboBox(this); 0091 if (cmbVal2 != nullptr) { 0092 cmbVal2->setObjectName(QStringLiteral("cmbVal2")); 0093 cmbVal2->setMinimumSize(QSize(100, 0)); 0094 cmbVal2->setEditable(true); 0095 QSizePolicy newSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); 0096 newSizePolicy.setHorizontalStretch(0); 0097 newSizePolicy.setVerticalStretch(0); 0098 newSizePolicy.setHeightForWidth(cmbVal2->sizePolicy().hasHeightForWidth()); 0099 cmbVal2->setSizePolicy(newSizePolicy); 0100 cmbVal2->lineEdit()->setPlaceholderText(i18n("Value")); 0101 0102 horizontalLayout->addWidget(cmbVal2); 0103 m_kValue2 = cmbVal2; 0104 } 0105 0106 if (document != nullptr) { 0107 QString realTable = QStringLiteral("operation"); 0108 QString realAtt = attribute; 0109 QString realCond = QLatin1String(""); 0110 if (attribute == QStringLiteral("t_REALCATEGORY")) { 0111 realTable = QStringLiteral("category"); 0112 realAtt = QStringLiteral("t_fullname"); 0113 } else if (attribute == QStringLiteral("t_BANK")) { 0114 realTable = QStringLiteral("bank"); 0115 realAtt = QStringLiteral("t_name"); 0116 } else if (attribute == QStringLiteral("t_ACCOUNT") || attribute == QStringLiteral("t_TOACCOUNT")) { 0117 realTable = QStringLiteral("account"); 0118 realAtt = QStringLiteral("t_name"); 0119 } else if (attribute == QStringLiteral("t_UNIT")) { 0120 realTable = QStringLiteral("unit"); 0121 realAtt = QStringLiteral("t_name"); 0122 } else if (attribute == QStringLiteral("t_REALCOMMENT")) { 0123 realTable = QStringLiteral("suboperation"); 0124 realAtt = QStringLiteral("t_comment"); 0125 } else if (attribute == QStringLiteral("t_REALREFUND")) { 0126 realTable = QStringLiteral("refund"); 0127 realAtt = QStringLiteral("t_name"); 0128 } else if (attribute == QStringLiteral("t_PAYEE")) { 0129 realTable = QStringLiteral("payee"); 0130 realAtt = QStringLiteral("t_name"); 0131 } else if (attribute.startsWith(QLatin1String("p_"))) { 0132 realTable = QStringLiteral("parameters"); 0133 realAtt = QStringLiteral("t_value"); 0134 realCond = "t_name='" % attribute.right(attribute.length() - 2) % '\''; 0135 } 0136 SKGMainPanel::fillWithDistinctValue(QList<QWidget*>() << cmbVal1 << cmbVal2, document, realTable, realAtt, realCond); 0137 } 0138 } else if (attType == SKGServices::INTEGER || attType == SKGServices::FLOAT) { 0139 auto cmbVal1 = new SKGCalculatorEdit(this); 0140 if (cmbVal1 != nullptr) { 0141 cmbVal1->setObjectName(QStringLiteral("cmbVal1")); 0142 cmbVal1->setMode(SKGCalculatorEdit::EXPRESSION); 0143 cmbVal1->setMinimumSize(QSize(100, 0)); 0144 0145 horizontalLayout->addWidget(cmbVal1); 0146 m_kValue1 = cmbVal1; 0147 } 0148 auto cmbVal2 = new SKGCalculatorEdit(this); 0149 if (cmbVal2 != nullptr) { 0150 cmbVal2->setObjectName(QStringLiteral("cmbVal2")); 0151 cmbVal2->setMode(SKGCalculatorEdit::EXPRESSION); 0152 cmbVal2->setMinimumSize(QSize(100, 0)); 0153 0154 horizontalLayout->addWidget(cmbVal2); 0155 m_kValue2 = cmbVal2; 0156 } 0157 } else if (attType == SKGServices::DATE) { 0158 if (iModeUpdate) { 0159 auto cmbVal1 = new SKGComboBox(this); 0160 if (cmbVal1 != nullptr) { 0161 cmbVal1->setObjectName(QStringLiteral("cmbVal1")); 0162 cmbVal1->setMinimumSize(QSize(100, 0)); 0163 cmbVal1->setEditable(true); 0164 QSizePolicy newSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); 0165 newSizePolicy.setHorizontalStretch(0); 0166 newSizePolicy.setVerticalStretch(0); 0167 newSizePolicy.setHeightForWidth(cmbVal1->sizePolicy().hasHeightForWidth()); 0168 cmbVal1->setSizePolicy(newSizePolicy); 0169 cmbVal1->lineEdit()->setPlaceholderText(i18n("Value")); 0170 0171 horizontalLayout->addWidget(cmbVal1); 0172 m_kValue1 = cmbVal1; 0173 } 0174 0175 auto cmbVal2 = new SKGComboBox(this); 0176 if (cmbVal2 != nullptr) { 0177 cmbVal2->setObjectName(QStringLiteral("cmbVal2")); 0178 cmbVal2->setMinimumSize(QSize(100, 0)); 0179 cmbVal2->setEditable(false); 0180 QSizePolicy newSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); 0181 newSizePolicy.setHorizontalStretch(0); 0182 newSizePolicy.setVerticalStretch(0); 0183 newSizePolicy.setHeightForWidth(cmbVal2->sizePolicy().hasHeightForWidth()); 0184 cmbVal2->setSizePolicy(newSizePolicy); 0185 cmbVal2->addItems(QStringList() << QStringLiteral("YYYYMMDD") << QStringLiteral("MMDDYYYY") << QStringLiteral("DDMMYYYY") 0186 << QStringLiteral("MM-DD-YY") << QStringLiteral("DD-MM-YY") << QStringLiteral("MM-DD-YYYY") << QStringLiteral("DD-MM-YYYY") << QStringLiteral("YYYY-MM-DD")); 0187 horizontalLayout->addWidget(cmbVal2); 0188 m_kValue2 = cmbVal2; 0189 } 0190 } else { 0191 auto cmbVal1 = new SKGDateEdit(this); 0192 if (cmbVal1 != nullptr) { 0193 cmbVal1->setObjectName(QStringLiteral("cmbVal1")); 0194 cmbVal1->setMinimumSize(QSize(100, 0)); 0195 0196 horizontalLayout->addWidget(cmbVal1); 0197 m_kValue1 = cmbVal1; 0198 } 0199 0200 auto cmbVal2 = new SKGDateEdit(this); 0201 if (cmbVal2 != nullptr) { 0202 cmbVal2->setObjectName(QStringLiteral("cmbVal2")); 0203 cmbVal2->setMinimumSize(QSize(100, 0)); 0204 0205 horizontalLayout->addWidget(cmbVal2); 0206 m_kValue2 = cmbVal2; 0207 } 0208 } 0209 } else if (attType == SKGServices::BOOL || attType == SKGServices::TRISTATE) { 0210 auto cmbVal1 = new QCheckBox(this); 0211 if (cmbVal1 != nullptr) { 0212 cmbVal1->setObjectName(QStringLiteral("cmbVal1")); 0213 cmbVal1->setMinimumSize(QSize(100, 0)); 0214 cmbVal1->setTristate(attType == SKGServices::TRISTATE); 0215 0216 horizontalLayout->addWidget(cmbVal1); 0217 m_kValue1 = cmbVal1; 0218 } 0219 } 0220 0221 // Fill combo boxes 0222 m_kOperator->clear(); 0223 m_kOperator->addItem(QLatin1String(""), ""); 0224 0225 if (m_kValue1 != nullptr) { 0226 m_kValue1->installEventFilter(this); 0227 } 0228 if (m_kValue2 != nullptr) { 0229 m_kValue2->installEventFilter(this); 0230 } 0231 if (m_kOperator != nullptr) { 0232 m_kOperator->installEventFilter(this); 0233 } 0234 if (m_kAttributes != nullptr) { 0235 m_kAttributes->installEventFilter(this); 0236 } 0237 0238 QStringList listOps = SKGRuleObject::getListOfOperators(attType, m_updateMode ? SKGRuleObject::UPDATE : SKGRuleObject::SEARCH); 0239 int nb = listOps.count(); 0240 if (iModeUpdate && attribute == QStringLiteral("t_REALCATEGORY") && nb > 1) { 0241 nb = 1; // TODO(Stephane MANKOWSKI): unblock t_REALCATEGORY 0242 } 0243 for (int i = 0; i < nb; ++i) { 0244 const QString& op = listOps.at(i); 0245 QString nlsOp = SKGRuleObject::getDisplayForOperator(op, 0246 i18nc("Default value", "…"), 0247 i18nc("Default value", "…"), 0248 i18nc("Noun, an item's attribute", "attribute")); 0249 if (m_kOperator != nullptr) { 0250 m_kOperator->addItem(nlsOp, op); 0251 } 0252 } 0253 0254 connect(m_kOperator, static_cast<void (SKGComboBox::*)(const QString&)>(&SKGComboBox::currentTextChanged), this, &SKGPredicatCreator::onOperatorChanged); 0255 onOperatorChanged(); 0256 } 0257 0258 SKGPredicatCreator::~SKGPredicatCreator() 0259 { 0260 m_kOperator = nullptr; 0261 m_kValue1 = nullptr; 0262 m_kValue2 = nullptr; 0263 m_kAttributes = nullptr; 0264 } 0265 0266 bool SKGPredicatCreator::eventFilter(QObject* iObject, QEvent* iEvent) 0267 { 0268 Q_UNUSED(iObject) 0269 if ((iEvent != nullptr) && (iEvent->type() == QEvent::FocusIn || iEvent->type() == QEvent::FocusOut)) { 0270 QObject* appliFocus = QApplication::focusWidget(); 0271 0272 while (appliFocus != nullptr) { 0273 if (appliFocus == this) { 0274 break; 0275 } 0276 appliFocus = appliFocus->parent(); 0277 } 0278 if (appliFocus == nullptr) { 0279 Q_EMIT editingFinished(); 0280 } 0281 } 0282 return false; 0283 } 0284 0285 void SKGPredicatCreator::onOperatorChanged() 0286 { 0287 QString req; 0288 if (m_kOperator != nullptr) { 0289 req = m_kOperator->itemData(m_kOperator->currentIndex()).toString(); 0290 0291 m_kOperator->setToolTip(SKGRuleObject::getToolTipForOperator(req)); 0292 } 0293 if (m_kValue1 != nullptr) { 0294 m_kValue1->setVisible(req.contains(QStringLiteral("#V1S#")) || req.contains(QStringLiteral("#V1#"))); 0295 } 0296 if (m_kValue2 != nullptr) { 0297 m_kValue2->setVisible(req.contains(QStringLiteral("#V2S#")) || req.contains(QStringLiteral("#V2#")) || req.contains(QStringLiteral("#DF#"))); 0298 } 0299 if (m_kAttributes != nullptr) { 0300 m_kAttributes->setVisible(req.contains(QStringLiteral("#ATT2#"))); 0301 } 0302 } 0303 0304 QString SKGPredicatCreator::text() 0305 { 0306 return SKGPredicatCreator::getTextFromXml(xmlDescription()); 0307 } 0308 0309 QString SKGPredicatCreator::getTextFromXml(const QString& iXML) 0310 { 0311 QDomDocument doc(QStringLiteral("SKGML")); 0312 doc.setContent(iXML); 0313 QDomElement root = doc.documentElement(); 0314 QString output = SKGRuleObject::getDisplayForOperator(root.attribute(QStringLiteral("operator")), 0315 root.attribute(QStringLiteral("value")), 0316 root.attribute(QStringLiteral("value2")), 0317 root.attribute(QStringLiteral("att2s"))); 0318 return output; 0319 } 0320 0321 QString SKGPredicatCreator::xmlDescription() 0322 { 0323 QString output; 0324 if (m_kOperator != nullptr) { 0325 QString op = m_kOperator->itemData(m_kOperator->currentIndex()).toString(); 0326 if (!op.isEmpty()) { 0327 QDomDocument doc(QStringLiteral("SKGML")); 0328 QDomElement root = doc.createElement(QStringLiteral("element")); 0329 doc.appendChild(root); 0330 0331 // Condition 0332 root.setAttribute(QStringLiteral("operator"), op); 0333 if ((m_kValue1 != nullptr) && m_kValue1->isVisible()) { 0334 auto* cmbVal1 = qobject_cast<SKGDateEdit*> (m_kValue1); 0335 if (cmbVal1 != nullptr) { 0336 root.setAttribute(QStringLiteral("value"), SKGServices::dateToSqlString(cmbVal1->date())); 0337 } else { 0338 auto* cmbVal12 = qobject_cast<SKGCalculatorEdit*> (m_kValue1); 0339 if (cmbVal12 != nullptr) { 0340 root.setAttribute(QStringLiteral("value"), cmbVal12->text()); 0341 } else { 0342 auto* cmbVal13 = qobject_cast<QCheckBox*> (m_kValue1); 0343 if (cmbVal13 != nullptr) { 0344 root.setAttribute(QStringLiteral("value"), cmbVal13->checkState() == Qt::Checked ? QStringLiteral("Y") : cmbVal13->checkState() == Qt::Unchecked ? QStringLiteral("N") : QStringLiteral("P")); 0345 } else { 0346 auto* cmbVal14 = qobject_cast<SKGComboBox*> (m_kValue1); 0347 if (cmbVal14 != nullptr) { 0348 root.setAttribute(QStringLiteral("value"), cmbVal14->text()); 0349 } 0350 } 0351 } 0352 } 0353 } 0354 if ((m_kValue2 != nullptr) && m_kValue2->isVisible()) { 0355 auto* cmbVal2 = qobject_cast<SKGDateEdit*> (m_kValue2); 0356 if (cmbVal2 != nullptr) { 0357 root.setAttribute(QStringLiteral("value2"), SKGServices::dateToSqlString(cmbVal2->date())); 0358 } else { 0359 auto* cmbVal21 = qobject_cast<SKGCalculatorEdit*> (m_kValue2); 0360 if (cmbVal21 != nullptr) { 0361 root.setAttribute(QStringLiteral("value2"), cmbVal21->text()); 0362 } else { 0363 auto* cmbVal22 = qobject_cast<SKGComboBox*> (m_kValue2); 0364 if (cmbVal22 != nullptr) { 0365 root.setAttribute(QStringLiteral("value2"), cmbVal22->text()); 0366 } 0367 } 0368 } 0369 } 0370 0371 if ((m_kAttributes != nullptr) && m_kAttributes->isVisible()) { 0372 root.setAttribute(QStringLiteral("att2"), m_kAttributes->itemData(m_kAttributes->currentIndex()).toString()); 0373 root.setAttribute(QStringLiteral("att2s"), m_kAttributes->text()); 0374 } 0375 0376 output = doc.toString(); 0377 } 0378 } 0379 return output; 0380 } 0381 0382 void SKGPredicatCreator::setXmlDescription(const QString& iXML) 0383 { 0384 QDomDocument doc(QStringLiteral("SKGML")); 0385 doc.setContent(iXML); 0386 QDomElement root = doc.documentElement(); 0387 0388 // Condition 0389 if (m_kOperator != nullptr) { 0390 m_kOperator->setCurrentIndex(m_kOperator->findData(root.attribute(QStringLiteral("operator")))); 0391 auto* cmbVal1 = qobject_cast<SKGDateEdit*> (m_kValue1); 0392 if (cmbVal1 != nullptr) { 0393 cmbVal1->setDate(SKGServices::stringToTime(root.attribute(QStringLiteral("value"))).date()); 0394 } else { 0395 auto* cmbVal12 = qobject_cast<SKGCalculatorEdit*> (m_kValue1); 0396 if (cmbVal12 != nullptr) { 0397 cmbVal12->setText(root.attribute(QStringLiteral("value"))); 0398 } else { 0399 auto* cmbVal13 = qobject_cast<QCheckBox*> (m_kValue1); 0400 if (cmbVal13 != nullptr) { 0401 cmbVal13->setCheckState(root.attribute(QStringLiteral("value")) == QStringLiteral("Y") ? Qt::Checked : root.attribute(QStringLiteral("value")) == QStringLiteral("P") ? Qt::PartiallyChecked : Qt::Unchecked); 0402 } else { 0403 auto* cmbVal14 = qobject_cast<SKGComboBox*> (m_kValue1); 0404 if (cmbVal14 != nullptr) { 0405 cmbVal14->setText(root.attribute(QStringLiteral("value"))); 0406 } 0407 } 0408 } 0409 } 0410 0411 auto* cmbVal2 = qobject_cast<SKGDateEdit*> (m_kValue2); 0412 if (cmbVal2 != nullptr) { 0413 cmbVal2->setDate(SKGServices::stringToTime(root.attribute(QStringLiteral("value2"))).date()); 0414 } else { 0415 auto* cmbVal22 = qobject_cast<SKGCalculatorEdit*> (m_kValue2); 0416 if (cmbVal22 != nullptr) { 0417 cmbVal22->setText(root.attribute(QStringLiteral("value2"))); 0418 } else { 0419 auto* cmbVal23 = qobject_cast<SKGComboBox*> (m_kValue2); 0420 if (cmbVal23 != nullptr) { 0421 cmbVal23->setText(root.attribute(QStringLiteral("value2"))); 0422 } 0423 } 0424 } 0425 0426 if (m_kAttributes != nullptr) { 0427 m_kAttributes->setCurrentIndex(m_kAttributes->findData(root.attribute(QStringLiteral("att2")))); 0428 } 0429 } 0430 0431 emit xmlDescriptionChanged(); 0432 } 0433 0434 0435