diff --git a/limereport/databrowser/lrdatabrowser.cpp b/limereport/databrowser/lrdatabrowser.cpp index 10de89e..5e335f2 100644 --- a/limereport/databrowser/lrdatabrowser.cpp +++ b/limereport/databrowser/lrdatabrowser.cpp @@ -46,7 +46,6 @@ #include "lrconnectiondialog.h" #include "lrreportengine_p.h" #include "lrvariabledialog.h" -#include "lrdatabrowsertree.h" namespace LimeReport{ @@ -596,8 +595,8 @@ void DataBrowser::changeQuery(SQLEditResult result) { try { m_report->dataManager()->removeDatasource(result.oldDatasourceName); - m_report->dataManager()->addQuery(result.datasourceName, result.sql, result.connectionName); - }catch(ReportError &exception){ + addQuery(result); + } catch(ReportError &exception){ qDebug()<dataManager()->removeDatasource(result.oldDatasourceName); - m_report->dataManager()->addSubQuery(result.datasourceName, result.sql, result.connectionName, result.masterDatasource); - }catch(ReportError &exception){ + addSubQuery(result); + } catch(ReportError &exception){ qDebug()<dataManager()->removeDatasource(result.oldDatasourceName); - m_report->dataManager()->addProxy(result.datasourceName,result.masterDatasource,result.childDataSource,result.fieldMap); + addProxy(result); + } catch(ReportError &exception){ + qDebug()<dataManager()->addCSV( + result.datasourceName, + result.csv, + result.separator, + result.firstRowIsHeader + ); + } catch(ReportError &exception){ + qDebug()<dataManager()->removeDatasource(result.oldDatasourceName); + addCSV(result); } catch(ReportError &exception){ qDebug()<dataManager()->isQuery(datasourceName)) return SQLEditResult::Query; if (m_report->dataManager()->isSubQuery(datasourceName)) return SQLEditResult::SubQuery; if (m_report->dataManager()->isProxy(datasourceName)) return SQLEditResult::SubProxy; + if (m_report->dataManager()->isCSV(datasourceName)) return SQLEditResult::CSVText; return SQLEditResult::Undefined; } @@ -662,12 +686,16 @@ void DataBrowser::applyChanges(SQLEditResult result) case SQLEditResult::SubProxy: changeProxy(result); break; + case SQLEditResult::CSVText: + changeCSV(result); + break; default: break; } } else { removeDatasource(result.datasourceName); addDatasource(result); } + activateItem(result.datasourceName, DataBrowserTree::Table); } void DataBrowser::addDatasource(SQLEditResult result) @@ -682,21 +710,32 @@ void DataBrowser::addDatasource(SQLEditResult result) case SQLEditResult::SubProxy: addProxy(result); break; + case SQLEditResult::CSVText: + addCSV(result); + break; default: break; } + activateItem(result.datasourceName, DataBrowserTree::Table); +} + +void DataBrowser::activateItem(const QString& name, DataBrowserTree::NodeType type){ + QTreeWidgetItem* item = findByNameAndType(name, type); + item->treeWidget()->setCurrentItem(item); } void DataBrowser::addConnectionDesc(ConnectionDesc *connection) { m_report->dataManager()->addConnectionDesc(connection); updateDataTree(); + activateItem(connection->name(), DataBrowserTree::Connection); } void DataBrowser::changeConnectionDesc(ConnectionDesc *connection) { if (connection->autoconnect()) m_report->dataManager()->connectConnection(connection->name()); updateDataTree(); + activateItem(connection->name(), DataBrowserTree::Connection); } bool DataBrowser::checkConnectionDesc(ConnectionDesc *connection) diff --git a/limereport/databrowser/lrdatabrowser.h b/limereport/databrowser/lrdatabrowser.h index 3e4bfd3..f0c5144 100644 --- a/limereport/databrowser/lrdatabrowser.h +++ b/limereport/databrowser/lrdatabrowser.h @@ -37,6 +37,7 @@ #include "lrreportdesignwidget.h" #include "lrsqleditdialog.h" +#include "lrdatabrowsertree.h" namespace LimeReport{ @@ -105,7 +106,8 @@ private: void changeSubQuery(SQLEditResult result); void addProxy(SQLEditResult result); void changeProxy(SQLEditResult result); - + void addCSV(SQLEditResult result); + void changeCSV(SQLEditResult result); SQLEditResult::ResultMode currentDatasourceType(const QString& datasourceName); void applyChanges(SQLEditResult result); @@ -115,6 +117,7 @@ private: void changeConnectionDesc(ConnectionDesc *connection); bool checkConnectionDesc(ConnectionDesc *connection); bool containsDefaultConnection(); + void activateItem(const QString &name, DataBrowserTree::NodeType type); private: Ui::DataBrowser* ui; diff --git a/limereport/databrowser/lrsqleditdialog.cpp b/limereport/databrowser/lrsqleditdialog.cpp index 2a05e69..d53bc3d 100644 --- a/limereport/databrowser/lrsqleditdialog.cpp +++ b/limereport/databrowser/lrsqleditdialog.cpp @@ -86,7 +86,7 @@ QSettings *SQLEditDialog::settings(){ void SQLEditDialog::setSettings(QSettings *value, bool owned){ if (m_settings && m_ownedSettings) delete m_settings; - m_settings=value; + m_settings = value; m_ownedSettings = owned; } @@ -94,24 +94,29 @@ void SQLEditDialog::accept() { SQLEditResult result; - if (!ui->cbSubdetail->isChecked()){ + if (ui->tabWidget->currentIndex() == 1){ + result.resultMode = SQLEditResult::CSVText; + } else if (!ui->cbSubdetail->isChecked()){ result.resultMode=SQLEditResult::Query; } else { - if (ui->rbSubQuery->isChecked()) result.resultMode=SQLEditResult::SubQuery; + if (ui->rbSubQuery->isChecked()) result.resultMode = SQLEditResult::SubQuery; else result.resultMode=SQLEditResult::SubProxy; } result.connectionName = ConnectionDesc::connectionNameForReport(ui->cbbConnection->currentText()); result.datasourceName=ui->leDatasourceName->text(); - result.sql=ui->textEditSQL->toPlainText(); - result.dialogMode=m_dialogMode; - result.oldDatasourceName=m_oldDatasourceName; + result.sql = ui->sqlText->toPlainText(); + result.csv = ui->csvText->toPlainText(); + result.dialogMode = m_dialogMode; + result.oldDatasourceName = m_oldDatasourceName; result.subdetail = ui->cbSubdetail->isChecked(); result.masterDatasource=ui->leMaster->text(); result.childDataSource=ui->leChild->text(); + result.separator = ui->leSeparator->text(); + result.firstRowIsHeader = ui->cbUseFirstRowAsHeader->isChecked(); - if (ui->fieldsMap->rowCount()>0){ - for(int i=0;ifieldsMap->rowCount();++i){ + if (ui->fieldsMap->rowCount() > 0){ + for(int i=0; i< ui->fieldsMap->rowCount(); ++i){ LimeReport::FieldsCorrelation fieldsCorrelation; fieldsCorrelation.master = ui->fieldsMap->item(i,0) ? ui->fieldsMap->item(i,0)->data(Qt::DisplayRole).toString() : ""; fieldsCorrelation.detail = ui->fieldsMap->item(i,1) ? ui->fieldsMap->item(i,1)->data(Qt::DisplayRole).toString() : ""; @@ -148,7 +153,7 @@ void SQLEditDialog::hideEvent(QHideEvent *) void SQLEditDialog::check() { if (ui->leDatasourceName->text().isEmpty()) throw LimeReport::ReportError(tr("Datasource Name is empty!")); - if (ui->textEditSQL->toPlainText().isEmpty() && (!ui->rbProxy) ) throw LimeReport::ReportError(tr("SQL is empty!")); + if (ui->sqlText->toPlainText().isEmpty() && (!ui->rbProxy) ) throw LimeReport::ReportError(tr("SQL is empty!")); if (m_dialogMode==AddMode){ if (m_datasources->containsDatasource(ui->leDatasourceName->text())){ throw LimeReport::ReportError(QString(tr("Datasource with name: \"%1\" already exists!")).arg(ui->leDatasourceName->text())); @@ -180,10 +185,12 @@ void SQLEditDialog::setDataSources(LimeReport::DataSourceManager *dataSources, Q m_datasources=dataSources; if (!datasourceName.isEmpty()){ ui->cbSubdetail->setEnabled(true); - initQueryMode(); m_oldDatasourceName=datasourceName; ui->leDatasourceName->setText(datasourceName); - ui->textEditSQL->setText(dataSources->queryText(datasourceName)); + ui->sqlText->setText(dataSources->queryText(datasourceName)); + if (dataSources->isQuery(datasourceName)){ + initQueryMode(); + } if (dataSources->isSubQuery(datasourceName)){ initSubQueryMode(); ui->leMaster->setText(dataSources->subQueryByName(datasourceName)->master()); @@ -201,6 +208,12 @@ void SQLEditDialog::setDataSources(LimeReport::DataSourceManager *dataSources, Q curIndex++; } } + if (dataSources->isCSV(datasourceName)){ + ui->csvText->setPlainText(dataSources->csvByName(datasourceName)->csvText()); + ui->leSeparator->setText(dataSources->csvByName(datasourceName)->separator()); + ui->cbUseFirstRowAsHeader->setChecked(dataSources->csvByName(datasourceName)->firstRowIsHeader()); + initCSVMode(); + } } } @@ -254,6 +267,7 @@ void SQLEditDialog::on_pbAddField_clicked() ui->fieldsMap->setRowCount(ui->fieldsMap->rowCount()+1); } + void SQLEditDialog::initQueryMode() { ui->gbSQL->setVisible(true); @@ -264,6 +278,7 @@ void SQLEditDialog::initQueryMode() ui->cbSubdetail->setChecked(false); ui->leMaster->setVisible(false); ui->lbMaster->setVisible(false); + ui->tabWidget->removeTab(1); } void SQLEditDialog::initSubQueryMode() @@ -278,6 +293,7 @@ void SQLEditDialog::initSubQueryMode() ui->leMaster->setVisible(true); ui->leMaster->setEnabled(true); ui->lbMaster->setVisible(true); + ui->tabWidget->removeTab(1); } void SQLEditDialog::initProxyMode() @@ -293,6 +309,12 @@ void SQLEditDialog::initProxyMode() ui->leMaster->setEnabled(true); ui->lbMaster->setVisible(true); ui->cbSubdetail->setEnabled(false); + ui->tabWidget->removeTab(1); +} + +void SQLEditDialog::initCSVMode() +{ + ui->tabWidget->removeTab(0); } void SQLEditDialog::slotPreviewData() @@ -303,7 +325,7 @@ void SQLEditDialog::slotPreviewData() } m_previewModel = m_datasources->previewSQL( ConnectionDesc::connectionNameForReport(ui->cbbConnection->currentText()), - ui->textEditSQL->toPlainText(), + ui->sqlText->toPlainText(), ui->leMaster->text() ); if (m_previewModel){ diff --git a/limereport/databrowser/lrsqleditdialog.h b/limereport/databrowser/lrsqleditdialog.h index 55166a9..28dcffd 100644 --- a/limereport/databrowser/lrsqleditdialog.h +++ b/limereport/databrowser/lrsqleditdialog.h @@ -77,6 +77,7 @@ private slots: void initQueryMode(); void initSubQueryMode(); void initProxyMode(); + void initCSVMode(); void slotPreviewData(); void slotHidePreview(); private: @@ -96,17 +97,20 @@ private: }; struct SQLEditResult{ - enum ResultMode{Query, SubQuery, SubProxy, Undefined}; + enum ResultMode{Query, SubQuery, SubProxy, CSVText, Undefined}; QString connectionName; QString datasourceName; QString oldDatasourceName; QString sql; + QString csv; bool subdetail; ResultMode resultMode; QString masterDatasource; QString childDataSource; SQLEditDialog::SQLDialogMode dialogMode; QList fieldMap; + QString separator; + bool firstRowIsHeader; }; } // namespace LimeReport diff --git a/limereport/databrowser/lrsqleditdialog.ui b/limereport/databrowser/lrsqleditdialog.ui index e1353aa..d6c6a91 100644 --- a/limereport/databrowser/lrsqleditdialog.ui +++ b/limereport/databrowser/lrsqleditdialog.ui @@ -6,8 +6,8 @@ 0 0 - 411 - 617 + 422 + 622 @@ -21,30 +21,6 @@ - - - - - - Connection - - - - - - - - 0 - 0 - - - - Qt::NoFocus - - - - - @@ -207,6 +183,15 @@ + + + + 0 + 0 + 0 + + + @@ -344,6 +329,15 @@ + + + + 0 + 0 + 0 + + + @@ -481,6 +475,15 @@ + + + + 0 + 0 + 0 + + + @@ -498,253 +501,351 @@ - - - - - Subdetail - - - - - + + + 0 + + + + SQL + + - - - Master datasource + + + + + Connection + + + + + + + + 0 + 0 + + + + Qt::NoFocus + + + + + + + + + + + Subdetail + + + + + + + + + Master datasource + + + + + + + false + + + + + + + + + false + + + Subquery mode + + + + + + + false + + + Filter mode + + + + + + + + + SQL + + + 4 + + + 2 + + + 2 + + + 2 + + + 2 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Preview + + + + + + + Hide Preview + + + + + + - - - false + + + QFrame::NoFrame + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + Child datasource + + + + + + + + + + + + + + + Fields map + + + + 4 + + + 4 + + + 4 + + + 4 + + + + + 2 + + + + + + + + + + + ... + + + + :/databrowser/images/add.png:/databrowser/images/add.png + + + true + + + + + + + ... + + + + :/databrowser/images/remove.png:/databrowser/images/remove.png + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + Data preview + + + + 2 + + + 2 + + + 2 + + + 2 + + + 2 + + + + + - - - - - false - - - Subquery mode - - - - - - - false - - - Filter mode - - - - - - - - - SQL - - - - 4 - - - 2 - - - 2 - - - 2 - - - 2 - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Preview - - - - - - - Hide Preview - - - - - - - - - - - - QFrame::NoFrame - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - Child datasource - - - - - - - - - - - - - - - Fields map - - - - 4 - - - 4 - - - 4 - - - 4 - - - - - 2 - - - - - - - - - - - ... - - - - :/databrowser/images/add.png:/databrowser/images/add.png - - - true - - - - - - - ... - - - - :/databrowser/images/remove.png:/databrowser/images/remove.png - - - true - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - Data preview - - - - 2 - - - 2 - - - 2 - - - 2 - - - 2 - - - - - + + + + CSV + + + + + + + + Separator + + + + + + + + 0 + 0 + + + + + 30 + 16777215 + + + + ; + + + + + + + Use first row as header + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + @@ -787,39 +888,14 @@ - leDatasourceName - cbSubdetail - leMaster - rbSubQuery - rbProxy - textEditSQL - leChild - fieldsMap - pbAddField - pbDelField pushButton_2 pushButton + - - leDatasourceName - textChanged(QString) - LimeReport::SQLEditDialog - slotDataSourceNameEditing() - - - 259 - 54 - - - 289 - 32 - - - pushButton clicked() diff --git a/limereport/lrdatadesignintf.cpp b/limereport/lrdatadesignintf.cpp index 9fae29e..718f1f4 100644 --- a/limereport/lrdatadesignintf.cpp +++ b/limereport/lrdatadesignintf.cpp @@ -831,4 +831,118 @@ bool CallbackDatasource::checkIfEmpty(){ } } +QString CSVDesc::name() const +{ + return m_csvName; +} + +void CSVDesc::setName(const QString &csvName) +{ + m_csvName = csvName; +} + +QString CSVDesc::csvText() const +{ + return m_csvText; +} + +void CSVDesc::setCsvText(const QString &csvText) +{ + m_csvText = csvText; + emit cvsTextChanged(m_csvName, m_csvText); +} + +QString CSVDesc::separator() const +{ + return m_separator; +} + +void CSVDesc::setSeparator(const QString &separator) +{ + m_separator = separator; +} + +bool CSVDesc::firstRowIsHeader() const +{ + return m_firstRowIsHeader; +} + +void CSVDesc::setFirstRowIsHeader(bool firstRowIsHeader) +{ + m_firstRowIsHeader = firstRowIsHeader; +} + +void CSVHolder::updateModel() +{ + m_model.clear(); + QString sep = (separator().compare("\\t") == 0) ? "\t" : separator(); + bool firstRow = true; + QList columns; + QStringList headers; + foreach(QString line, m_csvText.split('\n')){ + columns.clear(); + foreach(QString item, line.split(sep)){ + columns.append(new QStandardItem(item)); + if (firstRow && m_firstRowIsHeader) headers.append(item); + } + + if (firstRow){ + if (!headers.isEmpty()){ + m_model.setHorizontalHeaderLabels(headers); + firstRow = false; + } else { + m_model.appendRow(columns); + } + } else { + m_model.appendRow(columns); + } + + } + + +} + +bool CSVHolder::firsRowIsHeader() const +{ + return m_firstRowIsHeader; +} + +void CSVHolder::setFirsRowIsHeader(bool firstRowIsHeader) +{ + m_firstRowIsHeader = firstRowIsHeader; +} + +CSVHolder::CSVHolder(const CSVDesc &desc, DataSourceManager *dataManager) + : m_csvText(desc.csvText()), + m_separator(desc.separator()), + m_dataManager(dataManager), + m_firstRowIsHeader(desc.firstRowIsHeader()) +{ + m_dataSource = IDataSource::Ptr(new ModelToDataSource(&m_model, false)); + updateModel(); +} + +void CSVHolder::setCSVText(QString csvText) +{ + m_csvText = csvText; + updateModel(); +} + +QString CSVHolder::separator() const +{ + return m_separator; +} + +void CSVHolder::setSeparator(const QString &separator) +{ + m_separator = separator; + updateModel(); +} + +IDataSource *CSVHolder::dataSource(IDataSource::DatasourceMode mode) +{ + Q_UNUSED(mode); + return m_dataSource.data(); +} + } //namespace LimeReport diff --git a/limereport/lrdatadesignintf.h b/limereport/lrdatadesignintf.h index a05c81e..8665bc1 100644 --- a/limereport/lrdatadesignintf.h +++ b/limereport/lrdatadesignintf.h @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -131,6 +132,64 @@ public: virtual QString lastError() const = 0; }; +class CSVDesc: public QObject{ + Q_OBJECT + Q_PROPERTY(QString name READ name WRITE setName) + Q_PROPERTY(QString csvText READ csvText WRITE setCsvText) + Q_PROPERTY(QString separator READ separator WRITE setSeparator) + Q_PROPERTY(bool firstRowIsHeader READ firstRowIsHeader WRITE setFirstRowIsHeader) +public: + CSVDesc(const QString name, const QString csvText, QString separator, bool firstRowIsHeader) + : m_csvName(name), m_csvText(csvText), m_separator(separator), m_firstRowIsHeader(firstRowIsHeader){} + explicit CSVDesc(QObject* parent = 0):QObject(parent) {} + QString name() const; + void setName(const QString &name); + QString csvText() const; + void setCsvText(const QString &csvText); + QString separator() const; + void setSeparator(const QString &separator); + bool firstRowIsHeader() const; + void setFirstRowIsHeader(bool firstRowIsHeader); +signals: + void cvsTextChanged(const QString& cvsName, const QString& cvsText); +private: + QString m_csvName; + QString m_csvText; + QString m_separator; + bool m_firstRowIsHeader; +}; + +class CSVHolder: public IDataSourceHolder{ +public: + CSVHolder(const CSVDesc& desc, DataSourceManager* dataManager); + void setCSVText(QString csvText); + QString csvText() { return m_csvText;} + QString separator() const; + void setSeparator(const QString &separator); + bool firsRowIsHeader() const; + void setFirsRowIsHeader(bool firstRowIsHeader); + // IDataSourceHolder interface +public: + IDataSource *dataSource(IDataSource::DatasourceMode mode = IDataSource::RENDER_MODE); + QString lastError() const {return "";} + bool isInvalid() const {return false;} + bool isOwned() const {return true;} + bool isEditable() const {return true;} + bool isRemovable() const {return true;} + void invalidate(IDataSource::DatasourceMode mode, bool dbWillBeClosed){ updateModel();} + void update(){ updateModel(); } + void clearErrors(){} +private: + void updateModel(); +private: + QString m_csvText; + QStandardItemModel m_model; + QString m_separator; + IDataSource::Ptr m_dataSource; + DataSourceManager* m_dataManager; + bool m_firstRowIsHeader; +}; + class QueryDesc : public QObject{ Q_OBJECT Q_PROPERTY(QString queryName READ queryName WRITE setQueryName) @@ -140,11 +199,11 @@ public: QueryDesc(QString queryName, QString queryText, QString connection); explicit QueryDesc(QObject* parent=0):QObject(parent){} void setQueryName(QString value){m_queryName=value;} - QString queryName(){return m_queryName;} + QString queryName() const {return m_queryName;} void setQueryText(QString value){m_queryText=value; emit queryTextChanged(m_queryName, m_queryText);} - QString queryText(){return m_queryText;} + QString queryText() const {return m_queryText;} void setConnectionName(QString value){m_connectionName=value;} - QString connectionName(){return m_connectionName;} + QString connectionName() const {return m_connectionName;} signals: void queryTextChanged(const QString& queryName, const QString& queryText); private: diff --git a/limereport/lrdatasourcemanager.cpp b/limereport/lrdatasourcemanager.cpp index 4f9b147..b020550 100644 --- a/limereport/lrdatasourcemanager.cpp +++ b/limereport/lrdatasourcemanager.cpp @@ -179,7 +179,7 @@ DataNode* DataSourceModel::nodeFromIndex(const QModelIndex& index) const void DataSourceModel::fillFields(DataNode* parent) { foreach(QString name, m_dataManager->fieldNames(parent->name())){ - parent->addChild(name,DataNode::Field,QIcon(":/report/images/field")); + parent->addChild(name, DataNode::Field,QIcon(":/report/images/field")); } } @@ -537,7 +537,7 @@ void DataSourceManager::addSubQuery(const QString &name, const QString &sqlText, emit datasourcesChanged(); } -void DataSourceManager::addProxy(const QString &name, QString master, QString detail, QList fields) +void DataSourceManager::addProxy(const QString &name, const QString &master, const QString &detail, QList fields) { ProxyDesc *proxyDesc = new ProxyDesc(); proxyDesc->setName(name); @@ -552,6 +552,15 @@ void DataSourceManager::addProxy(const QString &name, QString master, QString de emit datasourcesChanged(); } +void DataSourceManager::addCSV(const QString& name, const QString& csvText, const QString &separator, bool firstRowIsHeader) +{ + CSVDesc* csvDesc = new CSVDesc(name, csvText, separator, firstRowIsHeader); + putCSVDesc(csvDesc); + putHolder(name, new CSVHolder(*csvDesc, this)); + m_hasChanges = true; + emit datasourcesChanged(); +} + QString DataSourceManager::queryText(const QString &dataSourceName) { if (isQuery(dataSourceName)) return queryByName(dataSourceName)->queryText(); @@ -559,16 +568,16 @@ QString DataSourceManager::queryText(const QString &dataSourceName) else return QString(); } -QueryDesc *DataSourceManager::queryByName(const QString &dataSourceName) +QueryDesc *DataSourceManager::queryByName(const QString &datasourceName) { - int queryIndex = queryIndexByName(dataSourceName); + int queryIndex = queryIndexByName(datasourceName); if (queryIndex!=-1) return m_queries.at(queryIndex); return 0; } -SubQueryDesc* DataSourceManager::subQueryByName(const QString &dataSourceName) +SubQueryDesc* DataSourceManager::subQueryByName(const QString &datasourceName) { - int queryIndex = subQueryIndexByName(dataSourceName); + int queryIndex = subQueryIndexByName(datasourceName); if (queryIndex!=-1) return m_subqueries.at(queryIndex); return 0; } @@ -607,6 +616,15 @@ int DataSourceManager::proxyIndexByName(const QString &dataSourceName) return -1; } +int DataSourceManager::csvIndexByName(const QString &dataSourceName) +{ + for(int i=0; i < m_csvs.count();++i){ + CSVDesc* desc=m_csvs.at(i); + if (desc->name().compare(dataSourceName,Qt::CaseInsensitive)==0) return i; + } + return -1; +} + int DataSourceManager::connectionIndexByName(const QString &connectionName) { for(int i=0;i-1) return m_proxies.at(proxyIndex); + if (proxyIndex > -1) return m_proxies.at(proxyIndex); + else return 0; +} + +CSVDesc *DataSourceManager::csvByName(const QString &datasourceName) +{ + int csvIndex = csvIndexByName(datasourceName); + if (csvIndex > -1) return m_csvs.at(csvIndex); else return 0; } @@ -671,6 +696,11 @@ void DataSourceManager::removeDatasource(const QString &name) delete m_proxies.at(proxyIndex); m_proxies.removeAt(proxyIndex); } + if (isCSV(name)){ + int csvIndex=csvIndexByName(name); + delete m_csvs.at(csvIndex); + m_csvs.removeAt(csvIndex); + } m_hasChanges = true; emit datasourcesChanged(); } @@ -763,6 +793,15 @@ void DataSourceManager::putProxyDesc(ProxyDesc *proxyDesc) } else throw ReportError(tr("Datasource with name \"%1\" already exists!").arg(proxyDesc->name())); } +void DataSourceManager::putCSVDesc(CSVDesc *csvDesc) +{ + if (!containsDatasource(csvDesc->name())){ + m_csvs.append(csvDesc); + connect(csvDesc, SIGNAL(cvsTextChanged(QString, QString)), + this, SLOT(slotCSVTextChanged(QString, QString))); + } else throw ReportError(tr("Datasource with name \"%1\" already exists!").arg(csvDesc->name())); +} + bool DataSourceManager::initAndOpenDB(QSqlDatabase& db, ConnectionDesc& connectionDesc){ bool connected = false; @@ -933,17 +972,22 @@ bool DataSourceManager::containsDatasource(const QString &dataSourceName) bool DataSourceManager::isSubQuery(const QString &dataSourceName) { - return subQueryIndexByName(dataSourceName.toLower())!=-1; + return subQueryIndexByName(dataSourceName) != -1; } bool DataSourceManager::isProxy(const QString &dataSourceName) { - return proxyIndexByName(dataSourceName)!=-1; + return proxyIndexByName(dataSourceName) != -1; +} + +bool DataSourceManager::isCSV(const QString &datasourceName) +{ + return csvIndexByName(datasourceName) != -1; } bool DataSourceManager::isConnection(const QString &connectionName) { - return connectionIndexByName(connectionName)!=-1; + return connectionIndexByName(connectionName) != -1; } bool DataSourceManager::isConnectionConnected(const QString &connectionName) @@ -1045,7 +1089,7 @@ QStringList DataSourceManager::fieldNames(const QString &datasourceName) QStringList result; IDataSource* ds = dataSource(datasourceName); if (ds && !ds->isInvalid()){ - for(int i=0;icolumnCount();i++){ + for(int i=0; i < ds->columnCount(); i++){ result.append(ds->columnNameByIndex(i)); } result.sort(); @@ -1089,6 +1133,12 @@ QObject *DataSourceManager::createElement(const QString& collectionName, const Q return var; } + if (collectionName=="csvs"){ + CSVDesc* csvDesc = new CSVDesc; + m_csvs.append(csvDesc); + return csvDesc; + } + return 0; } @@ -1109,6 +1159,9 @@ int DataSourceManager::elementsCount(const QString &collectionName) if (collectionName=="variables"){ return m_reportVariables.variablesCount(); } + if (collectionName=="csvs"){ + return m_csvs.count(); + } return 0; } @@ -1129,6 +1182,9 @@ QObject* DataSourceManager::elementAt(const QString &collectionName, int index) if (collectionName=="variables"){ return m_reportVariables.variableAt(index); } + if (collectionName=="csvs"){ + return m_csvs.at(index); + } return 0; } @@ -1206,6 +1262,25 @@ void DataSourceManager::collectionLoadFinished(const QString &collectionName) m_tempVars.clear(); } EASY_END_BLOCK; + + if (collectionName.compare("csvs", Qt::CaseInsensitive) == 0){ + QMutableListIterator it(m_csvs); + while (it.hasNext()){ + it.next(); + if (!m_datasources.contains(it.value()->name().toLower())){ + connect(it.value(), SIGNAL(cvsTextChanged(QString,QString)), + this, SLOT(slotCSVTextChanged(QString,QString))); + putHolder( + it.value()->name(), + new CSVHolder(*it.value(), this) + ); + } else { + delete it.value(); + it.remove(); + } + } + } + if (designTime()){ EASY_BLOCK("emit datasourcesChanged()"); emit datasourcesChanged(); @@ -1328,6 +1403,14 @@ void DataSourceManager::slotVariableHasBeenChanged(const QString& variableName) m_hasChanges = true; } +void DataSourceManager::slotCSVTextChanged(const QString &csvName, const QString &csvText) +{ + CSVHolder* holder = dynamic_cast(m_datasources.value(csvName)); + if (holder){ + holder->setCSVText(csvText); + } +} + void DataSourceManager::clear(ClearMethod method) { DataSourcesMap::iterator dit; diff --git a/limereport/lrdatasourcemanager.h b/limereport/lrdatasourcemanager.h index 001e09e..de708fe 100644 --- a/limereport/lrdatasourcemanager.h +++ b/limereport/lrdatasourcemanager.h @@ -100,6 +100,7 @@ class DataSourceManager : public QObject, public ICollectionContainer, public IV Q_PROPERTY(ACollectionProperty subqueries READ fakeCollectionReader) Q_PROPERTY(ACollectionProperty subproxies READ fakeCollectionReader) Q_PROPERTY(ACollectionProperty variables READ fakeCollectionReader) + Q_PROPERTY(ACollectionProperty csvs READ fakeCollectionReader) friend class ReportEnginePrivate; friend class ReportRender; public: @@ -112,7 +113,8 @@ public: bool checkConnectionDesc(ConnectionDesc *connection); void addQuery(const QString& name, const QString& sqlText, const QString& connectionName=""); void addSubQuery(const QString& name, const QString& sqlText, const QString& connectionName, const QString& masterDatasource); - void addProxy(const QString& name, QString master, QString detail, QList fields); + void addProxy(const QString& name, const QString& master, const QString& detail, QList fields); + void addCSV(const QString& name, const QString& csvText, const QString& separator, bool firstRowIsHeader); bool addModel(const QString& name, QAbstractItemModel *model, bool owned); void removeModel(const QString& name); ICallbackDatasource* createCallbackDatasource(const QString &name); @@ -143,18 +145,21 @@ public: bool containsDatasource(const QString& dataSourceName); bool isSubQuery(const QString& dataSourceName); bool isProxy(const QString& dataSourceName); + bool isCSV(const QString& datasourceName); bool isConnection(const QString& connectionName); bool isConnectionConnected(const QString& connectionName); bool connectConnection(const QString &connectionName); void connectAutoConnections(); void disconnectConnection(const QString &connectionName); - QueryDesc* queryByName(const QString& dataSourceName); - SubQueryDesc* subQueryByName(const QString& dataSourceName); - ProxyDesc* proxyByName(QString datasourceName); + QueryDesc* queryByName(const QString& datasourceName); + SubQueryDesc* subQueryByName(const QString& datasourceName); + ProxyDesc* proxyByName(const QString& datasourceName); + CSVDesc* csvByName(const QString& datasourceName); ConnectionDesc *connectionByName(const QString& connectionName); int queryIndexByName(const QString& dataSourceName); int subQueryIndexByName(const QString& dataSourceName); int proxyIndexByName(const QString& dataSourceName); + int csvIndexByName(const QString& dataSourceName); int connectionIndexByName(const QString& connectionName); QList &conections(); @@ -226,6 +231,7 @@ protected: void putQueryDesc(QueryDesc *queryDesc); void putSubQueryDesc(SubQueryDesc *subQueryDesc); void putProxyDesc(ProxyDesc *proxyDesc); + void putCSVDesc(CSVDesc* csvDesc); bool connectConnection(ConnectionDesc* connectionDesc); void clearReportVariables(); QList childDatasources(const QString& datasourceName); @@ -246,6 +252,7 @@ private slots: void slotQueryTextChanged(const QString& queryName, const QString& queryText); void slotVariableHasBeenAdded(const QString& variableName); void slotVariableHasBeenChanged(const QString& variableName); + void slotCSVTextChanged(const QString& csvName, const QString& csvText); private: explicit DataSourceManager(QObject *parent = 0); bool initAndOpenDB(QSqlDatabase &db, ConnectionDesc &connectionDesc); @@ -256,6 +263,7 @@ private: QList m_subqueries; QList m_proxies; QList m_tempVars; + QList m_csvs; QMultiMap m_groupFunctions; GroupFunctionFactory m_groupFunctionFactory;