0
0
mirror of https://github.com/fralx/LimeReport.git synced 2024-12-26 01:24:39 +03:00
LimeReport/limereport/scripteditor/lrscripteditor.cpp
2018-04-18 21:37:05 +03:00

404 lines
13 KiB
C++

#include "lrscripteditor.h"
#include "ui_lrscripteditor.h"
#ifdef USE_QJSENGINE
#include <QJSValueIterator>
#endif
#include "lrdatasourcemanager.h"
#include "lrscriptenginemanager.h"
#include "lrdatadesignintf.h"
#include "lrreportengine_p.h"
namespace LimeReport{
ScriptEditor::ScriptEditor(QWidget *parent) :
QWidget(parent),
ui(new Ui::ScriptEditor), m_reportEngine(0), m_page(0)
{
ui->setupUi(this);
setFocusProxy(ui->textEdit);
m_completer = new ReportStructureCompleater(this);
ui->textEdit->setCompleter(m_completer);
connect(ui->splitter, SIGNAL(splitterMoved(int,int)), this, SIGNAL(splitterMoved(int,int)));
}
ScriptEditor::~ScriptEditor()
{
delete ui;
}
void ScriptEditor::initEditor(DataSourceManager* dm)
{
ScriptEngineManager& se = LimeReport::ScriptEngineManager::instance();
se.setDataManager(dm);
initCompleter();
if (dm){
if (dm->isNeedUpdateDatasourceModel())
dm->updateDatasourceModel();
ui->twData->setModel(dm->datasourcesModel());
ui->twScriptEngine->setModel(se.model());
}
if (ui->twScriptEngine->selectionModel()){
connect(ui->twScriptEngine->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
this, SLOT(slotOnCurrentChanged(QModelIndex,QModelIndex)));
}
}
void ScriptEditor::setReportEngine(ReportEnginePrivateInterface* reportEngine)
{
m_reportEngine = reportEngine;
DataSourceManager* dm = m_reportEngine->dataManager();
initEditor(dm);
}
void ScriptEditor::setReportPage(PageDesignIntf* page)
{
m_page = page;
DataSourceManager* dm = page->datasourceManager();
initEditor(dm);
}
void ScriptEditor::setPageBand(BandDesignIntf* band)
{
if (band && ui->twData->model() && !band->datasourceName().isEmpty()){
QModelIndexList nodes = ui->twData->model()->match(
ui->twData->model()->index(0,0),
Qt::DisplayRole,
band->datasourceName(),
2,
Qt::MatchRecursive
);
if (!nodes.isEmpty()){
ui->twData->expand(nodes.at(0).parent());
ui->twData->expand(nodes.at(0));
}
}
}
void ScriptEditor::initCompleter()
{
// QStringList dataWords;
// DataSourceManager* dm = 0;
// if (m_reportEngine)
// dm = m_reportEngine->dataManager();
// if (m_page)
// dm = m_page->datasourceManager();
//#ifdef USE_QJSENGINE
// ScriptEngineManager& se = LimeReport::ScriptEngineManager::instance();
// QJSValue globalObject = se.scriptEngine()->globalObject();
// QJSValueIterator it(globalObject);
// while (it.hasNext()){
// it.next();
// if (it.value().isCallable() ){
// dataWords << it.name();
// }
// }
//#endif
// foreach(const QString &dsName,dm->dataSourceNames()){
// dataWords << dsName;
// foreach(const QString &field, dm->fieldNames(dsName)){
// dataWords<<dsName+"."+field;
// }
// }
// foreach (QString varName, dm->variableNames()) {
// dataWords << varName.remove("#");
// }
// if (m_reportEngine){
// for ( int i = 0; i < m_reportEngine->pageCount(); ++i){
// PageDesignIntf* page = m_reportEngine->pageAt(i);
// dataWords << page->pageItem()->objectName();
// QMetaObject const * mo = page->pageItem()->metaObject();
// for(int i = mo->methodOffset(); i < mo->methodCount(); ++i)
// {
// if (mo->method(i).methodType() == QMetaMethod::Signal) {
// dataWords << page->pageItem()->objectName() +"."+QString::fromLatin1(mo->method(i).name());
// }
// }
// dataWords << page->pageItem()->objectName()+".beforeRender";
// dataWords << page->pageItem()->objectName()+".afterRender";
// foreach (BaseDesignIntf* item, page->pageItem()->childBaseItems()){
// addItemToCompleater(page->pageItem()->objectName(), item, dataWords);
// }
// }
// }
// dataWords.sort();
if (m_reportEngine)
m_completer->updateCompleaterModel(m_reportEngine);
else
m_completer->updateCompleaterModel(m_page->datasourceManager());
}
QByteArray ScriptEditor::saveState()
{
return ui->splitter->saveState();
}
void ScriptEditor::restoreState(QByteArray state)
{
ui->splitter->restoreState(state);
}
void ScriptEditor::setPlainText(const QString& text)
{
ui->textEdit->setPlainText(text);
}
void ScriptEditor::setEditorFont(QFont font)
{
ui->textEdit->setFont(font);
}
QFont ScriptEditor::editorFont()
{
return ui->textEdit->font();
}
QString ScriptEditor::toPlainText()
{
return ui->textEdit->toPlainText();
}
void ScriptEditor::addItemToCompleater(const QString& pageName, BaseDesignIntf* item, QStringList& dataWords)
{
BandDesignIntf* band = dynamic_cast<BandDesignIntf*>(item);
if (band){
dataWords << band->objectName();
dataWords << pageName+"_"+band->objectName();
dataWords << pageName+"_"+band->objectName()+".beforeRender";
dataWords << pageName+"_"+item->objectName()+".afterData";
dataWords << pageName+"_"+band->objectName()+".afterRender";
foreach (BaseDesignIntf* child, band->childBaseItems()){
addItemToCompleater(pageName, child, dataWords);
}
} else {
dataWords << item->objectName();
dataWords << pageName+"_"+item->objectName();
dataWords << pageName+"_"+item->objectName()+".beforeRender";
dataWords << pageName+"_"+item->objectName()+".afterData";
dataWords << pageName+"_"+item->objectName()+".afterRender";
}
}
void ScriptEditor::on_twData_doubleClicked(const QModelIndex &index)
{
if (!index.isValid()) return;
LimeReport::DataNode* node = static_cast<LimeReport::DataNode*>(index.internalPointer());
if (node->type()==LimeReport::DataNode::Field){
ui->textEdit->insertPlainText(QString("$D{%1.%2}").arg(node->parent()->name()).arg(node->name()));
}
if (node->type()==LimeReport::DataNode::Variable){
ui->textEdit->insertPlainText(QString("$V{%1}").arg(node->name()));
}
ui->textEdit->setFocus();
}
void ScriptEditor::on_twScriptEngine_doubleClicked(const QModelIndex &index)
{
if (!index.isValid()) return;
LimeReport::ScriptEngineNode* node = static_cast<LimeReport::ScriptEngineNode*>(index.internalPointer());
if (node->type()==LimeReport::ScriptEngineNode::Function){
ui->textEdit->insertPlainText(node->name()+"()");
}
ui->textEdit->setFocus();
}
void ScriptEditor::slotOnCurrentChanged(const QModelIndex &to, const QModelIndex &)
{
LimeReport::ScriptEngineNode* node = static_cast<LimeReport::ScriptEngineNode*>(to.internalPointer());
if (node->type()==LimeReport::ScriptEngineNode::Function){
ui->lblDescription->setText(node->description());
}
}
QString ReportStructureCompleater::pathFromIndex(const QModelIndex &index) const
{
QStringList dataList;
for (QModelIndex i = index; i.isValid(); i = i.parent()) {
dataList.prepend(model()->data(i, Qt::DisplayRole).toString());
}
return dataList.join(".");
}
QStringList ReportStructureCompleater::splitPath(const QString &path) const
{
return path.split(".");
}
void ReportStructureCompleater::addAdditionalDatawords(DataSourceManager* dataManager){
foreach(const QString &dsName,dataManager->dataSourceNames()){
QStandardItem* dsNode = new QStandardItem;
dsNode->setText(dsName);
foreach(const QString &field, dataManager->fieldNames(dsName)){
QStandardItem* fieldNode = new QStandardItem;
fieldNode->setText(field);
dsNode->appendRow(fieldNode);
}
m_model.invisibleRootItem()->appendRow(dsNode);
}
foreach (QString varName, dataManager->variableNames()) {
QStandardItem* varNode = new QStandardItem;
varNode->setText(varName.remove("#"));
m_model.invisibleRootItem()->appendRow(varNode);
}
#ifdef USE_QJSENGINE
ScriptEngineManager& se = LimeReport::ScriptEngineManager::instance();
QJSValue globalObject = se.scriptEngine()->globalObject();
QJSValueIterator it(globalObject);
while (it.hasNext()){
it.next();
if (it.value().isCallable() ){
QStandardItem* itemNode = new QStandardItem;
itemNode->setText(it.name());
m_model.invisibleRootItem()->appendRow(itemNode);
}
}
#endif
}
void ReportStructureCompleater::updateCompleaterModel(ReportEnginePrivateInterface* report)
{
if (report){
m_model.clear();
QIcon signalIcon(":/report/images/signal");
QIcon propertyIcon(":/report/images/property");
addAdditionalDatawords(report->dataManager());
for ( int i = 0; i < report->pageCount(); ++i){
PageDesignIntf* page = report->pageAt(i);
QStandardItem* itemNode = new QStandardItem;
itemNode->setText(page->pageItem()->objectName());
itemNode->setIcon(QIcon(":/report/images/object"));
m_model.invisibleRootItem()->appendRow(itemNode);
QStringList items = extractSignalNames(page->pageItem());
foreach(QString slotName, items){
QStandardItem* slotItem = new QStandardItem;
slotItem->setText(slotName);
slotItem->setIcon(signalIcon);
itemNode->appendRow(slotItem);
}
items = extractProperties(page->pageItem());
foreach(QString propertyName, items){
QStandardItem* properyItem = new QStandardItem;
properyItem->setText(propertyName);
properyItem->setIcon(propertyIcon);
itemNode->appendRow(properyItem);
}
foreach (BaseDesignIntf* item, page->pageItem()->childBaseItems()){
addChildItem(item, itemNode->text(), m_model.invisibleRootItem());
}
}
}
}
void ReportStructureCompleater::updateCompleaterModel(DataSourceManager *dataManager)
{
m_model.clear();
addAdditionalDatawords(dataManager);
}
QStringList ReportStructureCompleater::extractSignalNames(BaseDesignIntf *item)
{
QStringList result;
if (!item) return result;
QMetaObject const * mo = item->metaObject();
while (mo){
for(int i = mo->methodOffset(); i < mo->methodCount(); ++i)
{
if (mo->method(i).methodType() == QMetaMethod::Signal) {
#ifndef HAVE_QT4
result.append(QString::fromLatin1(mo->method(i).name()));
#else
result.append(QString::fromLatin1(mo->method(i).signature()));
#endif
}
}
mo = mo->superClass();
}
result.sort();
return result;
}
QStringList ReportStructureCompleater::extractProperties(BaseDesignIntf *item)
{
QStringList result;
if (!item) return result;
QMetaObject const * mo = item->metaObject();
while (mo){
for(int i = mo->propertyOffset(); i < mo->propertyCount(); ++i)
{
result.append(QString::fromLatin1(mo->property(i).name()));
}
mo = mo->superClass();
}
result.sort();
return result;
}
void ReportStructureCompleater::addChildItem(BaseDesignIntf *item, const QString &pageName, QStandardItem *parent)
{
if (!item) return;
QIcon signalIcon(":/report/images/signal");
QIcon propertyIcon(":/report/images/property");
QStandardItem* itemNode = new QStandardItem;
itemNode->setText(pageName+"_"+item->objectName());
itemNode->setIcon(QIcon(":/report/images/object"));
parent->appendRow(itemNode);
QStringList items;
if (!m_signals.contains(item->metaObject()->className())){
items = extractSignalNames(item);
m_signals.insert(item->metaObject()->className(),items);
} else {
items = m_signals.value(item->metaObject()->className());
}
foreach(QString slotName, items){
QStandardItem* slotItem = new QStandardItem;
slotItem->setText(slotName);
slotItem->setIcon(signalIcon);
itemNode->appendRow(slotItem);
}
if (!m_properties.contains(item->metaObject()->className())){
items = extractProperties(item);
m_properties.insert(item->metaObject()->className(),items);
} else {
items = m_properties.value(item->metaObject()->className());
}
foreach(QString propertyName, items){
QStandardItem* properyItem = new QStandardItem;
properyItem->setText(propertyName);
properyItem->setIcon(propertyIcon);
itemNode->appendRow(properyItem);
}
foreach (BaseDesignIntf* child, item->childBaseItems()){
addChildItem(child, pageName, parent);
}
}
} // namespace LimeReport