1 /***************************************************************************
2 * This file is part of the Lime Report project *
3 * Copyright (C) 2015 by Alexander Arin *
4 * arin_a@bk.ru *
5 * *
6 ** GNU General Public License Usage **
7 * *
8 * This library is free software: you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation, either version 3 of the License, or *
11 * (at your option) any later version. *
12 * You should have received a copy of the GNU General Public License *
13 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
14 * *
15 ** GNU Lesser General Public License **
16 * *
17 * This library is free software: you can redistribute it and/or modify *
18 * it under the terms of the GNU Lesser General Public License as *
19 * published by the Free Software Foundation, either version 3 of the *
20 * License, or (at your option) any later version. *
21 * You should have received a copy of the GNU Lesser General Public *
22 * License along with this library. *
23 * If not, see <http://www.gnu.org/licenses/>. *
24 * *
25 * This library is distributed in the hope that it will be useful, *
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
28 * GNU General Public License for more details. *
29 ****************************************************************************/
30 #include "lrscriptenginemanager.h"
31
32 #include <QDate>
33 #include <QStringList>
34 #include <QUuid>
35 #ifdef USE_QTSCRIPTENGINE
36 #include <QScriptValueIterator>
37 #endif
38 #include <QMessageBox>
39 #ifdef HAVE_UI_LOADER
40 #include <QUiLoader>
41 #include <QBuffer>
42 #include <QWidget>
43 #endif
44 #include "lrdatasourcemanager.h"
45 #include "lrbasedesignintf.h"
46 #include "lrbanddesignintf.h"
47 #include "lrpageitemdesignintf.h"
48
49 Q_DECLARE_METATYPE(QColor)
Q_DECLARE_METATYPE(QFont)50 Q_DECLARE_METATYPE(QFont)
51 Q_DECLARE_METATYPE(LimeReport::ScriptEngineManager *)
52
53 #ifdef USE_QTSCRIPTENGINE
54 QScriptValue constructColor(QScriptContext *context, QScriptEngine *engine)
55 {
56 QColor color(context->argument(0).toString());
57 return engine->toScriptValue(color);
58 }
59 #endif
60
61 namespace LimeReport{
62
ScriptEngineNode(const QString & name,const QString & description,ScriptEngineNode::NodeType type,ScriptEngineNode * parent,const QIcon & icon)63 ScriptEngineNode::ScriptEngineNode(const QString &name, const QString &description,
64 ScriptEngineNode::NodeType type, ScriptEngineNode *parent, const QIcon &icon)
65 :m_name(name), m_description(description), m_icon(icon), m_type(type), m_parent(parent)
66 {}
67
~ScriptEngineNode()68 ScriptEngineNode::~ScriptEngineNode()
69 {
70 qDeleteAll(m_childs.begin(), m_childs.end());
71 }
72
addChild(const QString & name,const QString & description,ScriptEngineNode::NodeType type,const QIcon & icon)73 ScriptEngineNode*ScriptEngineNode::addChild(const QString& name, const QString& description,
74 ScriptEngineNode::NodeType type, const QIcon& icon)
75 {
76 ScriptEngineNode* res = new ScriptEngineNode(name, description, type,this,icon);
77 m_childs.push_back(res);
78 return res;
79 }
80
row()81 int ScriptEngineNode::row()
82 {
83 if (m_parent){
84 return m_parent->m_childs.indexOf(const_cast<ScriptEngineNode*>(this));
85 }
86 return 0;
87 }
88
clear()89 void ScriptEngineNode::clear()
90 {
91 for (int i=0; i<m_childs.count(); ++i){
92 delete m_childs[i];
93 }
94 m_childs.clear();
95 }
96
ScriptEngineModel(ScriptEngineManager * scriptManager)97 ScriptEngineModel::ScriptEngineModel(ScriptEngineManager* scriptManager)
98 :m_rootNode(new ScriptEngineNode())
99 {
100 setScriptEngineManager(scriptManager);
101 }
102
~ScriptEngineModel()103 ScriptEngineModel::~ScriptEngineModel() {
104 delete m_rootNode;
105 }
106
parent(const QModelIndex & child) const107 QModelIndex ScriptEngineModel::parent(const QModelIndex& child) const
108 {
109 if (!child.isValid()) return QModelIndex();
110
111 ScriptEngineNode* childNode = nodeFromIndex(child);
112 if (!childNode) return QModelIndex();
113
114 ScriptEngineNode* parentNode = childNode->parent();
115 if ((parentNode == m_rootNode) || (!parentNode)) return QModelIndex();
116 return createIndex(parentNode->row(),0,parentNode);
117 }
118
index(int row,int column,const QModelIndex & parent) const119 QModelIndex ScriptEngineModel::index(int row, int column, const QModelIndex& parent) const
120 {
121 if (!m_rootNode)
122 return QModelIndex();
123
124 if (!hasIndex(row,column,parent))
125 return QModelIndex();
126
127 ScriptEngineNode* parentNode;
128 if (parent.isValid()){
129 parentNode = nodeFromIndex(parent);
130 } else {
131 parentNode = m_rootNode;
132 }
133
134 ScriptEngineNode* childNode = parentNode->child(row);
135 if (childNode){
136 return createIndex(row,column,childNode);
137 } else return QModelIndex();
138 }
139
rowCount(const QModelIndex & parent) const140 int ScriptEngineModel::rowCount(const QModelIndex& parent) const
141 {
142 if (!m_rootNode) return 0;
143 ScriptEngineNode* parentNode;
144 if (parent.isValid())
145 parentNode = nodeFromIndex(parent);
146 else
147 parentNode = m_rootNode;
148 return parentNode->childCount();
149 }
150
columnCount(const QModelIndex & parent) const151 int ScriptEngineModel::columnCount(const QModelIndex& parent) const
152 {
153 Q_UNUSED(parent)
154 return 1;
155 }
156
data(const QModelIndex & index,int role) const157 QVariant ScriptEngineModel::data(const QModelIndex& index, int role) const
158 {
159 ScriptEngineNode *node = nodeFromIndex(index);
160 switch (role) {
161 case Qt::DisplayRole:
162 if (!node) return QVariant();
163 return node->name();
164 break;
165 case Qt::DecorationRole :
166 if (!node) return QIcon();
167 return node->icon();
168 break;
169 default:
170 return QVariant();
171 }
172 }
173
setScriptEngineManager(ScriptEngineManager * scriptManager)174 void ScriptEngineModel::setScriptEngineManager(ScriptEngineManager* scriptManager)
175 {
176 m_scriptManager = scriptManager;
177 updateModel();
178 }
179
slotScriptEngineChanged()180 void ScriptEngineModel::slotScriptEngineChanged()
181 {
182 updateModel();
183 }
184
nodeFromIndex(const QModelIndex & index) const185 ScriptEngineNode*ScriptEngineModel::nodeFromIndex(const QModelIndex& index) const
186 {
187 if (index.isValid()){
188 return static_cast<ScriptEngineNode*>(index.internalPointer());
189 } else return m_rootNode;
190 }
191
updateModel()192 void ScriptEngineModel::updateModel()
193 {
194 beginResetModel();
195 m_rootNode->clear();
196 QMap<QString,ScriptEngineNode*> categories;
197 foreach(ScriptFunctionDesc funcDesc, m_scriptManager->functionsDescribers()){
198 ScriptEngineNode* categ;
199 QString categoryName = (!funcDesc.category.isEmpty())?funcDesc.category:"NO CATEGORY";
200 if (categories.contains(categoryName)){
201 categ = categories.value(categoryName);
202 } else {
203 categ = m_rootNode->addChild(categoryName,"",ScriptEngineNode::Category,QIcon(":/report/images/folder"));
204 categories.insert(categoryName,categ);
205 }
206 categ->addChild(funcDesc.name,funcDesc.description,ScriptEngineNode::Function,QIcon(":/report/images/function"));
207 }
208 endResetModel();
209 }
210
~ScriptEngineManager()211 ScriptEngineManager::~ScriptEngineManager()
212 {
213 delete m_model;
214 m_model = 0;
215 delete m_scriptEngine;
216 }
217
isFunctionExists(const QString & functionName) const218 bool ScriptEngineManager::isFunctionExists(const QString &functionName) const
219 {
220 return m_functions.contains(functionName);
221 // foreach (ScriptFunctionDesc desc, m_functions.values()) {
222 // if (desc.name.compare(functionName,Qt::CaseInsensitive)==0){
223 // return true;
224 // }
225 // }
226 // return false;
227 }
228
deleteFunction(const QString & functionsName)229 void ScriptEngineManager::deleteFunction(const QString &functionsName)
230 {
231 m_functions.remove(functionsName);
232 }
233
addFunction(const JSFunctionDesc & functionDescriber)234 bool ScriptEngineManager::addFunction(const JSFunctionDesc &functionDescriber)
235 {
236 if (m_functions.contains(functionDescriber.name())) return false;
237 ScriptValueType functionManager = scriptEngine()->globalObject().property(functionDescriber.managerName());
238 #ifdef USE_QJSENGINE
239 if (functionManager.isUndefined()){
240 #else
241 if (!functionManager.isValid()){
242 #endif
243 functionManager = scriptEngine()->newQObject(functionDescriber.manager());
244 scriptEngine()->globalObject().setProperty(
245 functionDescriber.managerName(),
246 functionManager
247 );
248 }
249
250 if (functionManager.toQObject() == functionDescriber.manager()){
251 ScriptValueType checkWrapper = scriptEngine()->evaluate(functionDescriber.scriptWrapper());
252 if (!checkWrapper.isError()){
253 ScriptFunctionDesc funct;
254 funct.name = functionDescriber.name();
255 funct.description = functionDescriber.description();
256 funct.category = functionDescriber.category();
257 funct.type = ScriptFunctionDesc::Native;
258 m_functions.insert(funct.name, funct);
259 if (m_model)
260 m_model->updateModel();
261 return true;
262 } else {
263 m_lastError = checkWrapper.toString();
264 return false;
265 }
266 } else {
267 m_lastError = tr("Function manager with name \"%1\" already exists!");
268 return false;
269 }
270
271 }
272
273 #ifdef USE_QTSCRIPTENGINE
274 #if QT_VERSION > 0x050600
275 Q_DECL_DEPRECATED
276 #endif
277 bool ScriptEngineManager::addFunction(const QString& name,
278 QScriptEngine::FunctionSignature function,
279 const QString& category,
280 const QString& description)
281 {
282 if (!isFunctionExists(name)){
283 ScriptFunctionDesc funct;
284 funct.name = name;
285 funct.description = description;
286 funct.category = category;
287 funct.scriptValue = scriptEngine()->newFunction(function);
288 funct.scriptValue.setProperty("functionName", name);
289 funct.scriptValue.setData(m_scriptEngine->toScriptValue(this));
290 funct.type = ScriptFunctionDesc::Native;
291 m_functions.insert(name, funct);
292 if (m_model)
293 m_model->updateModel();
294 m_scriptEngine->globalObject().setProperty(funct.name, funct.scriptValue);
295 return true;
296 } else {
297 return false;
298 }
299 }
300 #endif
301
302 bool ScriptEngineManager::addFunction(const QString& name, const QString& script, const QString& category, const QString& description)
303 {
304 ScriptValueType functionValue = m_scriptEngine->evaluate(script);
305 if (!functionValue.isError()){
306 ScriptFunctionDesc funct;
307 funct.scriptValue = functionValue;
308 funct.name = name;
309 funct.category = category;
310 funct.description = description;
311 funct.type = ScriptFunctionDesc::Script;
312 m_functions.insert(name, funct);
313 m_model->updateModel();
314 return true;
315 } else {
316 m_lastError = functionValue.toString();
317 return false;
318 }
319 }
320
321 QStringList ScriptEngineManager::functionsNames()
322 {
323 return m_functions.keys();
324 // QStringList res;
325 // foreach(ScriptFunctionDesc func, m_functions){
326 // res<<func.name;
327 // }
328 // return res;
329 }
330
331 void ScriptEngineManager::setDataManager(DataSourceManager *dataManager){
332 if (dataManager && m_dataManager != dataManager){
333 m_dataManager = dataManager;
334 if (m_dataManager){
335 foreach(QString func, m_dataManager->groupFunctionNames()){
336 JSFunctionDesc describer(
337 func,
338 tr("GROUP FUNCTIONS"),
339 func+"(\""+tr("FieldName")+"\",\""+tr("BandName")+"\")",
340 LimeReport::Const::FUNCTION_MANAGER_NAME,
341 m_functionManager,
342 QString("function %1(fieldName, bandName, pageitem){\
343 if (typeof pageitem == 'undefined') return %2.calcGroupFunction(\"%1\", fieldName, bandName); \
344 else return %2.calcGroupFunction(\"%1\", fieldName, bandName, pageitem);}"
345 ).arg(func)
346 .arg(LimeReport::Const::FUNCTION_MANAGER_NAME)
347 );
348 addFunction(describer);
349 }
350 moveQObjectToScript(new DatasourceFunctions(dataManager), LimeReport::Const::DATAFUNCTIONS_MANAGER_NAME);
351 }
352 }
353 }
354
355 QString ScriptEngineManager::expandUserVariables(QString context, RenderPass /* pass */, ExpandType expandType, QVariant &varValue)
356 {
357 QRegExp rx(Const::VARIABLE_RX);
358 if (context.contains(rx)){
359 int pos = 0;
360 while ((pos = rx.indexIn(context,pos))!=-1){
361 QString variable=rx.cap(1);
362 pos += rx.matchedLength();
363 if (dataManager()->containsVariable(variable) ){
364 try {
365
366 varValue = dataManager()->variable(variable);
367 switch (expandType){
368 case EscapeSymbols:
369 context.replace(rx.cap(0),escapeSimbols(varValue.toString()));
370 break;
371 case NoEscapeSymbols:
372 context.replace(rx.cap(0),varValue.toString());
373 break;
374 case ReplaceHTMLSymbols:
375 context.replace(rx.cap(0),replaceHTMLSymbols(varValue.toString()));
376 break;
377 }
378 pos=0;
379
380 } catch (ReportError &e){
381 dataManager()->putError(e.what());
382 if (!dataManager()->reportSettings() || dataManager()->reportSettings()->suppressAbsentFieldsAndVarsWarnings())
383 context.replace(rx.cap(0),e.what());
384 else
385 context.replace(rx.cap(0),"");
386 }
387 } else {
388 QString error;
389 error = tr("Variable %1 not found").arg(variable);
390 dataManager()->putError(error);
391 if (!dataManager()->reportSettings() || dataManager()->reportSettings()->suppressAbsentFieldsAndVarsWarnings())
392 context.replace(rx.cap(0),error);
393 else
394 context.replace(rx.cap(0),"");
395 }
396 }
397 }
398 return context;
399 }
400
401 QString ScriptEngineManager::expandDataFields(QString context, ExpandType expandType, QVariant &varValue, QObject *reportItem)
402 {
403 QRegExp rx(Const::FIELD_RX);
404
405 if (context.contains(rx)){
406 while ((rx.indexIn(context))!=-1){
407 QString field=rx.cap(1);
408
409 if (dataManager()->containsField(field)) {
410 QString fieldValue;
411 varValue = dataManager()->fieldData(field);
412 if (expandType == EscapeSymbols) {
413 if (varValue.isNull()) {
414 fieldValue="\"\"";
415 } else {
416 fieldValue = escapeSimbols(varValue.toString());
417 switch (dataManager()->fieldData(field).type()) {
418 case QVariant::Char:
419 case QVariant::String:
420 case QVariant::StringList:
421 case QVariant::Date:
422 case QVariant::DateTime:
423 fieldValue = "\""+fieldValue+"\"";
424 break;
425 default:
426 break;
427 }
428 }
429 } else {
430 if (expandType == ReplaceHTMLSymbols)
431 fieldValue = replaceHTMLSymbols(varValue.toString());
432 else fieldValue = varValue.toString();
433 }
434
435 context.replace(rx.cap(0),fieldValue);
436
437 } else {
438 QString error;
439 if (reportItem){
440 error = tr("Field %1 not found in %2!").arg(field).arg(reportItem->objectName());
441 dataManager()->putError(error);
442 }
443 varValue = QVariant();
444 if (!dataManager()->reportSettings() || !dataManager()->reportSettings()->suppressAbsentFieldsAndVarsWarnings())
445 context.replace(rx.cap(0),error);
446 else
447 context.replace(rx.cap(0),"");
448 }
449 }
450 }
451
452 return context;
453 }
454
455 QString ScriptEngineManager::expandScripts(QString context, QVariant& varValue, QObject *reportItem)
456 {
457 QRegExp rx(Const::SCRIPT_RX);
458
459 if (context.contains(rx)){
460
461 if (ScriptEngineManager::instance().dataManager() != dataManager())
462 ScriptEngineManager::instance().setDataManager(dataManager());
463
464 ScriptEngineType* se = ScriptEngineManager::instance().scriptEngine();
465
466 if (reportItem){
467 ScriptValueType svThis;
468 #ifdef USE_QJSENGINE
469 svThis = getJSValue(*se, reportItem);
470 se->globalObject().setProperty("THIS",svThis);
471 #else
472 svThis = se->globalObject().property("THIS");
473 if (svThis.isValid()){
474 se->newQObject(svThis, reportItem);
475 } else {
476 svThis = se->newQObject(reportItem);
477 se->globalObject().setProperty("THIS",svThis);
478 }
479 #endif
480 }
481
482 ScriptExtractor scriptExtractor(context);
483 if (scriptExtractor.parse()){
484 context = replaceScripts(context, varValue, reportItem, se, scriptExtractor.scriptTree());
485 }
486
487 }
488 return context;
489 }
490
491 QString ScriptEngineManager::replaceScripts(QString context, QVariant &varValue, QObject *reportItem, ScriptEngineType* se, ScriptNode *scriptTree)
492 {
493 foreach(ScriptNode* item, scriptTree->children()){
494 QString scriptBody = expandDataFields(item->body(), EscapeSymbols, varValue, reportItem);
495 if (item->children().size() > 0)
496 scriptBody = replaceScripts(scriptBody, varValue, reportItem, se, item);
497 scriptBody = expandUserVariables(scriptBody, FirstPass, EscapeSymbols, varValue);
498 ScriptValueType value = se->evaluate(scriptBody);
499 #ifdef USE_QJSENGINE
500 if (!value.isError()){
501 varValue = value.toVariant();
502 context.replace(item->script(), value.toString());
503 } else {
504 context.replace(item->script(), value.toString());
505 }
506 #else
507 if (!se->hasUncaughtException()) {
508 varValue = value.toVariant();
509 context.replace(item->script(), value.toString());
510 } else {
511 context.replace(item->script(), se->uncaughtException().toString());
512 }
513 #endif
514 }
515 return context;
516 }
517
518 QVariant ScriptEngineManager::evaluateScript(const QString& script){
519
520 QRegExp rx(Const::SCRIPT_RX);
521 QVariant varValue;
522
523 if (script.contains(rx)){
524
525 if (ScriptEngineManager::instance().dataManager()!=dataManager())
526 ScriptEngineManager::instance().setDataManager(dataManager());
527
528 ScriptEngineType* se = ScriptEngineManager::instance().scriptEngine();
529
530 ScriptExtractor scriptExtractor(script);
531 if (scriptExtractor.parse()){
532 QString scriptBody = expandDataFields(scriptExtractor.scriptTree()[0].body(), EscapeSymbols, varValue, 0);
533 scriptBody = expandUserVariables(scriptBody, FirstPass, EscapeSymbols, varValue);
534 ScriptValueType value = se->evaluate(scriptBody);
535 #ifdef USE_QJSENGINE
536 if (!value.isError()){
537 #else
538 if (!se->hasUncaughtException()) {
539 #endif
540 return value.toVariant();
541 }
542 }
543 }
544 return QVariant();
545 }
546
547 void ScriptEngineManager::addBookMark(const QString& uniqKey, const QString& content){
548 Q_ASSERT(m_context != 0);
549 if (m_context){
550 BandDesignIntf* currentBand = m_context->getCurrentBand();
551 if (currentBand)
552 currentBand->addBookmark(uniqKey, content);
553 else if (m_context->getCurrentPage()) {
554 m_context->getCurrentPage()->addBookmark(uniqKey, content);
555 }
556 }
557
558 }
559
560 int ScriptEngineManager::findPageIndexByBookmark(const QString &uniqKey)
561 {
562 for (int i=0; i < m_context->reportPages()->size(); ++i){
563 if (m_context->reportPages()->at(i)->bookmarks().contains(uniqKey))
564 return i+1;
565 foreach(BandDesignIntf* band, m_context->reportPages()->at(i)->bands()){
566 if (band->bookmarks().contains(uniqKey))
567 return i+1;
568 }
569 }
570 return -1;
571 }
572
573 void ScriptEngineManager::addTableOfContentsItem(const QString& uniqKey, const QString& content, int indent)
574 {
575 Q_ASSERT(m_context != 0);
576 if (m_context){
577 m_context->tableOfContents()->setItem(uniqKey, content, 0, indent);
578 addBookMark(uniqKey, content);
579 }
580 }
581
582 void ScriptEngineManager::clearTableOfContents(){
583 if (m_context) {
584 if (m_context->tableOfContents())
585 m_context->tableOfContents()->clear();
586 }
587 }
588
589 ScriptValueType ScriptEngineManager::moveQObjectToScript(QObject* object, const QString objectName)
590 {
591
592 ScriptValueType obj = scriptEngine()->globalObject().property(objectName);
593 if (!obj.isNull()) delete obj.toQObject();
594 ScriptValueType result = scriptEngine()->newQObject(object);
595 scriptEngine()->globalObject().setProperty(objectName, result);
596 return result;
597 }
598
599 void ScriptEngineManager::updateModel()
600 {
601
602 }
603
604 bool ScriptEngineManager::createLineFunction()
605 {
606 JSFunctionDesc fd;
607
608 fd.setManager(m_functionManager);
609 fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME);
610 fd.setCategory(tr("SYSTEM"));
611 fd.setName("line");
612 fd.setDescription("line(\""+tr("BandName")+"\")");
613 fd.setScriptWrapper(QString("function line(bandName){ return %1.line(bandName);}").arg(LimeReport::Const::FUNCTION_MANAGER_NAME));
614
615 return addFunction(fd);
616
617 }
618
619 bool ScriptEngineManager::createNumberFomatFunction()
620 {
621 JSFunctionDesc fd;
622
623 fd.setManager(m_functionManager);
624 fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME);
625 fd.setCategory(tr("NUMBER"));
626 fd.setName("numberFormat");
627 fd.setDescription("numberFormat(\""+tr("Value")+"\",\""+tr("Format")+"\",\""+
628 tr("Precision")+"\",\""+
629 tr("Locale")+"\")"
630 );
631 fd.setScriptWrapper(QString("function numberFormat(value, format, precision, locale){"
632 " if(typeof(format)==='undefined') format = \"f\"; "
633 " if(typeof(precision)==='undefined') precision=2; "
634 " if(typeof(locale)==='undefined') locale=\"\"; "
635 "return %1.numberFormat(value,format,precision,locale);}"
636 ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME)
637 );
638 return addFunction(fd);
639 }
640
641 bool ScriptEngineManager::createDateFormatFunction(){
642 JSFunctionDesc fd;
643
644 fd.setManager(m_functionManager);
645 fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME);
646 fd.setCategory(tr("DATE&TIME"));
647 fd.setName("dateFormat");
648 fd.setDescription("dateFormat(\""+tr("Value")+"\",\""+tr("Format")+"\", \""+tr("Locale")+"\")");
649 fd.setScriptWrapper(QString("function dateFormat(value, format, locale){"
650 " if(typeof(format)==='undefined') format = \"dd.MM.yyyy\"; "
651 "return %1.dateFormat(value,format, locale);}"
652 ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME)
653 );
654 return addFunction(fd);
655 }
656
657 bool ScriptEngineManager::createTimeFormatFunction(){
658 JSFunctionDesc fd;
659
660 fd.setManager(m_functionManager);
661 fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME);
662 fd.setCategory(tr("DATE&TIME"));
663 fd.setName("timeFormat");
664 fd.setDescription("timeFormat(\""+tr("Value")+"\",\""+tr("Format")+"\")");
665 fd.setScriptWrapper(QString("function timeFormat(value, format){"
666 " if(typeof(format)==='undefined') format = \"hh:mm\"; "
667 "return %1.timeFormat(value,format);}"
668 ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME)
669 );
670 return addFunction(fd);
671 }
672
673 bool ScriptEngineManager::createDateTimeFormatFunction(){
674 JSFunctionDesc fd;
675
676 fd.setManager(m_functionManager);
677 fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME);
678 fd.setCategory(tr("DATE&TIME"));
679 fd.setName("dateTimeFormat");
680 fd.setDescription("dateTimeFormat(\""+tr("Value")+"\",\""+tr("Format")+"\", \""+tr("Locale")+"\")");
681 fd.setScriptWrapper(QString("function dateTimeFormat(value, format, locale){"
682 " if(typeof(format)==='undefined') format = \"dd.MM.yyyy hh:mm\"; "
683 "return %1.dateTimeFormat(value, format, locale);}"
684 ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME)
685 );
686 return addFunction(fd);
687 }
688
689 bool ScriptEngineManager::createSectotimeFormatFunction()
690 {
691 JSFunctionDesc fd;
692
693 fd.setManager(m_functionManager);
694 fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME);
695 fd.setCategory(tr("DATE&TIME"));
696 fd.setName("sectotimeFormat");
697 fd.setDescription("sectotimeFormat(\""+tr("Value")+"\",\""+tr("Format")+"\")");
698 fd.setScriptWrapper(QString("function sectotimeFormat(value, format){"
699 " if(typeof(format)==='undefined') format = \"hh:mm:ss\"; "
700 "return %1.sectotimeFormat(value,format);}"
701 ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME)
702 );
703 return addFunction(fd);
704 }
705
706 bool ScriptEngineManager::createDateFunction(){
707 // addFunction("date",date,"DATE&TIME","date()");
708 JSFunctionDesc fd;
709
710 fd.setManager(m_functionManager);
711 fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME);
712 fd.setCategory(tr("DATE&TIME"));
713 fd.setName("date");
714 fd.setDescription("date()");
715 fd.setScriptWrapper(QString("function date(){"
716 "return %1.date();}"
717 ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME)
718 );
719 return addFunction(fd);
720 }
721
722
723 bool ScriptEngineManager::createNowFunction(){
724 // addFunction("now",now,"DATE&TIME","now()");
725 JSFunctionDesc fd;
726
727 fd.setManager(m_functionManager);
728 fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME);
729 fd.setCategory(tr("DATE&TIME"));
730 fd.setName("now");
731 fd.setDescription("now()");
732 fd.setScriptWrapper(QString("function now(){"
733 "return %1.now();}"
734 ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME)
735 );
736 return addFunction(fd);
737 }
738
739 bool ScriptEngineManager::createCurrencyFormatFunction(){
740 // addFunction("currencyFormat",currencyFormat,"NUMBER","currencyFormat(\""+tr("Value")+"\",\""+tr("Locale")+"\")");
741 JSFunctionDesc fd;
742
743 fd.setManager(m_functionManager);
744 fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME);
745 fd.setCategory(tr("NUMBER"));
746 fd.setName("currencyFormat");
747 fd.setDescription("currencyFormat(\""+tr("Value")+"\",\""+tr("Locale")+"\")");
748 fd.setScriptWrapper(QString("function currencyFormat(value, locale){"
749 " if(typeof(locale)==='undefined') locale = \"\"; "
750 "return %1.currencyFormat(value,locale);}"
751 ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME)
752 );
753 return addFunction(fd);
754 }
755
756 bool ScriptEngineManager::createCurrencyUSBasedFormatFunction(){
757 // addFunction("currencyUSBasedFormat",currencyUSBasedFormat,"NUMBER","currencyUSBasedFormat(\""+tr("Value")+",\""+tr("CurrencySymbol")+"\")");
758 JSFunctionDesc fd;
759
760 fd.setManager(m_functionManager);
761 fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME);
762 fd.setCategory(tr("NUMBER"));
763 fd.setName("currencyUSBasedFormat");
764 fd.setDescription("currencyUSBasedFormat(\""+tr("Value")+",\""+tr("CurrencySymbol")+"\")");
765 fd.setScriptWrapper(QString("function currencyUSBasedFormat(value, currencySymbol){"
766 " if(typeof(currencySymbol)==='undefined') currencySymbol = \"\"; "
767 "return %1.currencyUSBasedFormat(value,currencySymbol);}"
768 ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME)
769 );
770 return addFunction(fd);
771 }
772
773 bool ScriptEngineManager::createSetVariableFunction(){
774 // addFunction("setVariable", setVariable, "GENERAL", "setVariable(\""+tr("Name")+"\",\""+tr("Value")+"\")");
775 JSFunctionDesc fd;
776
777 fd.setManager(m_functionManager);
778 fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME);
779 fd.setCategory(tr("GENERAL"));
780 fd.setName("setVariable");
781 fd.setDescription("setVariable(\""+tr("Name")+"\",\""+tr("Value")+"\")");
782 fd.setScriptWrapper(QString("function setVariable(name, value){"
783 "return %1.setVariable(name,value);}"
784 ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME)
785 );
786 return addFunction(fd);
787 }
788
789 bool ScriptEngineManager::createGetVariableFunction()
790 {
791 JSFunctionDesc fd;
792 fd.setManager(m_functionManager);
793 fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME);
794 fd.setCategory(tr("GENERAL"));
795 fd.setName("getVariable");
796 fd.setDescription("getVariable(\""+tr("Name")+"\")");
797 fd.setScriptWrapper(QString("function getVariable(name){"
798 "return %1.getVariable(name);}"
799 ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME)
800 );
801 return addFunction(fd);
802 }
803
804 bool ScriptEngineManager::createGetFieldFunction()
805 {
806 JSFunctionDesc fd;
807 fd.setManager(m_functionManager);
808 fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME);
809 fd.setCategory(tr("GENERAL"));
810 fd.setName("getField");
811 fd.setDescription("getField(\""+tr("Name")+"\")");
812 fd.setScriptWrapper(QString("function getField(name){"
813 "return %1.getField(name);}"
814 ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME)
815 );
816 return addFunction(fd);
817 }
818
819 bool ScriptEngineManager::createGetFieldByKeyFunction()
820 {
821 JSFunctionDesc fd;
822 fd.setManager(m_functionManager);
823 fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME);
824 fd.setCategory(tr("GENERAL"));
825 fd.setName("getFieldByKeyField");
826 fd.setDescription("getFieldByKeyField(\""+tr("Datasource")+"\", \""+
827 tr("ValueField")+"\",\""+
828 tr("KeyField")+"\", \""+
829 tr("KeyFieldValue")+"\")"
830 );
831 fd.setScriptWrapper(QString("function getFieldByKeyField(datasource, valueFieldName, keyFieldName, keyValue){"
832 "return %1.getFieldByKeyField(datasource, valueFieldName, keyFieldName, keyValue);}"
833 ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME)
834 );
835 return addFunction(fd);
836 }
837
838 bool ScriptEngineManager::createGetFieldByRowIndex()
839 {
840 JSFunctionDesc fd;
841 fd.setManager(m_functionManager);
842 fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME);
843 fd.setCategory(tr("GENERAL"));
844 fd.setName("getFieldByRowIndex");
845 fd.setDescription("getFieldByRowIndex(\""+tr("FieldName")+"\", \""+
846 tr("RowIndex")+"\")"
847 );
848 fd.setScriptWrapper(QString("function getFieldByRowIndex(fieldName, rowIndex){"
849 "return %1.getFieldByRowIndex(fieldName, rowIndex);}"
850 ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME)
851 );
852 return addFunction(fd);
853 }
854
855 bool ScriptEngineManager::createAddBookmarkFunction()
856 {
857 JSFunctionDesc fd;
858 fd.setManager(m_functionManager);
859 fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME);
860 fd.setCategory(tr("GENERAL"));
861 fd.setName("addBookmark");
862 fd.setDescription("addBookmark(\""+tr("Unique identifier")+" \""+tr("Content")+"\")");
863 fd.setScriptWrapper(QString("function addBookmark(uniqKey, content){"
864 "return %1.addBookmark(uniqKey, content);}"
865 ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME)
866 );
867 return addFunction(fd);
868 }
869
870 bool ScriptEngineManager::createFindPageIndexByBookmark()
871 {
872 JSFunctionDesc fd;
873 fd.setManager(m_functionManager);
874 fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME);
875 fd.setCategory(tr("GENERAL"));
876 fd.setName("findPageIndexByBookmark");
877 fd.setDescription("findPageIndexByBookmark(\""+tr("Unique identifier")+"\")");
878 fd.setScriptWrapper(QString("function findPageIndexByBookmark(uniqKey){"
879 "return %1.findPageIndexByBookmark(uniqKey);}"
880 ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME)
881 );
882 return addFunction(fd);
883 }
884
885 bool ScriptEngineManager::createAddTableOfContentsItemFunction()
886 {
887 JSFunctionDesc fd;
888 fd.setManager(m_functionManager);
889 fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME);
890 fd.setCategory(tr("GENERAL"));
891 fd.setName("addTableOfContentsItem");
892 fd.setDescription("addTableOfContentsItem(\""+tr("Unique identifier")+" \""+tr("Content")+"\", \""+tr("Indent")+"\")");
893 fd.setScriptWrapper(QString("function addTableOfContentsItem(uniqKey, content, indent){"
894 "return %1.addTableOfContentsItem(uniqKey, content, indent);}"
895 ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME)
896 );
897 return addFunction(fd);
898 }
899
900 bool ScriptEngineManager::createClearTableOfContentsFunction()
901 {
902 JSFunctionDesc fd;
903 fd.setManager(m_functionManager);
904 fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME);
905 fd.setCategory(tr("GENERAL"));
906 fd.setName("clearTableOfContents");
907 fd.setDescription("clearTableOfContents()");
908 fd.setScriptWrapper(QString("function clearTableOfContents(){"
909 "return %1.clearTableOfContents();}"
910 ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME)
911 );
912 return addFunction(fd);
913 }
914
915 bool ScriptEngineManager::createReopenDatasourceFunction()
916 {
917 JSFunctionDesc fd;
918 fd.setManager(m_functionManager);
919 fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME);
920 fd.setCategory(tr("GENERAL"));
921 fd.setName("reopenDatasource");
922 fd.setDescription("reopenDatasource(\""+tr("datasourceName")+"\")");
923 fd.setScriptWrapper(QString("function reopenDatasource(datasourceName){"
924 "return %1.reopenDatasource(datasourceName);}"
925 ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME)
926 );
927 return addFunction(fd);
928 }
929
930 ScriptEngineManager::ScriptEngineManager()
931 :m_model(0), m_context(0), m_dataManager(0)
932 {
933 m_scriptEngine = new ScriptEngineType;
934 m_functionManager = new ScriptFunctionsManager(this);
935 m_functionManager->setScriptEngineManager(this);
936 #ifdef USE_QTSCRIPTENGINE
937 m_scriptEngine->setDefaultPrototype(qMetaTypeId<QComboBox*>(),
938 m_scriptEngine->newQObject(new ComboBoxPrototype()));
939 #endif
940 createLineFunction();
941 createNumberFomatFunction();
942 createDateFormatFunction();
943 createTimeFormatFunction();
944 createDateTimeFormatFunction();
945 createSectotimeFormatFunction();
946 createDateFunction();
947 createNowFunction();
948 #if QT_VERSION>0x040800
949 createCurrencyFormatFunction();
950 createCurrencyUSBasedFormatFunction();
951 #endif
952 createSetVariableFunction();
953 createGetFieldFunction();
954 createGetFieldByRowIndex();
955 createGetFieldByKeyFunction();
956 createGetVariableFunction();
957 #ifdef USE_QTSCRIPTENGINE
958 QScriptValue colorCtor = m_scriptEngine->newFunction(constructColor);
959 m_scriptEngine->globalObject().setProperty("QColor", colorCtor);
960
961 QScriptValue fontProto(m_scriptEngine->newQObject(new QFontPrototype,QScriptEngine::ScriptOwnership));
962 m_scriptEngine->setDefaultPrototype(qMetaTypeId<QFont>(), fontProto);
963 QScriptValue fontConstructor = m_scriptEngine->newFunction(QFontPrototype::constructorQFont, fontProto);
964 m_scriptEngine->globalObject().setProperty("QFont", fontConstructor);
965 #endif
966 createAddBookmarkFunction();
967 createFindPageIndexByBookmark();
968 createAddTableOfContentsItemFunction();
969 createClearTableOfContentsFunction();
970 createReopenDatasourceFunction();
971
972 m_model = new ScriptEngineModel(this);
973 }
974
975 bool ScriptExtractor::parse()
976 {
977 int currentPos = 0;
978 parse(currentPos, None, m_scriptTree);
979 return m_scriptTree->children().count() > 0;
980 }
981
982 bool ScriptExtractor::parse(int &curPos, const State& state, ScriptNode* scriptNode)
983 {
984 while (curPos<m_context.length()){
985 switch (state) {
986 case OpenBracketFound:
987 if (m_context[curPos]=='}'){
988 return true;
989 } else {
990 if (m_context[curPos]=='{')
991 extractBracket(curPos, scriptNode);
992 }
993 case None:
994 if (m_context[curPos]=='$'){
995 int startPos = curPos;
996 if (isStartScriptLexem(curPos))
997 extractScript(curPos, substring(m_context,startPos,curPos), scriptNode->createChildNode());
998 if (isStartFieldLexem(curPos) || isStartVariableLexem(curPos))
999 skipField(curPos);
1000 }
1001 default:
1002 break;
1003 }
1004 curPos++;
1005 }
1006 return false;
1007 }
1008
1009 void ScriptExtractor::extractScript(int &curPos, const QString& startStr, ScriptNode* scriptNode)
1010 {
1011 int startPos = curPos;
1012 if (extractBracket(curPos, scriptNode)){
1013 QString scriptBody = substring(m_context,startPos+1,curPos);
1014 scriptNode->setBody(scriptBody);
1015 scriptNode->setStartLex(startStr+'{');
1016 }
1017 }
1018
1019 void ScriptExtractor::skipField(int &curPos){
1020 while (curPos<m_context.length()) {
1021 if (m_context[curPos]=='}'){
1022 return;
1023 } else {
1024 curPos++;
1025 }
1026 }
1027 }
1028
1029 bool ScriptExtractor::extractBracket(int &curPos, ScriptNode* scriptNode)
1030 {
1031 curPos++;
1032 return parse(curPos,OpenBracketFound, scriptNode);
1033 }
1034
1035 bool ScriptExtractor::isStartLexem(int& curPos, QChar value){
1036 int pos = curPos+1;
1037 State ls = BuksFound;
1038 while (pos<m_context.length()){
1039 switch (ls){
1040 case BuksFound:
1041 if (m_context[pos]==value){
1042 ls = SignFound;
1043 } else {
1044 if (m_context[pos]!=' ')
1045 return false;
1046 }
1047 break;
1048 case SignFound:
1049 if (m_context[pos]=='{'){
1050 curPos=pos;
1051 return true;
1052 } else
1053 if (m_context[pos]!=' ')
1054 return false;
1055 default:
1056 break;
1057 }
1058 pos++;
1059 }
1060 return false;
1061 }
1062
1063 bool ScriptExtractor::isStartScriptLexem(int& curPos)
1064 {
1065 return isStartLexem(curPos, Const::SCRIPT_SIGN);
1066 }
1067
1068 bool ScriptExtractor::isStartFieldLexem(int& curPos){
1069 return isStartLexem(curPos, Const::FIELD_SIGN);
1070 }
1071
1072 bool ScriptExtractor::isStartVariableLexem(int &curPos)
1073 {
1074 return isStartLexem(curPos, Const::VARIABLE_SIGN);
1075 }
1076
1077
1078 QString ScriptExtractor::substring(const QString &value, int start, int end)
1079 {
1080 return value.mid(start,end-start);
1081 }
1082
1083 QString DialogDescriber::name() const
1084 {
1085 return m_name;
1086 }
1087
1088 void DialogDescriber::setName(const QString& name)
1089 {
1090 m_name = name;
1091 }
1092
1093 QByteArray DialogDescriber::description() const
1094 {
1095 return m_description;
1096 }
1097
1098 void DialogDescriber::setDescription(const QByteArray &description)
1099 {
1100 m_description = description;
1101 }
1102
1103 #ifdef HAVE_UI_LOADER
1104 void ScriptEngineContext::addDialog(const QString& name, const QByteArray& description)
1105 {
1106 m_dialogs.push_back(DialogDescriber::create(name,description));
1107 emit dialogAdded(name);
1108 }
1109
1110 bool ScriptEngineContext::changeDialog(const QString& name, const QByteArray& description)
1111 {
1112 foreach( DialogDescriber::Ptr describer, m_dialogs){
1113 if (describer->name().compare(name) == 0){
1114 describer->setDescription(description);
1115 {
1116 QList<DialogPtr>::Iterator it = m_createdDialogs.begin();
1117 while(it!=m_createdDialogs.end()){
1118 if ((*it)->objectName()==name){
1119 it = m_createdDialogs.erase(it);
1120 } else {
1121 ++it;
1122 }
1123 }
1124 }
1125 return true;
1126 }
1127 }
1128 return false;
1129 }
1130
1131 bool ScriptEngineContext::changeDialogName(const QString& oldName, const QString& newName)
1132 {
1133 foreach( DialogDescriber::Ptr describer, m_dialogs){
1134 if (describer->name().compare(oldName) == 0){
1135 describer->setName(newName);
1136 {
1137 QList<DialogPtr>::Iterator it = m_createdDialogs.begin();
1138 while(it!=m_createdDialogs.end()){
1139 if ((*it)->objectName()==oldName){
1140 it = m_createdDialogs.erase(it);
1141 } else {
1142 ++it;
1143 }
1144 }
1145 }
1146 return true;
1147 }
1148 }
1149 return false;
1150 }
1151
1152 bool ScriptEngineContext::previewDialog(const QString& dialogName)
1153 {
1154 QDialog* dialog = getDialog(dialogName);
1155 if (dialog) {
1156 dialog->exec();
1157 return true;
1158 } else {
1159 m_lastError = tr("Dialog with name: %1 can`t be created").arg(dialogName);
1160 return false;
1161 }
1162 }
1163
1164 bool ScriptEngineContext::containsDialog(const QString& dialogName)
1165 {
1166 foreach(DialogDescriber::Ptr dialog, m_dialogs){
1167 if (dialog->name()==dialogName)
1168 return true;
1169 }
1170 return false;
1171 }
1172
1173 void ScriptEngineContext::deleteDialog(const QString& dialogName)
1174 {
1175 {
1176 QVector<DialogDescriber::Ptr>::Iterator it = m_dialogs.begin();
1177 while(it!=m_dialogs.end()){
1178 if ((*it)->name()==dialogName){
1179 it = m_dialogs.erase(it);
1180 emit dialogDeleted(dialogName);
1181 } else {
1182 ++it;
1183 }
1184 }
1185 }
1186 {
1187 QList<DialogPtr>::Iterator it = m_createdDialogs.begin();
1188 while(it!=m_createdDialogs.end()){
1189 if ((*it)->objectName()==dialogName){
1190 it = m_createdDialogs.erase(it);
1191 } else {
1192 ++it;
1193 }
1194 }
1195 }
1196 }
1197
1198 #endif
1199
1200 void ScriptEngineContext::clear()
1201 {
1202 #ifdef HAVE_UI_LOADER
1203 m_dialogs.clear();
1204 m_createdDialogs.clear();
1205 #endif
1206 m_initScript.clear();
1207 m_tableOfContents->clear();
1208 m_lastError="";
1209 }
1210
1211 QObject* ScriptEngineContext::createElement(const QString& collectionName, const QString& elementType)
1212 {
1213 Q_UNUSED(elementType)
1214 #ifdef HAVE_UI_LOADER
1215 if (collectionName.compare("dialogs",Qt::CaseInsensitive)==0){
1216 m_dialogs.push_back(DialogDescriber::create());
1217 return m_dialogs.at(m_dialogs.count()-1).data();
1218 }
1219 #else
1220 Q_UNUSED(collectionName)
1221 #endif
1222 return 0;
1223 }
1224
1225 int ScriptEngineContext::elementsCount(const QString& collectionName)
1226 {
1227 #ifdef HAVE_UI_LOADER
1228 if (collectionName.compare("dialogs",Qt::CaseInsensitive)==0){
1229 return m_dialogs.count();
1230 };
1231 #else
1232 Q_UNUSED(collectionName)
1233 #endif
1234 return 0;
1235 }
1236
1237 QObject* ScriptEngineContext::elementAt(const QString& collectionName, int index)
1238 {
1239 #ifdef HAVE_UI_LOADER
1240 if (collectionName.compare("dialogs",Qt::CaseInsensitive)==0){
1241 return m_dialogs.at(index).data();
1242 };
1243 #else
1244 Q_UNUSED(collectionName)
1245 Q_UNUSED(index)
1246 #endif
1247 return 0;
1248 }
1249
1250 void ScriptEngineContext::collectionLoadFinished(const QString& collectionName)
1251 {
1252 Q_UNUSED(collectionName);
1253 }
1254
1255 ReportPages* ScriptEngineContext::reportPages() const
1256 {
1257 return m_reportPages;
1258 }
1259
1260 void ScriptEngineContext::setReportPages(ReportPages *value)
1261 {
1262 m_reportPages = value;
1263 }
1264
1265 #ifdef HAVE_UI_LOADER
1266 QDialog* ScriptEngineContext::createDialog(DialogDescriber* cont)
1267 {
1268 QUiLoader loader;
1269 QByteArray desc = cont->description();
1270 QBuffer buffer(&desc);
1271 buffer.open(QIODevice::ReadOnly);
1272 QDialog* dialog = dynamic_cast<QDialog*>(loader.load(&buffer));
1273 m_createdDialogs.push_back(QSharedPointer<QDialog>(dialog));
1274 if (cont->name().compare(dialog->objectName())){
1275 cont->setName(dialog->objectName());
1276 emit dialogNameChanged(dialog->objectName());
1277 }
1278 return dialog;
1279 }
1280
1281 QDialog* ScriptEngineContext::findDialog(const QString& dialogName)
1282 {
1283 foreach(DialogPtr dialog, m_createdDialogs){
1284 if (dialog->objectName()==dialogName)
1285 return dialog.data();
1286 }
1287 return 0;
1288 }
1289
1290 DialogDescriber* ScriptEngineContext::findDialogContainer(const QString& dialogName)
1291 {
1292 foreach (DialogDescriber::Ptr dialogCont , m_dialogs) {
1293 if (dialogCont->name().compare(dialogName,Qt::CaseInsensitive)==0){
1294 return dialogCont.data();
1295 }
1296 }
1297 return 0;
1298 }
1299
1300 TableOfContents* ScriptEngineContext::tableOfContents() const
1301 {
1302 return m_tableOfContents;
1303 }
1304
1305 void ScriptEngineContext::setTableOfContents(TableOfContents* tableOfContents)
1306 {
1307 m_tableOfContents = tableOfContents;
1308 }
1309
1310 PageItemDesignIntf* ScriptEngineContext::getCurrentPage() const
1311 {
1312 return m_currentPage;
1313 }
1314
1315 void ScriptEngineContext::setCurrentPage(PageItemDesignIntf* currentPage)
1316 {
1317 m_currentPage = currentPage;
1318 m_currentBand = 0;
1319 }
1320
1321 BandDesignIntf* ScriptEngineContext::getCurrentBand() const
1322 {
1323 return m_currentBand;
1324 }
1325
1326 void ScriptEngineContext::setCurrentBand(BandDesignIntf* currentBand)
1327 {
1328 m_currentBand = currentBand;
1329 }
1330
1331 QDialog* ScriptEngineContext::getDialog(const QString& dialogName)
1332 {
1333 QDialog* dialog = findDialog(dialogName);
1334 if (dialog){
1335 return dialog;
1336 } else {
1337 DialogDescriber* cont = findDialogContainer(dialogName);
1338 if (cont){
1339 dialog = createDialog(cont);
1340 if (dialog)
1341 return dialog;
1342 }
1343 }
1344 return 0;
1345 }
1346
1347 QString ScriptEngineContext::getNewDialogName()
1348 {
1349 QString result = "Dialog";
1350 int index = m_dialogs.size() - 1;
1351 while (containsDialog(result)){
1352 index++;
1353 result = QString("Dialog%1").arg(index);
1354 }
1355 return result;
1356 }
1357
1358 #endif
1359
1360 void ScriptEngineContext::baseDesignIntfToScript(const QString& pageName, BaseDesignIntf* item)
1361 {
1362 if ( item ) {
1363 if (item->metaObject()->indexOfSignal("beforeRender()")!=-1)
1364 item->disconnect(SIGNAL(beforeRender()));
1365 if (item->metaObject()->indexOfSignal("afterData()")!=-1)
1366 item->disconnect(SIGNAL(afterData()));
1367 if (item->metaObject()->indexOfSignal("afterRender()")!=-1)
1368 item->disconnect(SIGNAL(afterRender()));
1369
1370 ScriptEngineType* engine = ScriptEngineManager::instance().scriptEngine();
1371
1372 #ifdef USE_QJSENGINE
1373 ScriptValueType sItem = getJSValue(*engine, item);
1374 QString on = item->patternName().compare(pageName) == 0 ? pageName : pageName+"_"+item->patternName();
1375 engine->globalObject().setProperty(on, sItem);
1376 #else
1377 QString on = item->patternName().compare(pageName) == 0 ? pageName : pageName+"_"+item->patternName();
1378 ScriptValueType sItem = engine->globalObject().property(on);
1379 if (sItem.isValid()){
1380 engine->newQObject(sItem, item);
1381 } else {
1382 sItem = engine->newQObject(item);
1383 engine->globalObject().setProperty(on,sItem);
1384 }
1385 #endif
1386 foreach(BaseDesignIntf* child, item->childBaseItems()){
1387 baseDesignIntfToScript(pageName, child);
1388 }
1389 }
1390 }
1391
1392 void ScriptEngineContext::qobjectToScript(const QString& name, QObject *item)
1393 {
1394 ScriptEngineType* engine = ScriptEngineManager::instance().scriptEngine();
1395 #ifdef USE_QJSENGINE
1396 ScriptValueType sItem = getJSValue(*engine, item);
1397 engine->globalObject().setProperty(name, sItem);
1398 #else
1399 ScriptValueType sItem = engine->globalObject().property(name);
1400 if (sItem.isValid()){
1401 engine->newQObject(sItem, item);
1402 } else {
1403 sItem = engine->newQObject(item);
1404 engine->globalObject().setProperty(name,sItem);
1405 }
1406 #endif
1407 }
1408
1409 #ifdef HAVE_UI_LOADER
1410
1411 #ifdef USE_QJSENGINE
1412 void registerChildObjects(ScriptEngineType* se, ScriptValueType* sv){
1413 foreach(QObject* obj, sv->toQObject()->children()){
1414 ScriptValueType child = se->newQObject(obj);
1415 sv->setProperty(obj->objectName(),child);
1416 registerChildObjects(se, &child);
1417 }
1418 }
1419 #endif
1420
1421 void ScriptEngineContext::initDialogs(){
1422 ScriptEngineType* se = ScriptEngineManager::instance().scriptEngine();
1423 foreach(DialogDescriber::Ptr dialog, dialogDescribers()){
1424 ScriptValueType sv = se->newQObject(getDialog(dialog->name()));
1425 #ifdef USE_QJSENGINE
1426 registerChildObjects(se,&sv);
1427 #endif
1428 se->globalObject().setProperty(dialog->name(),sv);
1429 }
1430 }
1431
1432 #endif
1433
1434
1435 bool ScriptEngineContext::runInitScript(){
1436
1437 ScriptEngineType* engine = ScriptEngineManager::instance().scriptEngine();
1438 ScriptEngineManager::instance().setContext(this);
1439 m_tableOfContents->clear();
1440
1441 ScriptValueType res = engine->evaluate(initScript());
1442 if (res.isBool()) return res.toBool();
1443 #ifdef USE_QJSENGINE
1444 if (res.isError()){
1445 QMessageBox::critical(0,tr("Error"),
1446 QString("Line %1: %2 ").arg(res.property("lineNumber").toString())
1447 .arg(res.toString())
1448 );
1449 return false;
1450 }
1451 #else
1452 if (engine->hasUncaughtException()) {
1453 QMessageBox::critical(0,tr("Error"),
1454 QString("Line %1: %2 ").arg(engine->uncaughtExceptionLineNumber())
1455 .arg(engine->uncaughtException().toString())
1456 );
1457 return false;
1458 }
1459 #endif
1460 return true;
1461 }
1462
1463 QString ScriptEngineContext::initScript() const
1464 {
1465 return m_initScript;
1466 }
1467
1468 void ScriptEngineContext::setInitScript(const QString& initScript)
1469 {
1470 if (m_initScript != initScript){
1471 m_initScript = initScript;
1472 m_hasChanges = true;
1473 }
1474 }
1475
1476 DialogDescriber::Ptr DialogDescriber::create(const QString& name, const QByteArray& desc) {
1477 Ptr res(new DialogDescriber());
1478 res->setName(name);
1479 res->setDescription(desc);
1480 return res;
1481 }
1482
1483 QString JSFunctionDesc::name() const
1484 {
1485 return m_name;
1486 }
1487
1488 void JSFunctionDesc::setName(const QString &name)
1489 {
1490 m_name = name;
1491 }
1492
1493 QString JSFunctionDesc::category() const
1494 {
1495 return m_category;
1496 }
1497
1498 void JSFunctionDesc::setCategory(const QString &category)
1499 {
1500 m_category = category;
1501 }
1502
1503 QString JSFunctionDesc::description() const
1504 {
1505 return m_description;
1506 }
1507
1508 void JSFunctionDesc::setDescription(const QString &description)
1509 {
1510 m_description = description;
1511 }
1512
1513 QString JSFunctionDesc::managerName() const
1514 {
1515 return m_managerName;
1516 }
1517
1518 void JSFunctionDesc::setManagerName(const QString &managerName)
1519 {
1520 m_managerName = managerName;
1521 }
1522
1523 QObject *JSFunctionDesc::manager() const
1524 {
1525 return m_manager;
1526 }
1527
1528 void JSFunctionDesc::setManager(QObject *manager)
1529 {
1530 m_manager = manager;
1531 }
1532
1533 QString JSFunctionDesc::scriptWrapper() const
1534 {
1535 return m_scriptWrapper;
1536 }
1537
1538 void JSFunctionDesc::setScriptWrapper(const QString &scriptWrapper)
1539 {
1540 m_scriptWrapper = scriptWrapper;
1541 }
1542
1543 QVariant ScriptFunctionsManager::calcGroupFunction(const QString &name, const QString &expressionID, const QString &bandName, QObject* currentPage)
1544 {
1545 if (m_scriptEngineManager->dataManager()){
1546 PageItemDesignIntf* pageItem = dynamic_cast<PageItemDesignIntf*>(currentPage);
1547 QString expression = m_scriptEngineManager->dataManager()->getExpression(expressionID);
1548 GroupFunction* gf = m_scriptEngineManager->dataManager()->groupFunction(name,expression,bandName);
1549 if (gf){
1550 if (gf->isValid()){
1551 return gf->calculate(pageItem);
1552 }else{
1553 return gf->error();
1554 }
1555 }
1556 else {
1557 return QString(QObject::tr("Function %1 not found or have wrong arguments").arg(name));
1558 }
1559 } else {
1560 return QString(QObject::tr("Datasource manager not found"));
1561 }
1562 }
1563
1564 QVariant ScriptFunctionsManager::calcGroupFunction(const QString& name, const QString& expressionID, const QString& bandName)
1565 {
1566 return calcGroupFunction(name, expressionID, bandName, 0);
1567 }
1568
1569 QVariant ScriptFunctionsManager::line(const QString &bandName)
1570 {
1571 QString varName = QLatin1String("line_")+bandName.toLower();
1572 QVariant res;
1573 if (scriptEngineManager()->dataManager()->variable(varName).isValid()){
1574 res=scriptEngineManager()->dataManager()->variable(varName);
1575 } else res=QString("Variable line for band %1 not found").arg(bandName);
1576 return res;
1577 }
1578
1579 QVariant ScriptFunctionsManager::numberFormat(QVariant value, const char &format, int precision, const QString& locale)
1580 {
1581 return (locale.isEmpty()) ? QString::number(value.toDouble(),format,precision):
1582 QLocale(locale).toString(value.toDouble(),format,precision);
1583 }
1584
1585 QVariant ScriptFunctionsManager::dateFormat(QVariant value, const QString &format, const QString& locale)
1586 {
1587 return (locale.isEmpty()) ? QLocale().toString(value.toDate(),format) :
1588 QLocale(locale).toString(value.toDate(),format);
1589 }
1590
1591 QVariant ScriptFunctionsManager::timeFormat(QVariant value, const QString &format)
1592 {
1593 return QLocale().toString(value.toTime(),format);
1594 }
1595
1596 QVariant ScriptFunctionsManager::dateTimeFormat(QVariant value, const QString &format, const QString& locale)
1597 {
1598 return (locale.isEmpty()) ? QLocale().toString(value.toDateTime(),format) :
1599 QLocale(locale).toString(value.toDateTime(),format);
1600 }
1601
1602 QVariant ScriptFunctionsManager::sectotimeFormat(QVariant value, const QString &format)
1603 {
1604 int seconds = value.toInt();
1605 int minutes = seconds / 60;
1606 int hours = minutes / 60;
1607
1608 QString result = format;
1609 bool hasHour = format.contains("h");
1610 bool hasMinute = format.contains("m");
1611 for(int len = 2; len; len--) {
1612 if(hasHour) result.replace(QString('h').repeated(len), QString::number(hours).rightJustified(len, '0'));
1613 if(hasMinute) result.replace(QString('m').repeated(len), QString::number(hasHour ? minutes % 60 : minutes).rightJustified(len, '0'));
1614 result.replace(QString('s').repeated(len), QString::number(hasMinute ? seconds % 60 : seconds).rightJustified(len, '0'));
1615 }
1616 return result;
1617 }
1618
1619 QVariant ScriptFunctionsManager::date()
1620 {
1621 return QDate::currentDate();
1622 }
1623
1624 QVariant ScriptFunctionsManager::now()
1625 {
1626 return QDateTime::currentDateTime();
1627 }
1628
1629 QVariant ScriptFunctionsManager::currencyFormat(QVariant value, const QString &locale)
1630 {
1631 QString l = (!locale.isEmpty())?locale:QLocale::system().name();
1632 return QLocale(l).toCurrencyString(value.toDouble());
1633 }
1634
1635 QVariant ScriptFunctionsManager::currencyUSBasedFormat(QVariant value, const QString ¤cySymbol)
1636 {
1637 QString CurrencySymbol = (!currencySymbol.isEmpty())?currencySymbol:QLocale::system().currencySymbol();
1638 // Format it using USA locale
1639 QString vTempStr=QLocale(QLocale::English, QLocale::UnitedStates).toCurrencyString(value.toDouble());
1640 // Replace currency symbol if necesarry
1641 if (CurrencySymbol!="") vTempStr.replace("$", CurrencySymbol);
1642 return vTempStr;
1643 }
1644
1645 void ScriptFunctionsManager::setVariable(const QString &name, QVariant value)
1646 {
1647 DataSourceManager* dm = scriptEngineManager()->dataManager();
1648 if (dm->containsVariable(name)){
1649 dm->changeVariable(name,value);
1650 } else {
1651 dm->addVariable(name, value, VarDesc::User);
1652 }
1653 }
1654
1655 QVariant ScriptFunctionsManager::getVariable(const QString &name)
1656 {
1657 DataSourceManager* dm = scriptEngineManager()->dataManager();
1658 return dm->variable(name);
1659 }
1660
1661 QVariant ScriptFunctionsManager::getField(const QString &field)
1662 {
1663 DataSourceManager* dm = scriptEngineManager()->dataManager();
1664 return dm->fieldData(field);
1665 }
1666
1667 QVariant ScriptFunctionsManager::getFieldByKeyField(const QString& datasourceName, const QString& valueFieldName, const QString& keyFieldName, QVariant keyValue)
1668 {
1669 DataSourceManager* dm = scriptEngineManager()->dataManager();
1670 return dm->fieldDataByKey(datasourceName, valueFieldName, keyFieldName, keyValue);
1671 }
1672
1673 QVariant ScriptFunctionsManager::getFieldByRowIndex(const QString &fieldName, int rowIndex)
1674 {
1675 DataSourceManager* dm = scriptEngineManager()->dataManager();
1676 return dm->fieldDataByRowIndex(fieldName, rowIndex);
1677 }
1678
1679 void ScriptFunctionsManager::reopenDatasource(const QString& datasourceName)
1680 {
1681 DataSourceManager* dm = scriptEngineManager()->dataManager();
1682 return dm->reopenDatasource(datasourceName);
1683 }
1684
1685 void ScriptFunctionsManager::addBookmark(const QString &uniqKey, const QString &content)
1686 {
1687 scriptEngineManager()->addBookMark(uniqKey, content);
1688 }
1689
1690 int ScriptFunctionsManager::findPageIndexByBookmark(const QString &uniqKey)
1691 {
1692 return scriptEngineManager()->findPageIndexByBookmark(uniqKey);
1693 }
1694
1695 void ScriptFunctionsManager::addTableOfContentsItem(const QString& uniqKey, const QString& content, int indent)
1696 {
1697 scriptEngineManager()->addTableOfContentsItem(uniqKey, content, indent);
1698 }
1699
1700 void ScriptFunctionsManager::clearTableOfContents()
1701 {
1702 scriptEngineManager()->clearTableOfContents();
1703 }
1704
1705 QFont ScriptFunctionsManager::font(const QString &family, int pointSize, bool italic, bool bold, bool underLine)
1706 {
1707 QFont result (family, pointSize);
1708 result.setBold(bold);
1709 result.setItalic(italic);
1710 result.setUnderline(underLine);
1711 return result;
1712 }
1713
1714 #ifdef USE_QJSENGINE
1715
1716 void ScriptFunctionsManager::addItemsToComboBox(QJSValue object, const QStringList &values)
1717 {
1718 QComboBox* comboBox = dynamic_cast<QComboBox*>(object.toQObject());
1719 if (comboBox){
1720 comboBox->addItems(values);
1721 }
1722 }
1723
1724 void ScriptFunctionsManager::addItemToComboBox(QJSValue object, const QString &value)
1725 {
1726 QComboBox* comboBox = dynamic_cast<QComboBox*>(object.toQObject());
1727 if (comboBox){
1728 comboBox->addItem(value);
1729 }
1730 }
1731
1732 QJSValue ScriptFunctionsManager::createComboBoxWrapper(QJSValue comboBox)
1733 {
1734 QComboBox* item = dynamic_cast<QComboBox*>(comboBox.toQObject());
1735 if (item){
1736 ComboBoxWrapper* wrapper = new ComboBoxWrapper(item);
1737 return m_scriptEngineManager->scriptEngine()->newQObject(wrapper);
1738 }
1739 return QJSValue();
1740 }
1741
1742 QJSValue ScriptFunctionsManager::createWrapper(QJSValue item)
1743 {
1744 QObject* object = item.toQObject();
1745 if (object){
1746 IWrapperCreator* wrapper = m_wrappersFactory.value(object->metaObject()->className());
1747 if (wrapper){
1748 return m_scriptEngineManager->scriptEngine()->newQObject(wrapper->createWrapper(item.toQObject()));
1749 }
1750 }
1751 return QJSValue();
1752 }
1753
1754 #else
1755
1756 void ScriptFunctionsManager::addItemsToComboBox(QScriptValue object, const QStringList &values)
1757 {
1758 QComboBox* comboBox = dynamic_cast<QComboBox*>(object.toQObject());
1759 if (comboBox){
1760 comboBox->addItems(values);
1761 }
1762 }
1763
1764 void ScriptFunctionsManager::addItemToComboBox(QScriptValue object, const QString &value)
1765 {
1766 QComboBox* comboBox = dynamic_cast<QComboBox*>(object.toQObject());
1767 if (comboBox){
1768 comboBox->addItem(value);
1769 }
1770 }
1771
1772 QScriptValue ScriptFunctionsManager::createComboBoxWrapper(QScriptValue comboBox)
1773 {
1774 QComboBox* item = dynamic_cast<QComboBox*>(comboBox.toQObject());
1775 if (item){
1776 ComboBoxWrapper* wrapper = new ComboBoxWrapper(item);
1777 return m_scriptEngineManager->scriptEngine()->newQObject(wrapper);
1778 }
1779 return QScriptValue();
1780 }
1781
1782 QScriptValue ScriptFunctionsManager::createWrapper(QScriptValue item)
1783 {
1784 QObject* object = item.toQObject();
1785 if (object){
1786 IWrapperCreator* wrapper = m_wrappersFactory.value(object->metaObject()->className());
1787 if (wrapper){
1788 return m_scriptEngineManager->scriptEngine()->newQObject(wrapper->createWrapper(item.toQObject()));
1789 }
1790 }
1791 return QScriptValue();
1792 }
1793
1794 #endif
1795
1796 QFont ScriptFunctionsManager::font(QVariantMap params){
1797 if (!params.contains("family")){
1798 return QFont();
1799 } else {
1800 QFont result(params.value("family").toString());
1801 if (params.contains("pointSize"))
1802 result.setPointSize(params.value("pointSize").toInt());
1803 if (params.contains("bold"))
1804 result.setBold(params.value("bold").toBool());
1805 if (params.contains("italic"))
1806 result.setItalic(params.value("italic").toBool());
1807 if (params.contains("underline"))
1808 result.setUnderline(params.value("underline").toBool());
1809 return result;
1810 }
1811 }
1812
1813 ScriptEngineManager *ScriptFunctionsManager::scriptEngineManager() const
1814 {
1815 return m_scriptEngineManager;
1816 }
1817
1818 void ScriptFunctionsManager::setScriptEngineManager(ScriptEngineManager *scriptEngineManager)
1819 {
1820 m_scriptEngineManager = scriptEngineManager;
1821 }
1822
1823 TableOfContents::~TableOfContents()
1824 {
1825 clear();
1826 }
1827
1828 void TableOfContents::setItem(const QString& uniqKey, const QString& content, int pageNumber, int indent)
1829 {
1830 ContentItem * item = 0;
1831 if (m_hash.contains(uniqKey)){
1832 item = m_hash.value(uniqKey);
1833 item->content = content;
1834 item->pageNumber = pageNumber;
1835 if (indent>0)
1836 item->indent = indent;
1837 } else {
1838 item = new ContentItem;
1839 item->content = content;
1840 item->pageNumber = pageNumber;
1841 item->indent = indent;
1842 item->uniqKey = uniqKey;
1843 m_tableOfContents.append(item);
1844 m_hash.insert(uniqKey, item);
1845 }
1846
1847 }
1848
1849 void TableOfContents::slotOneSlotDS(CallbackInfo info, QVariant& data)
1850 {
1851 QStringList columns;
1852 columns << "Content" << "Page number" << "Content Key";
1853
1854 switch (info.dataType) {
1855 case LimeReport::CallbackInfo::RowCount:
1856 data = m_tableOfContents.count();
1857 break;
1858 case LimeReport::CallbackInfo::ColumnCount:
1859 data = columns.size();
1860 break;
1861 case LimeReport::CallbackInfo::ColumnHeaderData: {
1862 data = columns.at(info.index);
1863 break;
1864 }
1865 case LimeReport::CallbackInfo::ColumnData:
1866 if (info.index < m_tableOfContents.count()){
1867 ContentItem* item = m_tableOfContents.at(info.index);
1868 if (info.columnName.compare("Content",Qt::CaseInsensitive) == 0)
1869 data = item->content.rightJustified(item->indent+item->content.size());
1870 if (info.columnName.compare("Content Key",Qt::CaseInsensitive) == 0)
1871 data = item->uniqKey;
1872 if (info.columnName.compare("Page number",Qt::CaseInsensitive) == 0)
1873 data = QString::number(item->pageNumber);
1874 }
1875 break;
1876 default: break;
1877 }
1878 }
1879
1880 void LimeReport::TableOfContents::clear(){
1881
1882 m_hash.clear();
1883 foreach(ContentItem* item, m_tableOfContents){
1884 delete item;
1885 }
1886 m_tableOfContents.clear();
1887
1888 }
1889
1890 QObject* ComboBoxWrapperCreator::createWrapper(QObject *item)
1891 {
1892 QComboBox* comboBox = dynamic_cast<QComboBox*>(item);
1893 if (comboBox){
1894 return new ComboBoxWrapper(comboBox);
1895 }
1896 return 0;
1897 }
1898
1899 bool DatasourceFunctions::first(const QString& datasourceName)
1900 {
1901 if (m_dataManager && m_dataManager->dataSource(datasourceName)){
1902 m_dataManager->dataSource(datasourceName)->first();
1903 return true;
1904 }
1905 return false;
1906 }
1907
1908 bool DatasourceFunctions::next(const QString &datasourceName){
1909 if (m_dataManager && m_dataManager->dataSource(datasourceName))
1910 return m_dataManager->dataSource(datasourceName)->next();
1911 return false;
1912 }
1913
1914 bool DatasourceFunctions::prior(const QString& datasourceName)
1915 {
1916 if (m_dataManager && m_dataManager->dataSource(datasourceName))
1917 return m_dataManager->dataSource(datasourceName)->prior();
1918 return false;
1919 }
1920
1921 bool DatasourceFunctions::isEOF(const QString &datasourceName)
1922 {
1923 if (m_dataManager && m_dataManager->dataSource(datasourceName))
1924 return m_dataManager->dataSource(datasourceName)->eof();
1925 return true;
1926 }
1927
1928 bool DatasourceFunctions::invalidate(const QString& datasourceName)
1929 {
1930 if (m_dataManager && m_dataManager->dataSource(datasourceName)){
1931 m_dataManager->dataSourceHolder(datasourceName)->invalidate(IDataSource::RENDER_MODE);
1932 return true;
1933 }
1934 return false;
1935 }
1936
1937 QObject* DatasourceFunctions::createTableBuilder(BaseDesignIntf* horizontalLayout)
1938 {
1939 return new TableBuilder(dynamic_cast<LimeReport::HorizontalLayout*>(horizontalLayout), dynamic_cast<DataSourceManager*>(m_dataManager));
1940 }
1941
1942 TableBuilder::TableBuilder(HorizontalLayout* layout, DataSourceManager* dataManager)
1943 : m_horizontalLayout(layout), m_baseLayout(0), m_dataManager(dataManager)
1944 {
1945 if (m_horizontalLayout)
1946 m_patternLayout = dynamic_cast<HorizontalLayout*>(m_horizontalLayout->cloneItem(m_horizontalLayout->itemMode()));
1947 }
1948
1949 QObject* TableBuilder::addRow()
1950 {
1951 checkBaseLayout();
1952 if (m_baseLayout && m_patternLayout){
1953 HorizontalLayout* newRow = new HorizontalLayout(m_baseLayout, m_baseLayout);
1954 newRow->setLayoutSpacing(m_horizontalLayout->layoutSpacing());
1955 for(int i = 0; i < m_horizontalLayout->childrenCount(); ++i){
1956 BaseDesignIntf* item = dynamic_cast<BaseDesignIntf*>(m_patternLayout->at(i));
1957 BaseDesignIntf* cloneItem = item->cloneItem(item->itemMode(), newRow, newRow);
1958 newRow->addChild(cloneItem);
1959 }
1960 m_baseLayout->addChild(newRow);
1961 return newRow;
1962 } else return 0;
1963 }
1964
1965 QObject* TableBuilder::currentRow()
1966 {
1967 checkBaseLayout();
1968 if (m_baseLayout && m_baseLayout->childrenCount()>0)
1969 return m_baseLayout->at(m_baseLayout->childrenCount()-1);
1970 return 0;
1971 }
1972
1973 void TableBuilder::fillInRowData(QObject* row)
1974 {
1975 HorizontalLayout* layout = dynamic_cast<HorizontalLayout*>(row);
1976 if (layout){
1977 for (int i = 0; i < layout->childrenCount(); ++i) {
1978 BaseDesignIntf* item = dynamic_cast<BaseDesignIntf*>(layout->at(i));
1979 DataSourceManager* dm = dynamic_cast<DataSourceManager*>(m_dataManager);
1980 if (item && dm)
1981 item->updateItemSize(dm);
1982 }
1983 }
1984 }
1985
1986 void TableBuilder::buildTable(const QString& datasourceName)
1987 {
1988 checkBaseLayout();
1989 m_dataManager->dataSourceHolder(datasourceName)->invalidate(IDataSource::RENDER_MODE);
1990 m_dataManager->dataSource(datasourceName)->first();
1991 bool firstTime = true;
1992 QObject* row = m_horizontalLayout;
1993 while(!m_dataManager->dataSource(datasourceName)->eof()){
1994 if (!firstTime) row = addRow();
1995 else firstTime = false;
1996 fillInRowData(row);
1997 m_dataManager->dataSource(datasourceName)->next();
1998 }
1999 }
2000
2001 void TableBuilder::checkBaseLayout()
2002 {
2003 if (!m_baseLayout){
2004 m_baseLayout = dynamic_cast<VerticalLayout*>(m_horizontalLayout->parentItem());
2005 if (!m_baseLayout){
2006 m_baseLayout = new VerticalLayout(m_horizontalLayout->parent(), m_horizontalLayout->parentItem());
2007 m_baseLayout->setItemLocation(m_horizontalLayout->itemLocation());
2008 m_baseLayout->setPos(m_horizontalLayout->pos());
2009 m_baseLayout->setWidth(m_horizontalLayout->width());
2010 m_baseLayout->setHeight(0);
2011 m_baseLayout->addChild(m_horizontalLayout);
2012 m_baseLayout->setObjectName(QUuid::createUuid().toString());
2013 m_baseLayout->setItemTypeName("VerticalLayout");
2014 }
2015 }
2016 }
2017
2018 #ifdef USE_QTSCRIPTENGINE
2019 void ComboBoxPrototype::addItem(const QString &text)
2020 {
2021 QComboBox* comboBox = qscriptvalue_cast<QComboBox*>(thisObject());
2022 if (comboBox){
2023 comboBox->addItem(text);
2024 }
2025 }
2026
2027 void ComboBoxPrototype::addItems(const QStringList &texts)
2028 {
2029 QComboBox* comboBox = qscriptvalue_cast<QComboBox*>(thisObject());
2030 if (comboBox){
2031 comboBox->addItems(texts);
2032 }
2033 }
2034 #endif
2035
2036 } //namespace LimeReport
2037
2038