Warning, file /education/analitza/analitzagui/operatorsmodel.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /************************************************************************************* 0002 * Copyright (C) 2007-2008 by Aleix Pol <aleixpol@kde.org> * 0003 * * 0004 * This program is free software; you can redistribute it and/or * 0005 * modify it under the terms of the GNU General Public License * 0006 * as published by the Free Software Foundation; either version 2 * 0007 * of the License, or (at your option) any later version. * 0008 * * 0009 * This program is distributed in the hope that it will be useful, * 0010 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0012 * GNU General Public License for more details. * 0013 * * 0014 * You should have received a copy of the GNU General Public License * 0015 * along with this program; if not, write to the Free Software * 0016 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 0017 *************************************************************************************/ 0018 0019 #include "operatorsmodel.h" 0020 #include <analitza/operator.h> 0021 #include <analitza/variables.h> 0022 #include <QFont> 0023 #include <QCoreApplication> 0024 0025 using Analitza::Operator; 0026 0027 OperatorsModel::OperatorsModel(QObject *parent) : QAbstractTableModel(parent), m_vars(nullptr) 0028 { 0029 } 0030 0031 QHash<int, QByteArray> OperatorsModel::roleNames() const 0032 { 0033 auto ret = QAbstractTableModel::roleNames(); 0034 ret.insert(IsVariableRole, "isVariable"); 0035 ret.insert(DescriptionRole, "description"); 0036 return ret; 0037 } 0038 0039 QVariant OperatorsModel::data(const QModelIndex & index, int role) const 0040 { 0041 QVariant ret; 0042 if(role==Qt::DisplayRole) { 0043 if(index.row()<Analitza::Operator::nOfOps-2) { 0044 Analitza::Operator oper((Analitza::Operator::OperatorType) (index.row()+1)); 0045 0046 switch(index.column()) { 0047 case 0: 0048 ret=oper.toString(); 0049 break; 0050 case 1: 0051 ret=description(oper); 0052 break; 0053 case 2: 0054 ret=sample(oper); 0055 break; 0056 case 3: 0057 ret=example(oper); 0058 break; 0059 } 0060 } else if(m_vars) { 0061 int var=index.row()-Analitza::Operator::nOfOps+2; 0062 QString key=m_vars->keys()[var]; 0063 switch(index.column()) { 0064 case 0: 0065 ret=key; 0066 break; 0067 case 1: 0068 ret=m_vars->value(key)->toString(); 0069 break; 0070 } 0071 } 0072 } else if(role==Qt::FontRole && index.column()==1) { 0073 QFont f; 0074 f.setItalic(true); 0075 ret=f; 0076 } else if(role==DescriptionRole && index.column()==0) { 0077 Analitza::Operator oper((Analitza::Operator::OperatorType) (index.row()+1)); 0078 switch(index.column()) { 0079 case 0: 0080 ret=description(oper); 0081 break; 0082 } 0083 } else if(role==IsVariableRole && index.column()==0) { 0084 ret=index.row()<Analitza::Operator::nOfOps-2; 0085 } 0086 return ret; 0087 } 0088 0089 QVariant OperatorsModel::headerData(int section, Qt::Orientation orientation, int role) const 0090 { 0091 QVariant ret; 0092 if(role==Qt::DisplayRole && orientation==Qt::Horizontal) { 0093 switch(section) { 0094 case 0: 0095 ret=QCoreApplication::translate("@title:column", "Name"); 0096 break; 0097 case 1: 0098 ret=QCoreApplication::translate("@title:column", "Description"); 0099 break; 0100 case 2: 0101 ret=QCoreApplication::translate("@title:column", "Parameters"); 0102 break; 0103 case 3: 0104 ret=QCoreApplication::translate("@title:column", "Example"); 0105 break; 0106 } 0107 } 0108 return ret; 0109 } 0110 0111 int OperatorsModel::rowCount(const QModelIndex &) const 0112 { 0113 int count=Analitza::Operator::nOfOps; 0114 if(m_vars) 0115 count+=m_vars->count(); 0116 return count-2; 0117 } 0118 0119 int OperatorsModel::columnCount(const QModelIndex &) const 0120 { 0121 return 4; 0122 } 0123 0124 void OperatorsModel::updateInformation() 0125 { 0126 beginResetModel(); 0127 endResetModel(); 0128 } 0129 0130 QString OperatorsModel::sample(const Analitza::Operator& oper) 0131 { 0132 QString funcname=oper.toString(); 0133 QString bounds; 0134 if(oper.isBounded()) { 0135 bounds=QCoreApplication::translate("Syntax for function bounding", " : var"); 0136 if(oper.operatorType()==Operator::sum || oper.operatorType()==Operator::product) 0137 bounds += QCoreApplication::translate("Syntax for function bounding values", "=from..to"); 0138 } 0139 0140 QString sample = QCoreApplication::tr("%1(").arg(funcname); 0141 0142 if(oper.nparams()<0) { 0143 return QCoreApplication::tr("%1... parameters, ...%2)").arg(sample, bounds); 0144 } else { 0145 for(int i=0; i<oper.nparams(); ++i) { 0146 sample += QCoreApplication::tr("par%1").arg(i+1); 0147 if(i<oper.nparams()-1) 0148 sample += QLatin1String(", "); 0149 } 0150 return sample+bounds+')'; 0151 } 0152 } 0153 0154 QString OperatorsModel::description(const Analitza::Operator& o) 0155 { 0156 QString s; 0157 switch(o.operatorType()) { 0158 case Operator::plus: 0159 s = QCoreApplication::tr("Addition"); 0160 break; 0161 case Operator::times: 0162 s = QCoreApplication::tr("Multiplication"); 0163 break; 0164 case Operator::divide: 0165 s = QCoreApplication::tr("Division"); 0166 break; 0167 case Operator::minus: 0168 s = QCoreApplication::tr("Subtraction. Will remove all values from the first one."); 0169 break; 0170 case Operator::power: 0171 s = QCoreApplication::tr("Power"); 0172 break; 0173 case Operator::rem: 0174 s = QCoreApplication::tr("Remainder"); 0175 break; 0176 case Operator::quotient: 0177 s = QCoreApplication::tr("Quotient"); 0178 break; 0179 case Operator::factorof: 0180 s = QCoreApplication::tr("The factor of"); 0181 break; 0182 case Operator::factorial: 0183 s = QCoreApplication::tr("Factorial. factorial(n)=n!"); 0184 break; 0185 case Operator::sin: 0186 s = QCoreApplication::tr("Function to calculate the sine of a given angle"); 0187 break; 0188 case Operator::cos: 0189 s = QCoreApplication::tr("Function to calculate the cosine of a given angle"); 0190 break; 0191 case Operator::tan: 0192 s = QCoreApplication::tr("Function to calculate the tangent of a given angle"); 0193 break; 0194 case Operator::sec: 0195 s = QCoreApplication::tr("Secant"); 0196 break; 0197 case Operator::csc: 0198 s = QCoreApplication::tr("Cosecant"); 0199 break; 0200 case Operator::cot: 0201 s = QCoreApplication::tr("Cotangent"); 0202 break; 0203 case Operator::sinh: 0204 s = QCoreApplication::tr("Hyperbolic sine"); 0205 break; 0206 case Operator::cosh: 0207 s = QCoreApplication::tr("Hyperbolic cosine"); 0208 break; 0209 case Operator::tanh: 0210 s = QCoreApplication::tr("Hyperbolic tangent"); 0211 break; 0212 case Operator::sech: 0213 s = QCoreApplication::tr("Hyperbolic secant"); 0214 break; 0215 case Operator::csch: 0216 s = QCoreApplication::tr("Hyperbolic cosecant"); 0217 break; 0218 case Operator::coth: 0219 s = QCoreApplication::tr("Hyperbolic cotangent"); 0220 break; 0221 case Operator::arcsin: 0222 s = QCoreApplication::tr("Arc sine"); 0223 break; 0224 case Operator::arccos: 0225 s = QCoreApplication::tr("Arc cosine"); 0226 break; 0227 case Operator::arctan: 0228 s = QCoreApplication::tr("Arc tangent"); 0229 break; 0230 case Operator::arccot: 0231 s = QCoreApplication::tr("Arc cotangent"); 0232 break; 0233 // case Operator::arccoth: 0234 // s = QCoreApplication::tr("Hyperbolic arc cotangent"); 0235 // break; 0236 case Operator::arctanh: 0237 s = QCoreApplication::tr("Hyperbolic arc tangent"); 0238 break; 0239 case Operator::sum: 0240 s = QCoreApplication::tr("Summatory"); 0241 break; 0242 case Operator::product: 0243 s = QCoreApplication::tr("Productory"); 0244 break; 0245 case Operator::forall: 0246 s = QCoreApplication::tr("For all"); 0247 break; 0248 case Operator::exists: 0249 s = QCoreApplication::tr("Exists"); 0250 break; 0251 case Operator::diff: 0252 s = QCoreApplication::tr("Differentiation"); 0253 break; 0254 case Operator::arcsinh: 0255 s = QCoreApplication::tr("Hyperbolic arc sine"); 0256 break; 0257 case Operator::arccosh: 0258 s = QCoreApplication::tr("Hyperbolic arc cosine"); 0259 break; 0260 case Operator::arccsc: 0261 s = QCoreApplication::tr("Arc cosecant"); 0262 break; 0263 case Operator::arccsch: 0264 s = QCoreApplication::tr("Hyperbolic arc cosecant"); 0265 break; 0266 case Operator::arcsec: 0267 s = QCoreApplication::tr("Arc secant"); 0268 break; 0269 case Operator::arcsech: 0270 s = QCoreApplication::tr("Hyperbolic arc secant"); 0271 break; 0272 case Operator::exp: 0273 s = QCoreApplication::tr("Exponent (e^x)"); 0274 break; 0275 case Operator::ln: 0276 s = QCoreApplication::tr("Base-e logarithm"); 0277 break; 0278 case Operator::log: 0279 s = QCoreApplication::tr("Base-10 logarithm"); 0280 break; 0281 case Operator::abs: 0282 s = QCoreApplication::tr("Absolute value. abs(n)=|n|"); 0283 break; 0284 case Operator::conjugate: 0285 s = QCoreApplication::tr("Conjugate"); 0286 break; 0287 case Operator::arg: 0288 s = QCoreApplication::tr("Arg"); 0289 break; 0290 case Operator::real: 0291 s = QCoreApplication::tr("Real"); 0292 break; 0293 case Operator::imaginary: 0294 s = QCoreApplication::tr("Imaginary"); 0295 break; 0296 case Operator::floor: 0297 s = QCoreApplication::tr("Floor value. floor(n)=⌊n⌋"); 0298 break; 0299 case Operator::ceiling: 0300 s = QCoreApplication::tr("Ceil value. ceil(n)=⌈n⌉"); 0301 break; 0302 case Operator::min: 0303 s = QCoreApplication::tr("Minimum"); 0304 break; 0305 case Operator::max: 0306 s = QCoreApplication::tr("Maximum"); 0307 break; 0308 case Operator::gt: 0309 s = QCoreApplication::tr("Greater than. gt(a,b)=a>b"); 0310 break; 0311 case Operator::lt: 0312 s = QCoreApplication::tr("Less than. lt(a,b)=a<b"); 0313 break; 0314 case Operator::eq: 0315 s = QCoreApplication::tr("Equal. eq(a,b) = a=b"); 0316 break; 0317 case Operator::approx: 0318 s = QCoreApplication::tr("Approximation. approx(a)=a±n"); 0319 break; 0320 case Operator::neq: 0321 s = QCoreApplication::tr("Not equal. neq(a,b)=a≠b"); 0322 break; 0323 case Operator::geq: 0324 s = QCoreApplication::tr("Greater or equal. geq(a,b)=a≥b"); 0325 break; 0326 case Operator::leq: 0327 s = QCoreApplication::tr("Less or equal. leq(a,b)=a≤b"); 0328 break; 0329 case Operator::_and: 0330 s = QCoreApplication::tr("Boolean and"); 0331 break; 0332 case Operator::_not: 0333 s = QCoreApplication::tr("Boolean not"); 0334 break; 0335 case Operator::_or: 0336 s = QCoreApplication::tr("Boolean or"); 0337 break; 0338 case Operator::_xor: 0339 s = QCoreApplication::tr("Boolean xor"); 0340 break; 0341 case Operator::implies: 0342 s = QCoreApplication::tr("Boolean implication"); 0343 break; 0344 case Operator::gcd: 0345 s = QCoreApplication::tr("Greatest common divisor"); 0346 break; 0347 case Operator::lcm: 0348 s = QCoreApplication::tr("Least common multiple"); 0349 break; 0350 case Operator::root: 0351 s = QCoreApplication::tr("Root"); 0352 break; 0353 case Operator::card: 0354 s = QCoreApplication::tr("Cardinal"); 0355 break; 0356 case Operator::scalarproduct: 0357 s = QCoreApplication::tr("Scalar product"); 0358 break; 0359 case Operator::selector: 0360 s = QCoreApplication::tr("Select the par1-th element of par2 list or vector"); 0361 break; 0362 case Operator::_union: 0363 s = QCoreApplication::tr("Joins several items of the same type"); 0364 break; 0365 case Operator::map: 0366 s = QCoreApplication::tr("Applies a function to every element in a list"); 0367 break; 0368 case Operator::filter: 0369 s = QCoreApplication::tr("Removes all elements that don't fit a condition"); 0370 break; 0371 case Operator::transpose: 0372 s = QCoreApplication::tr("Transpose"); 0373 break; 0374 case Operator::function: 0375 case Operator::nOfOps: 0376 case Operator::none: 0377 break; 0378 } 0379 return s; 0380 } 0381 0382 QString OperatorsModel::example(const Analitza::Operator& o) 0383 { 0384 QString s; 0385 0386 switch(o.operatorType()) { 0387 case Operator::plus: 0388 s=QStringLiteral("x+2"); 0389 break; 0390 case Operator::times: 0391 s=QStringLiteral("x*2"); 0392 break; 0393 case Operator::divide: 0394 s=QStringLiteral("x/2"); 0395 break; 0396 case Operator::minus: 0397 s=QStringLiteral("x-2"); 0398 break; 0399 case Operator::power: 0400 s=QStringLiteral("x^2"); 0401 break; 0402 case Operator::rem: 0403 s=QStringLiteral("rem(x, 5)"); 0404 break; 0405 case Operator::quotient: 0406 s=QStringLiteral("quotient(x, 2)"); 0407 break; 0408 case Operator::factorof: 0409 s=QStringLiteral("factorof(x, 3)"); 0410 break; 0411 case Operator::min: 0412 s=QStringLiteral("min(x, 4)"); 0413 break; 0414 case Operator::max: 0415 s=QStringLiteral("max(x, 4)"); 0416 break; 0417 case Operator::gt: 0418 s=QStringLiteral("piecewise { x>4 ? 1, ? 0 }"); 0419 break; 0420 case Operator::lt: 0421 s=QStringLiteral("piecewise { x<4 ? 1, ? 0 }"); 0422 break; 0423 case Operator::eq: 0424 s=QStringLiteral("piecewise { x=4 ? 1, ? 0 }"); 0425 break; 0426 case Operator::approx: 0427 s=QStringLiteral("piecewise { approx(x, 4) ? 1, ? 0 }"); 0428 break; 0429 case Operator::neq: 0430 s=QStringLiteral("piecewise { x!=4 ? 1, ? 0 }"); 0431 break; 0432 case Operator::geq: 0433 s=QStringLiteral("piecewise { x>=4 ? 1, ? 0 }"); 0434 break; 0435 case Operator::leq: 0436 s=QStringLiteral("piecewise { x<=4 ? 1, ? 0 }"); 0437 break; 0438 case Operator::_and: 0439 s=QStringLiteral("piecewise { and(x>-2, x<2) ? 1, ? 0 }"); 0440 break; 0441 case Operator::_or: 0442 s=QStringLiteral("piecewise { or(x>2, x>-2) ? 1, ? 0 }"); 0443 break; 0444 case Operator::_xor: 0445 s=QStringLiteral("piecewise { xor(x>0, x<3) ? 1, ? 0 }"); 0446 break; 0447 case Operator::implies: 0448 s=QStringLiteral("piecewise { implies(x<0, x<3) ? 1, ? 0 }"); 0449 break; 0450 case Operator::forall: 0451 s=QStringLiteral("piecewise { forall(t:t@list { true, false, false }) ? 1, ? 0 }"); 0452 break; 0453 case Operator::exists: 0454 s=QStringLiteral("piecewise { exists(t:t@list { true, false, false }) ? 1, ? 0 }"); 0455 break; 0456 case Operator::_not: 0457 s=QStringLiteral("piecewise { not(x>0) ? 1, ? 0 }"); 0458 break; 0459 case Operator::gcd: 0460 s=QStringLiteral("gcd(x, 3)"); 0461 break; 0462 case Operator::lcm: 0463 s=QStringLiteral("lcm(x, 4)"); 0464 break; 0465 case Operator::root: 0466 s=QStringLiteral("root(x, 2)"); 0467 break; 0468 case Operator::selector: 0469 s=QStringLiteral("scalarproduct(vector { 0, x }, vector { x, 0 })[1]"); 0470 break; 0471 case Operator::sum: 0472 s=QStringLiteral("x*sum(t*t:t=0..3)"); 0473 break; 0474 case Operator::product: 0475 s=QStringLiteral("product(t+t:t=1..3)"); 0476 break; 0477 case Operator::card: 0478 s=QStringLiteral("card(vector { x, 1, 2 })"); 0479 break; 0480 case Operator::scalarproduct: 0481 s=QStringLiteral("scalarproduct(vector { 0, x }, vector { x, 0 })[1]"); 0482 break; 0483 case Operator::diff: 0484 s=QStringLiteral("(diff(x^2:x))(x)"); 0485 break; 0486 case Operator::_union: 0487 s=QStringLiteral("union(list { 1, 2, 3 }, list { 4, 5, 6 })[rem(floor(x), 5)+3]"); 0488 break; 0489 case Operator::map: 0490 s=QStringLiteral("map(x->x+x, list { 1, 2, 3, 4, 5, 6 })[rem(floor(x), 5)+3]"); 0491 break; 0492 case Operator::filter: 0493 s=QStringLiteral("filter(u->rem(u, 2)=0, list { 2, 4, 3, 4, 8, 6 })[rem(floor(x), 5)+3]"); 0494 break; 0495 case Operator::transpose: 0496 s = QStringLiteral("transpose(matrix { matrixrow { 1, 2, 3, 4, 5, 6 } })[rem(floor(x), 5)+3][1]"); 0497 break; 0498 case Operator::real: 0499 s = QStringLiteral("real(x*i)"); 0500 break; 0501 case Operator::conjugate: 0502 s = QStringLiteral("conjugate(x*i)"); 0503 break; 0504 case Operator::arg: 0505 s = QStringLiteral("arg(x*i)"); 0506 break; 0507 case Operator::imaginary: 0508 s = QStringLiteral("imaginary(x*i)"); 0509 break; 0510 case Operator::factorial: 0511 case Operator::arcsech: 0512 case Operator::arcsec: 0513 case Operator::arccsch: 0514 case Operator::arccsc: 0515 // case Operator::arccoth: 0516 case Operator::sin: 0517 case Operator::cos: 0518 case Operator::tan: 0519 case Operator::sec: 0520 case Operator::csc: 0521 case Operator::cot: 0522 case Operator::sinh: 0523 case Operator::cosh: 0524 case Operator::tanh: 0525 case Operator::sech: 0526 case Operator::csch: 0527 case Operator::coth: 0528 case Operator::arcsin: 0529 case Operator::arccos: 0530 case Operator::arctan: 0531 case Operator::arccot: 0532 case Operator::arcsinh: 0533 case Operator::arccosh: 0534 // case Operator::arccsc: 0535 // case Operator::arccsch: 0536 // case Operator::arcsec: 0537 // case Operator::arcsech: 0538 case Operator::arctanh: 0539 case Operator::exp: 0540 case Operator::ln: 0541 case Operator::log: 0542 case Operator::abs: 0543 case Operator::floor: 0544 case Operator::ceiling: 0545 s=QStringLiteral("%1(x)").arg(o.toString()); 0546 break; 0547 case Operator::nOfOps: 0548 case Operator::none: 0549 case Operator::function: 0550 break; 0551 } 0552 return "x->"+s; 0553 } 0554 0555 QModelIndex OperatorsModel::indexForOperatorName(const QString& id) const 0556 { 0557 Operator::OperatorType opt=Analitza::Operator::toOperatorType(id); 0558 if(opt==Operator::none) 0559 return QModelIndex(); 0560 else 0561 return index(opt-1, 0); 0562 } 0563 0564 QString OperatorsModel::parameterHelp(const QModelIndex& index, int param, bool inbounds) const 0565 { 0566 Q_ASSERT(index.isValid()); 0567 QString ret; 0568 Analitza::Operator oper((Analitza::Operator::OperatorType) (index.row()+1)); 0569 QString funcname = oper.toString(); 0570 const int op=oper.nparams(); 0571 if(op == -1) { 0572 ret=QCoreApplication::translate("n-ary function prototype", "<em>%1</em>(..., <b>par%2</b>, ...)").arg(funcname).arg(param+1); 0573 } else { 0574 ret=standardFunctionCallHelp(funcname, param, op, inbounds, oper.isBounded()); 0575 } 0576 return ret; 0577 } 0578 0579 QString OperatorsModel::standardFunctionCallHelp(const QString& funcname, int param, int paramcount, bool inbounds, bool isbounded) 0580 { 0581 QString sample = (param < paramcount || (inbounds && isbounded)) ? 0582 QCoreApplication::translate("Function name in function prototype", "<em>%1</em>(").arg(funcname) : 0583 QCoreApplication::translate("Uncorrect function name in function prototype", "<em style='color:red'><b>%1</b></em>(").arg(funcname); 0584 0585 for(int i=0; i<paramcount; ++i) { 0586 QString current=QCoreApplication::translate("Parameter in function prototype", "par%1").arg(i+1); 0587 0588 if(i==param) 0589 current=QCoreApplication::translate("Current parameter in function prototype", "<b>%1</b>").arg(current); 0590 sample += current; 0591 if(i<paramcount-1) 0592 sample += QCoreApplication::translate("Function parameter separator", ", "); 0593 } 0594 0595 if(isbounded) { 0596 static QString bounds=QCoreApplication::translate("Current parameter is the bounding", " : bounds"); 0597 QString p=bounds; 0598 if(inbounds) 0599 p=QCoreApplication::translate("Current parameter in function prototype", "<b>%1</b>").arg(p); 0600 sample += p; 0601 } 0602 0603 return sample+')'; 0604 0605 } 0606 0607 QString OperatorsModel::lastWord(int pos, const QString& exp) 0608 { 0609 int act=pos-1; 0610 for(; act>=0 && exp[act].isLetter(); act--) {} 0611 0612 return exp.mid(act+1, pos-act-1); 0613 } 0614 0615 /*QString OperatorsModel::operToString(const Operator& op) const 0616 { 0617 QStandardItem *it; 0618 0619 for(int i=0; i<KEYWORDNUM; i++) { 0620 it=item(i,2); 0621 if(it!=NULL && it->data(Qt::EditRole).toInt()==op.operatorType()) { 0622 return item(i,0)->data(Qt::EditRole).toString(); 0623 } 0624 } 0625 return QString(); 0626 }*/ 0627 0628