~ubuntu-branches/ubuntu/oneiric/kalgebra/oneiric-proposed

1 by Philip Muškovac
Import upstream version 4.6.90+repack1
1
/*************************************************************************************
2
 *  Copyright (C) 2007-2008 by Aleix Pol <aleixpol@kde.org>                          *
3
 *                                                                                   *
4
 *  This program is free software; you can redistribute it and/or                    *
5
 *  modify it under the terms of the GNU General Public License                      *
6
 *  as published by the Free Software Foundation; either version 2                   *
7
 *  of the License, or (at your option) any later version.                           *
8
 *                                                                                   *
9
 *  This program 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                    *
12
 *  GNU General Public License for more details.                                     *
13
 *                                                                                   *
14
 *  You should have received a copy of the GNU General Public License                *
15
 *  along with this program; if not, write to the Free Software                      *
16
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA   *
17
 *************************************************************************************/
18
19
#include "operatorsmodel.h"
20
#include <analitza/operator.h>
21
#include <analitza/variables.h>
22
#include <KLocale>
23
#include <KApplication>
24
#include <QFont>
25
26
using Analitza::Operator;
27
28
OperatorsModel::OperatorsModel(QObject *parent) : QAbstractTableModel(parent), m_vars(0)
29
{
30
}
31
32
QVariant OperatorsModel::data(const QModelIndex & index, int role) const
33
{
34
	QVariant ret;
35
	if(role==Qt::DisplayRole) {
36
		if(index.row()<Analitza::Operator::nOfOps-2) {
37
			Analitza::Operator oper((Analitza::Operator::OperatorType) (index.row()+1));
38
			
39
			switch(index.column()) {
40
				case 0:
41
					ret=oper.toString();
42
					break;
43
				case 1:
44
					ret=description(oper);
45
					break;
46
				case 2:
47
					ret=sample(oper);
48
					break;
49
				case 3:
50
					ret=example(oper);
51
					break;
52
			}
53
		} else if(m_vars) {
54
			int var=index.row()-Analitza::Operator::nOfOps+2;
55
			QString key=m_vars->keys()[var];
56
			switch(index.column()) {
57
				case 0:
58
					ret=key;
59
					break;
60
				case 1:
61
					ret=m_vars->value(key)->toString();
62
					break;
63
			}
64
		}
65
	} else if(role==Qt::FontRole && index.column()==1) {
66
		QFont f = KApplication::font();
67
		f.setItalic(true);
68
		ret=f;
69
	}
70
	return ret;
71
}
72
73
QVariant OperatorsModel::headerData(int section, Qt::Orientation orientation, int role) const
74
{
75
	QVariant ret;
76
	if(role==Qt::DisplayRole && orientation==Qt::Horizontal) {
77
		switch(section) {
78
			case 0:
79
				ret=i18nc("@title:column", "Name");
80
				break;
81
			case 1:
82
				ret=i18nc("@title:column", "Description");
83
				break;
84
			case 2:
85
				ret=i18nc("@title:column", "Parameters");
86
				break;
87
			case 3:
88
				ret=i18nc("@title:column", "Example");
89
				break;
90
		}
91
	}
92
	return ret;
93
}
94
95
int OperatorsModel::rowCount(const QModelIndex &) const
96
{
97
	int count=Analitza::Operator::nOfOps;
98
	if(m_vars)
99
		count+=m_vars->count();
100
	return count-2;
101
}
102
103
int OperatorsModel::columnCount(const QModelIndex &) const
104
{
105
	return 4;
106
}
107
108
void OperatorsModel::updateInformation()
109
{
110
	reset();
111
}
112
113
QString OperatorsModel::sample(const Analitza::Operator& oper)
114
{
115
	QString funcname=oper.toString();
116
	QString bounds;
117
	if(oper.isBounded()) {
118
		bounds=i18nc("Syntax for function bounding", " : var");
119
		if(oper.operatorType()==Operator::sum || oper.operatorType()==Operator::product)
120
			bounds += i18nc("Syntax for function bounding values", "=from..to");
121
	}
122
	
123
	QString sample = i18n("%1(", funcname);
124
	
125
	if(oper.nparams()<0) {
126
		return i18n("%1... parameters, ...%2)", sample, bounds);
127
	} else {
128
		for(int i=0; i<oper.nparams(); ++i) {
129
			sample += i18n("par%1", i+1);
130
			if(i<oper.nparams()-1)
131
				sample += ", ";
132
		}
133
		return sample+bounds+')';
134
	}
135
}
136
137
QString OperatorsModel::description(const Analitza::Operator& o)
138
{
139
	QString s;
140
	switch(o.operatorType()) {
141
		case Operator::plus:
142
			s = i18n("Addition");
143
			break;
144
		case Operator::times:
145
			s = i18n("Multiplication");
146
			break;
147
		case Operator::divide:
148
			s = i18n("Division");
149
			break;
150
		case Operator::minus:
151
			s = i18n("Subtraction. Will remove all values from the first one.");
152
			break;
153
		case Operator::power:
154
			s = i18n("Power");
155
			break;
156
		case Operator::rem:
157
			s = i18n("Remainder");
158
			break;
159
		case Operator::quotient:
160
			s = i18n("Quotient");
161
			break;
162
		case Operator::factorof:
163
			s = i18n("The factor of");
164
			break;
165
		case Operator::factorial:
166
			s = i18n("Factorial. factorial(n)=n!");
167
			break;
168
		case Operator::sin:
169
			s = i18n("Function to calculate the sine of a given angle");
170
			break;
171
		case Operator::cos:
172
			s = i18n("Function to calculate the cosine of a given angle");
173
			break;
174
		case Operator::tan:
175
			s = i18n("Function to calculate the tangent of a given angle");
176
			break;
177
		case Operator::sec:
178
			s = i18n("Secant");
179
			break;
180
		case Operator::csc:
181
			s = i18n("Cosecant");
182
			break;
183
		case Operator::cot:
184
			s = i18n("Cotangent");
185
			break;
186
		case Operator::sinh:
187
			s = i18n("Hyperbolic sine");
188
			break;
189
		case Operator::cosh:
190
			s = i18n("Hyperbolic cosine");
191
			break;
192
		case Operator::tanh:
193
			s = i18n("Hyperbolic tangent");
194
			break;
195
		case Operator::sech:
196
			s = i18n("Hyperbolic secant");
197
			break;
198
		case Operator::csch:
199
			s = i18n("Hyperbolic cosecant");
200
			break;
201
		case Operator::coth:
202
			s = i18n("Hyperbolic cotangent");
203
			break;
204
		case Operator::arcsin:
205
			s = i18n("Arc sine");
206
			break;
207
		case Operator::arccos:
208
			s = i18n("Arc cosine");
209
			break;
210
		case Operator::arctan:
211
			s = i18n("Arc tangent");
212
			break;
213
		case Operator::arccot:
214
			s = i18n("Arc cotangent");
215
			break;
216
// 		case Operator::arccoth:
217
// 			s = i18n("Hyperbolic arc cotangent");
218
// 			break;
219
		case Operator::arctanh:
220
			s = i18n("Hyperbolic arc tangent");
221
			break;
222
		case Operator::sum:
223
			s = i18n("Summatory");
224
			break;
225
		case Operator::product:
226
			s = i18n("Productory");
227
			break;
228
		case Operator::forall:
229
			s = i18n("For all");
230
			break;
231
		case Operator::exists:
232
			s = i18n("Exists");
233
			break;
234
		case Operator::diff:
235
			s = i18n("Differentiation");
236
			break;
237
		case Operator::arcsinh:
238
			s = i18n("Hyperbolic arc sine");
239
			break;
240
		case Operator::arccosh:
241
			s = i18n("Hyperbolic arc cosine");
242
			break;
243
		case Operator::arccsc:
244
			s = i18n("Arc cosecant");
245
			break;
246
		case Operator::arccsch:
247
			s = i18n("Hyperbolic arc cosecant");
248
			break;
249
		case Operator::arcsec:
250
			s = i18n("Arc secant");
251
			break;
252
		case Operator::arcsech:
253
			s = i18n("Hyperbolic arc secant");
254
			break;
255
		case Operator::exp:
256
			s = i18n("Exponent (e^x)");
257
			break;
258
		case Operator::ln:
259
			s = i18n("Base-e logarithm");
260
			break;
261
		case Operator::log:
262
			s = i18n("Base-10 logarithm");
263
			break;
264
		case Operator::abs:
265
			s = i18n("Absolute value. abs(n)=|n|");
266
			break;
267
// 		case Operator::conjugate:
268
// 			s = i18n("Conjugate");
269
// 			break;
270
// 		case Operator::arg:
271
// 			s = "---";//i18n("Arg?");
272
// 			break;
273
// 		case Operator::real:
274
// 			s = i18n("Real");
275
// 			break;
276
// 		case Operator::imaginary:
277
// 			s = i18n("Imaginary");
278
// 			break;
279
		case Operator::floor:
280
			s = i18n("Floor value. floor(n)=⌊n⌋");
281
			break;
282
		case Operator::ceiling:
283
			s = i18n("Ceil value. ceil(n)=⌈n⌉");
284
			break;
285
		case Operator::min:
286
			s = i18n("Minimum");
287
			break;
288
		case Operator::max:
289
			s = i18n("Maximum");
290
			break;
291
		case Operator::gt:
292
			s = i18n("Greater than. gt(a,b)=a>b");
293
			break;
294
		case Operator::lt:
295
			s = i18n("Less than. lt(a,b)=a<b");
296
			break;
297
		case Operator::eq:
298
			s = i18n("Equal. eq(a,b) = a=b");
299
			break;
300
		case Operator::approx:
301
			s = i18n("Approximation. approx(a)=a±n");
302
			break;
303
		case Operator::neq:
304
			s = i18n("Not equal. neq(a,b)=a≠b");
305
			break;
306
		case Operator::geq:
307
			s = i18n("Greater or equal. geq(a,b)=a≥b");
308
			break;
309
		case Operator::leq:
310
			s = i18n("Less or equal. leq(a,b)=a≤b");
311
			break;
312
		case Operator::_and:
313
			s = i18n("Boolean and");
314
			break;
315
		case Operator::_not:
316
			s = i18n("Boolean not");
317
			break;
318
		case Operator::_or:
319
			s = i18n("Boolean or");
320
			break;
321
		case Operator::_xor:
322
			s = i18n("Boolean xor");
323
			break;
324
		case Operator::implies:
325
			s = i18n("Boolean implication");
326
			break;
327
		case Operator::gcd:
328
			s = i18n("Greatest common divisor");
329
			break;
330
		case Operator::lcm:
331
			s = i18n("Least common multiple");
332
			break;
333
		case Operator::root:
334
			s = i18n("Root");
335
			break;
336
		case Operator::card:
337
			s = i18n("Cardinal");
338
			break;
339
		case Operator::scalarproduct:
340
			s = i18n("Scalar product");
341
			break;
342
		case Operator::selector:
343
			s = i18n("Select the par1-th element of par2 list or vector");
344
			break;
345
		case Operator::_union:
346
			s = i18n("Joins several items of the same type");
347
			break;
348
		case Operator::function:
349
		case Operator::nOfOps:
350
		case Operator::none:
351
			break;
352
	}
353
	return s;
354
}
355
356
QString OperatorsModel::example(const Analitza::Operator& o)
357
{
358
	QString s;
359
	
360
	switch(o.operatorType()) {
361
		case Operator::plus:
362
			s="x+2";
363
			break;
364
		case Operator::times:
365
			s="x*2";
366
			break;
367
		case Operator::divide:
368
			s="x/2";
369
			break;
370
		case Operator::minus:
371
			s="x-2";
372
			break;
373
		case Operator::power:
374
			s="x^2";
375
			break;
376
		case Operator::rem:
377
			s="rem(x, 5)";
378
			break;
379
		case Operator::quotient:
380
			s="quotient(x, 2)";
381
			break;
382
		case Operator::factorof:
383
			s="factorof(x, 3)";
384
			break;
385
		case Operator::min:
386
			s="min(x, 4)";
387
			break;
388
		case Operator::max:
389
			s="max(x, 4)";
390
			break;
391
		case Operator::gt:
392
			s="x>4";
393
			break;
394
		case Operator::lt:
395
			s="x<4";
396
			break;
397
		case Operator::eq:
398
			s="x=4";
399
			break;
400
		case Operator::approx:
401
			s="approx(x, 4)";
402
			break;
403
		case Operator::neq:
404
			s="x!=4";
405
			break;
406
		case Operator::geq:
407
			s="x>=4";
408
			break;
409
		case Operator::leq:
410
			s="x<=4";
411
			break;
412
		case Operator::_and:
413
			s="and(x>-2, x<2)";
414
			break;
415
		case Operator::_or:
416
			s="or(x>2, x>-2)";
417
			break;
418
		case Operator::_xor:
419
			s="xor(x>0, x<3)";
420
			break;
421
		case Operator::implies:
422
			s="implies(x<0, x<3)";
423
			break;
424
		case Operator::gcd:
425
			s="gcd(x, 3)";
426
			break;
427
		case Operator::lcm:
428
			s="lcm(x, 4)";
429
			break;
430
		case Operator::root:
431
			s="root(x, 2)";
432
			break;
433
		case Operator::selector:
434
			s="(scalarproduct(vector { 0, x }, vector { x, 0 }))[1]";
435
			break;
436
		case Operator::sum:
437
			s="x*sum(t*t:t=0..3)";
438
			break;
439
		case Operator::product:
440
			s="product(t+t:t=1..3)";
441
			break;
442
		case Operator::forall:
443
			s="forall(t:t@list { true, false, false })";
444
			break;
445
		case Operator::exists:
446
			s="exists(t:t@list { true, false, false })";
447
			break;
448
		case Operator::card:
449
			s="card(vector { x, 1, 2 })";
450
			break;
451
		case Operator::scalarproduct:
452
			s="(scalarproduct(vector { 0, x }, vector { x, 0 }))[1]";
453
			break;
454
		case Operator::diff:
455
			s="(diff(x^2:x))(x)";
456
			break;
457
		case Operator::_union:
458
			s="(union(list { 1, 2, 3 }, list { 4, 5, 6 }))[rem(floor(x), 5)+3]";
459
			break;
460
		case Operator::factorial:
461
		case Operator::arcsech:
462
		case Operator::arcsec:
463
		case Operator::arccsch:
464
		case Operator::arccsc:
465
// 		case Operator::arccoth:
466
		case Operator::sin:
467
		case Operator::cos:
468
		case Operator::tan:
469
		case Operator::sec:
470
		case Operator::csc:
471
		case Operator::cot:
472
		case Operator::sinh:
473
		case Operator::cosh:
474
		case Operator::tanh:
475
		case Operator::sech:
476
		case Operator::csch:
477
		case Operator::coth:
478
		case Operator::arcsin:
479
		case Operator::arccos:
480
		case Operator::arctan:
481
		case Operator::arccot:
482
		case Operator::arcsinh:
483
		case Operator::arccosh:
484
// 		case Operator::arccsc:
485
// 		case Operator::arccsch:
486
// 		case Operator::arcsec:
487
// 		case Operator::arcsech:
488
		case Operator::arctanh:
489
		case Operator::exp:
490
		case Operator::ln:
491
		case Operator::log:
492
		case Operator::abs:
493
		//case Object::conjugate:
494
		//case Object::arg:
495
		//case Object::real:
496
		//case Object::imaginary:
497
		case Operator::floor:
498
		case Operator::ceiling:
499
		case Operator::_not:
500
			s=QString("%1(x)").arg(o.toString());
501
			break;
502
		case Operator::nOfOps:
503
		case Operator::none:
504
		case Operator::function:
505
// 		case Operator::real:
506
// 		case Operator::conjugate:
507
// 		case Operator::arg:
508
// 		case Operator::imaginary:
509
			break;
510
	}
511
	return "x->"+s;
512
}
513
514
QModelIndex OperatorsModel::indexForOperatorName(const QString& id) const
515
{
516
	Operator::OperatorType opt=Analitza::Operator::toOperatorType(id);
517
	if(opt==Operator::none)
518
		return QModelIndex();
519
	else
520
		return index(opt-1, 0);
521
}
522
523
QString OperatorsModel::parameterHelp(const QModelIndex& index, int param, bool inbounds) const
524
{
525
	Q_ASSERT(index.isValid());
526
	QString ret;
527
	Analitza::Operator oper((Analitza::Operator::OperatorType) (index.row()+1));
528
	QString funcname = oper.toString();
529
	const int op=oper.nparams();
530
	if(op == -1) {
531
		ret=i18nc("n-ary function prototype", "<em>%1</em>(..., <b>par%2</b>, ...)",
532
							funcname, param+1);
533
	} else {
534
		ret=standardFunctionCallHelp(funcname, param, op, inbounds, oper.isBounded());
535
	}
536
	return ret;
537
}
538
539
QString OperatorsModel::standardFunctionCallHelp(const QString& funcname, int param, int paramcount, bool inbounds, bool isbounded)
540
{
541
	QString sample = (param < paramcount || (inbounds && isbounded)) ?
542
		i18nc("Function name in function prototype", "<em>%1</em>(", funcname) :
543
		i18nc("Uncorrect function name in function prototype", "<em style='color:red'><b>%1</b></em>(", funcname);
544
		
545
	for(int i=0; i<paramcount; ++i) {
546
		QString current=i18nc("Parameter in function prototype", "par%1", i+1);
547
		
548
		if(i==param)
549
			current=i18nc("Current parameter in function prototype", "<b>%1</b>", current);
550
		sample += current;
551
		if(i<paramcount-1)
552
			sample += i18nc("Function parameter separator", ", ");
553
	}
554
	
555
	if(isbounded) {
556
		static QString bounds=i18nc("Current parameter is the bounding", " : bounds");
557
		QString p=bounds;
558
		if(inbounds)
559
			p=i18nc("Current parameter in function prototype", "<b>%1</b>", p);
560
		sample += p;
561
	}
562
	
563
	return sample+')';
564
565
}
566
567
568
/*QString OperatorsModel::operToString(const Operator& op) const
569
{
570
	QStandardItem *it;
571
	
572
	for(int i=0; i<KEYWORDNUM; i++) {
573
		it=item(i,2);
574
		if(it!=NULL && it->data(Qt::EditRole).toInt()==op.operatorType()) {
575
			return item(i,0)->data(Qt::EditRole).toString();
576
}
577
}
578
	return QString();
579
}*/
580
581