|
View:
New views
2 Messages
—
Rating Filter:
Alert me
|
|
|
Keximigrate extensionLo
Attached is 3 patches to kexi. 1. Extend the keximigrate api to add a cursor style api - fix the txt plugin to use this api 2. A kspread plugin implementing the api 3. Updated reportspgz plugin to allow using keximigrate as a datasource for reporting (also some misc cleanups) The idea behind this is that it allows integration with other koffice apps, as a driver could be written for kplato also. We could also extend the existing plugins with the cursor api, to allow reading directly from a mysql or postgresql datasource etc. Please comment on the theory, im not saying the impl is perfect yet, more of a 'just enough to work'! More ideas very welcome. Cheers Adam [keximigrate_and_txt_driver.patch] Index: txt/txtmigrate.cpp =================================================================== --- txt/txtmigrate.cpp (revision 985390) +++ txt/txtmigrate.cpp (working copy) @@ -14,8 +14,12 @@ namespace KexiMigration { -TxtMigrate::TxtMigrate() - : KexiMigrate() +KEXIMIGRATE_DRIVER_INFO(TxtMigrate, txt) + + + +TxtMigrate::TxtMigrate(QObject *parent, const QStringList &args) + : KexiMigrate(parent, args) { } @@ -24,5 +28,85 @@ { } +bool TxtMigrate::drv_connect() +{ + mfolder = m_migrateData->source->dbPath(); + return true; +} +bool TxtMigrate::drv_disconnect() +{ + return true; +} + +bool TxtMigrate::drv_tableNames(QStringList& tablenames) +{ + tablenames << "Table1"; + return true; +} + +bool TxtMigrate::drv_readTableSchema(const QString& originalName, KexiDB::TableSchema& tableSchema) +{ + if (drv_readFromTable(originalName)) + { + for (unsigned int i = 0; i < mFieldNames.count(); ++i) + { + tableSchema.addField( new KexiDB::Field(mFieldNames[i], KexiDB::Field::Text) ); + } + return true; + } + return false; +} + +bool TxtMigrate::drv_readFromTable(const QString & tableName) +{ + mDataFile = new QFile(mfolder + "/" + tableName); + + kDebug() << mDataFile->fileName(); + mRow = -1; + fileRow = -1; + + if (!mDataFile->open(QIODevice::ReadOnly | QIODevice::Text)) + return false; + + mLastLine = mDataFile->readLine(); + mFieldNames = mLastLine.split("\t"); + + return true; +} + +bool TxtMigrate::drv_moveNext() +{ + if (mRow < fileRow) + { + mRow++; + } + else + { + if (mDataFile->atEnd()) + return false; + + mLastLine = mDataFile->readLine(); + mFieldValues.push_back(mLastLine.split("\t")); + mRow++; + fileRow++; + } + return true; +} + +bool TxtMigrate::drv_movePrevious() +{ + if (mRow > 0) + { + mRow--; + return true; + } + return false; +} + +QVariant TxtMigrate::drv_value(uint i) +{ + return QVariant(mFieldValues[mRow][i]); +} + }; Index: txt/CMakeLists.txt =================================================================== --- txt/CMakeLists.txt (revision 985390) +++ txt/CMakeLists.txt (working copy) @@ -8,40 +8,20 @@ set(keximigrate_txtmigrate_PART_SRCS txtmigrate.cpp ) -kde4_add_plugin(keximigrate_txtmigrate ${keximigrate_txtmigrate_PART_SRCS}) +kde4_add_plugin(keximigrate_txt ${keximigrate_txtmigrate_PART_SRCS}) -target_link_libraries(keximigrate_txtmigrate ${KDE4_KPARTS_LIBS} keximigrate ) +target_link_libraries(keximigrate_txt + ${KDE4_KPARTS_LIBS} + keximigrate + kexidb + kexiutils +) -install(TARGETS keximigrate_txtmigrate DESTINATION ${PLUGIN_INSTALL_DIR}) +install(TARGETS keximigrate_txt DESTINATION ${PLUGIN_INSTALL_DIR}) ########### install files ############### -install( FILES keximigrate_txtmigrate.desktop DESTINATION ${SERVICES_INSTALL_DIR}) - - - - - -#original Makefile.am contents follow: - -#include $(top_srcdir)/kexi/Makefile.global -# -#kde_module_LTLIBRARIES = keximigrate_txtmigrate.la -# -#INCLUDES = -I$(srcdir)/../../.. -I$(top_srcdir)/kexi $(all_includes) -# -#keximigrate_txtmigrate_la_METASOURCES = AUTO -# -#keximigrate_txtmigrate_la_SOURCES = txtmigrate.cpp -# -#keximigrate_txtmigrate_la_LIBADD = $(LIB_KPARTS) $(LIB_QT) ../libkeximigrate.la -# -#keximigrate_txtmigrate_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) $(VER_INFO) -no-undefined -# -#kde_services_DATA = keximigrate_txtmigrate.desktop -# -#noinst_HEADERS = txtmigrate.h -# +install( FILES keximigrate_txt.desktop DESTINATION ${SERVICES_INSTALL_DIR}) Index: txt/txtmigrate.h =================================================================== --- txt/txtmigrate.h (revision 985390) +++ txt/txtmigrate.h (working copy) @@ -12,7 +12,8 @@ #ifndef KEXIMIGRATIONTXTMIGRATE_H #define KEXIMIGRATIONTXTMIGRATE_H -#include <keximigrate.h> +#include <migration/keximigrate.h> +#include <QFile> namespace KexiMigration { @@ -22,11 +23,56 @@ */ class TxtMigrate : public KexiMigrate { + Q_OBJECT + KEXIMIGRATION_DRIVER public: - TxtMigrate(); + TxtMigrate(QObject *parent, const QStringList &args = QStringList()); - ~TxtMigrate(); + virtual ~TxtMigrate(); + protected: + //! Connect to source + virtual bool drv_connect(); + + //! Disconnect from source + virtual bool drv_disconnect(); + + //! Get table names in source + virtual bool drv_tableNames(QStringList& tablenames); + + virtual bool drv_copyTable(const QString&, KexiDB::Connection*, KexiDB::TableSchema*){return false;}; + + //! Read schema for a given table + virtual bool drv_readTableSchema(const QString& originalName, KexiDB::TableSchema& tableSchema); + + //!Position the source dataset at the start of a table + virtual bool drv_readFromTable(const QString & tableName); + + //!Move to the next row + virtual bool drv_moveNext(); + + //!Move to the previous row + virtual bool drv_movePrevious(); + + //!Read the data at the given row/field + virtual QVariant drv_value(uint i); + + private: + QString mfolder; + + QString mFileName; + + QString mLastLine; + + QFile *mDataFile; + + QStringList mFieldNames; + QVector<QStringList> mFieldValues; + + int mRow; + + int fileRow; + }; }; Index: keximigrate.cpp =================================================================== --- keximigrate.cpp (revision 985390) +++ keximigrate.cpp (working copy) @@ -429,15 +429,6 @@ } //============================================================================= -// Functions for getting table data -bool KexiMigrate::tableNames(QStringList & tn) -{ - //! @todo Cache list of table names - kDebug() << "Reading list of tables..."; - return drv_tableNames(tn); -} - -//============================================================================= // Progress functions bool KexiMigrate::progressInitialise() { @@ -573,4 +564,53 @@ return res; } +//============================================================================= +//Extended API for access to external data +bool KexiMigrate::connectSource() +{ + return drv_connect(); +} + +bool KexiMigrate::readTableSchema(const QString& originalName, KexiDB::TableSchema& tableSchema) +{ + return drv_readTableSchema(originalName, tableSchema); +} + +bool KexiMigrate::tableNames(QStringList & tn) +{ + //! @todo Cache list of table names + kDebug() << "Reading list of tables..."; + return drv_tableNames(tn); +} + +bool KexiMigrate::readFromTable(const QString & tableName) +{ + return drv_readFromTable(tableName); +} + +bool KexiMigrate::moveNext() +{ + return drv_moveNext(); +} + +bool KexiMigrate::movePrevious() +{ + return drv_movePrevious(); +} + +bool KexiMigrate::moveFirst() +{ + return drv_moveFirst(); +} + +bool KexiMigrate::moveLast() +{ + return drv_moveLast(); +} + +QVariant KexiMigrate::value(uint i) +{ + return drv_value(i); +} + #include "keximigrate.moc" Index: keximigrate.h =================================================================== --- keximigrate.h (revision 985390) +++ keximigrate.h (working copy) @@ -114,7 +114,7 @@ //! Perform an export operation bool performExport(Kexi::ObjectStatus* result = 0); - + //! Returns true if the migration driver supports progress updates. inline bool progressSupported() { return drv_progressSupported(); @@ -144,7 +144,35 @@ and KexiMigrate::versionMinor() are matching. You can reimplement this but always call KexiMigrate::isValid() implementation. */ virtual bool isValid(); + + //Extension of existing api to provide generic row access to external data. + //!Connect to the source data + bool connectSource(); + + //! Get table names in source database (driver specific) + bool tableNames(QStringList& tablenames); + //! Read schema for a given table (driver specific) + bool readTableSchema(const QString& originalName, KexiDB::TableSchema& tableSchema); + + //!Position the source dataset at the start of a table + bool readFromTable(const QString& tableName); + + //!Move to the next row + bool moveNext(); + + //!Move to the previous row + bool movePrevious(); + + //!Move to the next row + bool moveFirst(); + + //!Move to the previous row + bool moveLast(); + + //!Read the data at the given row/field + QVariant value(uint i); + signals: void progressPercent(int percent); @@ -275,10 +303,27 @@ //! KexiDB driver. For instance, it is used for escaping identifiers QPointer<KexiDB::Driver> m_kexiDBDriver; - + + //Extended API + //!Position the source dataset at the start of a table + virtual bool drv_readFromTable(const QString & tableName){ return false; }; + + //!Move to the next row + virtual bool drv_moveNext() { return false; }; + + //!Move to the previous row + virtual bool drv_movePrevious() { return false; }; + + //!Move to the next row + virtual bool drv_moveFirst() { return false; }; + + //!Move to the previous row + virtual bool drv_moveLast() { return false; }; + + //!Read the data at the given row/field + virtual QVariant drv_value(uint i){ return QVariant(); }; + private: - //! Get the list of tables - bool tableNames(QStringList& tablenames); //! Create the target database project // KexiProject* createProject(Kexi::ObjectStatus* result); Index: CMakeLists.txt =================================================================== --- CMakeLists.txt (revision 985390) +++ CMakeLists.txt (working copy) @@ -6,6 +6,10 @@ add_definitions(-DKDE_DEFAULT_DEBUG_AREA=44000) +add_subdirectory(txt) + +add_subdirectory(kspread) + macro_optional_find_package(MySQL) macro_log_feature(MYSQL_FOUND "libmysqlclient" "MySQL Client Library" "http://www.mysql.com" FALSE "" "Required by Kexi MySQL Migration driver") IF (MYSQL_FOUND) @@ -74,7 +78,14 @@ target_link_libraries(keximigratetest ${KDE4_KDECORE_LIBS} keximigrate kexicore kexidb kexiextendedwidgets keximain ) +########### next target ############### +set(readertest_SRCS readertest.cpp ) + +kde4_add_executable(readertest ${readertest_SRCS}) + +target_link_libraries(readertest ${KDE4_KDECORE_LIBS} keximigrate kexicore kexidb keximain ) + ########### install files ############### install( FILES keximigrate.h keximigratedata.h migratemanager.h DESTINATION ${INCLUDE_INSTALL_DIR}/kexidb COMPONENT Devel) [keximigrate_kspread_plugin.patch] Index: kspreadmigrate.cpp =================================================================== --- kspreadmigrate.cpp (revision 0) +++ kspreadmigrate.cpp (revision 0) @@ -0,0 +1,150 @@ +// +// C++ Implementation: txtmigrate +// +// Description: +// +// +// Author: Adam Pigg <adam@...>, (C) 2004 +// +// Copyright: See COPYING file that comes with this distribution +// +// +#include "kspreadmigrate.h" + +namespace KexiMigration +{ + +KEXIMIGRATE_DRIVER_INFO(KSpreadMigrate, kspread) + +KSpreadMigrate::KSpreadMigrate(QObject *parent, const QStringList &args) + : KexiMigrate(parent, args) +{ + mCurSheet = 0; +} + +KSpreadMigrate::~KSpreadMigrate() +{ +} + +bool KSpreadMigrate::drv_connect() +{ + mFileName = m_migrateData->source->dbPath() + "/" + m_migrateData->source->dbFileName(); + mKSDoc = new KSpread::Doc(); + return mKSDoc->openUrl(mFileName); +} + +bool KSpreadMigrate::drv_disconnect() +{ + delete mKSDoc; + return true; +} + +bool KSpreadMigrate::drv_tableNames(QStringList& tablenames) +{ + QList<KSpread::Sheet*> sheets = mKSDoc->map()->sheetList(); + + kDebug() << sheets.size() << "sheets" << mKSDoc->map()->sheetList().size(); + + for (unsigned int i = 0; i < sheets.size(); ++i) + { + tablenames << sheets[i]->sheetName(); + } + + return true; +} + +bool KSpreadMigrate::drv_readTableSchema(const QString& originalName, KexiDB::TableSchema& tableSchema) +{ + KSpread::Sheet *sheet = mKSDoc->map()->findSheet(originalName); + + if (!sheet) + { + kDebug() << "unable to find sheet" << originalName; + return false; + } + + int row=1, col = 1; + QString fieldname; + + KSpread::Cell *cell; + do + { + cell = new KSpread::Cell(sheet, col, row); + + fieldname = cell->displayText(); + col++; + if (!cell->isEmpty()) + { + tableSchema.addField( new KexiDB::Field(fieldname, KexiDB::Field::Text) ); + kDebug() << fieldname; + } + }while(!cell->isEmpty()); + + return true; +} + +bool KSpreadMigrate::drv_readFromTable(const QString & tableName) +{ + mCurSheet = mKSDoc->map()->findSheet(tableName); + + mRow = 1; + + return mCurSheet; +} + +bool KSpreadMigrate::drv_moveNext() +{ + if (!mCurSheet) + return false; + + KSpread::Cell cell = KSpread::Cell(mCurSheet, 1, mRow + 1); + + if (!cell.isEmpty()) + { + mRow++; + return true; + } + + return false; +} + +bool KSpreadMigrate::drv_movePrevious() +{ + if (!mCurSheet) + return false; + + if (mRow > 1) + { + mRow--; + return true; + } + return false; +} + +bool KSpreadMigrate::drv_moveFirst() +{ + if (!mCurSheet) + return false; + + mRow = 1; + return drv_moveNext(); +} + +bool KSpreadMigrate::drv_moveLast() +{ + if (!mCurSheet) + return false; + + while(drv_moveNext()){} + + return true; +} + +QVariant KSpreadMigrate::drv_value(uint i) +{ + QString str = KSpread::Cell(mCurSheet, i+1, mRow).displayText(); + + return str; +} + +}; Property changes on: kspreadmigrate.cpp ___________________________________________________________________ Added: svn:executable + * Added: svn:eol-style + native Index: kspreadmigrate.h =================================================================== --- kspreadmigrate.h (revision 0) +++ kspreadmigrate.h (revision 0) @@ -0,0 +1,87 @@ +// +// C++ Interface: kspreadmigrate +// +// Description: +// +// +// Author: Adam Pigg <adam@...>, (C) 2004 +// +// Copyright: See COPYING file that comes with this distribution +// +// +#ifndef KEXIMIGRATIONTXTMIGRATE_H +#define KEXIMIGRATIONTXTMIGRATE_H + +#include <migration/keximigrate.h> +#include <QFile> +#include <kspread/part/Doc.h> +#include <kspread/Map.h> +#include <kspread/Sheet.h> +#include <KoStore.h> +#include <KoOdfWriteStore.h> +#include <KoEmbeddedDocumentSaver.h> +#include <KoDocument.h> + +namespace KexiMigration +{ + +/** +@author Adam Pigg +*/ +class KSpreadMigrate : public KexiMigrate +{ + Q_OBJECT + KEXIMIGRATION_DRIVER +public: + KSpreadMigrate(QObject *parent, const QStringList &args = QStringList()); + + virtual ~KSpreadMigrate(); + + protected: + //! Connect to source + virtual bool drv_connect(); + + //! Disconnect from source + virtual bool drv_disconnect(); + + //! Get table names in source + virtual bool drv_tableNames(QStringList& tablenames); + + virtual bool drv_copyTable(const QString&, KexiDB::Connection*, KexiDB::TableSchema*){return false;}; + + //! Read schema for a given table + virtual bool drv_readTableSchema(const QString& originalName, KexiDB::TableSchema& tableSchema); + + //!Position the source dataset at the start of a table + virtual bool drv_readFromTable(const QString & tableName); + + //!Move to the next row + virtual bool drv_moveNext(); + + //!Move to the previous row + virtual bool drv_movePrevious(); + + //!Move to the next row + virtual bool drv_moveFirst(); + + //!Move to the previous row + virtual bool drv_moveLast(); + + //!Read the data at the given row/field + virtual QVariant drv_value(uint i); + + private: + QString mFileName; + KSpread::Sheet *mCurSheet; + + KSpread::Doc *mKSDoc; + + QStringList mFieldNames; + + unsigned int mRow; + +}; + +}; + +#endif Property changes on: kspreadmigrate.h ___________________________________________________________________ Added: svn:executable + * Added: svn:eol-style + native Index: CMakeLists.txt =================================================================== --- CMakeLists.txt (revision 980386) +++ CMakeLists.txt (working copy) @@ -5,43 +5,24 @@ ########### next target ############### -set(keximigrate_txtmigrate_PART_SRCS txtmigrate.cpp ) +set(keximigrate_kspread_PART_SRCS kspreadmigrate.cpp ) -kde4_add_plugin(keximigrate_txtmigrate ${keximigrate_txtmigrate_PART_SRCS}) +kde4_add_plugin(keximigrate_kspread ${keximigrate_kspread_PART_SRCS}) -target_link_libraries(keximigrate_txtmigrate ${KDE4_KPARTS_LIBS} keximigrate ) +target_link_libraries(keximigrate_kspread + ${KDE4_KPARTS_LIBS} + keximigrate + kexidb + kexiutils + kspreadcommon +) -install(TARGETS keximigrate_txtmigrate DESTINATION ${PLUGIN_INSTALL_DIR}) +install(TARGETS keximigrate_kspread DESTINATION ${PLUGIN_INSTALL_DIR}) ########### install files ############### -install( FILES keximigrate_txtmigrate.desktop DESTINATION ${SERVICES_INSTALL_DIR}) - - - - - -#original Makefile.am contents follow: - -#include $(top_srcdir)/kexi/Makefile.global -# -#kde_module_LTLIBRARIES = keximigrate_txtmigrate.la -# -#INCLUDES = -I$(srcdir)/../../.. -I$(top_srcdir)/kexi $(all_includes) -# -#keximigrate_txtmigrate_la_METASOURCES = AUTO -# -#keximigrate_txtmigrate_la_SOURCES = txtmigrate.cpp -# -#keximigrate_txtmigrate_la_LIBADD = $(LIB_KPARTS) $(LIB_QT) ../libkeximigrate.la -# -#keximigrate_txtmigrate_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) $(VER_INFO) -no-undefined -# -#kde_services_DATA = keximigrate_txtmigrate.desktop -# -#noinst_HEADERS = txtmigrate.h -# +install( FILES keximigrate_kspread.desktop DESTINATION ${SERVICES_INSTALL_DIR}) [reportspgz_use_keximigrate_and_cleanup.patch] Index: backend/renderer/orutils.cpp =================================================================== --- backend/renderer/orutils.cpp (revision 985390) +++ backend/renderer/orutils.cpp (working copy) @@ -25,44 +25,79 @@ // // Class orQuery implementations // -orQuery::orQuery() -{ - m_cursor = 0; - m_connection = 0; -} -orQuery::orQuery(const QString &qstrPName, const QString &qstrSQL, - bool doexec, KexiDB::Connection * pDb) +orQuery::orQuery(const QString &qstrSQL, + KexiDB::Connection * pDb) { QString qstrParsedSQL(qstrSQL); QString qstrParam; int intParamNum; int intStartIndex = 0; + m_externalData = false; m_cursor = 0; m_connection = pDb; m_schema = 0; // Initialize some privates - m_qstrName = qstrPName; m_qstrQuery = qstrSQL; kDebug() << m_qstrName << ":" << m_qstrQuery; - //For now, lets assume we only support simple tables or queries - if (doexec) { - execute(); + m_valid = executeInternal(); +} + +//!Connect to an external data source +//!connStr is in the form driver|connection_string|table +orQuery::orQuery(const QString & connStr) +{ + m_externalData = true; + m_cursor = 0; + + QStringList extConn = connStr.split("|"); + + if (extConn.size() == 3) + { + KexiMigration::MigrateManager mm; + + m_km = mm.driver(extConn[0]); + KexiDB::ConnectionData cd; + KexiMigration::Data dat; + cd.setFileName(extConn[1]); + dat.source = &cd; + m_km->setData(&dat); + m_valid = m_km->connectSource(); + QStringList names; + + if (m_valid) { + m_valid = m_km->readTableSchema(extConn[2], ts); } - + if (m_valid) { + m_schema = new KexiDB::TableOrQuerySchema(ts); + } + m_valid = m_km->tableNames(names); + if (m_valid && names.contains(extConn[2])){ + m_valid = m_km->readFromTable(extConn[2]); + } + } } orQuery::~orQuery() { - m_cursor->close(); - delete m_cursor; - m_cursor = 0; + if (m_externalData) + { + delete m_km; + } + else + { + if (m_cursor) { + m_cursor->close(); + delete m_cursor; + m_cursor = 0; + } + } } -bool orQuery::execute() +bool orQuery::executeInternal() { if (m_connection && m_cursor == 0) { //NOTE we can use the variation of executeQuery to pass in parameters @@ -92,19 +127,29 @@ uint orQuery::fieldNumber(const QString &fld) { + KexiDB::QueryColumnInfo::Vector flds; + uint x = -1; - if (m_cursor->query()) { - KexiDB::QueryColumnInfo::Vector flds = m_cursor->query()->fieldsExpanded(); - for (int i = 0; i < flds.size() ; ++i) { - if (fld.toLower() == flds[i]->aliasOrName()) { - x = i; - } - } + if (m_externalData) { + flds = schema().columns(); } + else { + if (m_cursor->query()) { + flds = m_cursor->query()->fieldsExpanded(); + + } + } + for (int i = 0; i < flds.size() ; ++i) { + if (fld.toLower() == flds[i]->aliasOrName().toLower()) { + x = i; + } + + } + return x; } -KexiDB::TableOrQuerySchema &orQuery::schema() +KexiDB::TableOrQuerySchema &orQuery::schema() const { if (m_schema) return *m_schema; @@ -115,43 +160,102 @@ } } -// -// Class orData -// -orData::orData() +QVariant orQuery::value(unsigned int i) { - m_valid = false; - m_query = 0; + if(!m_valid) + return QVariant(); + + if (m_externalData) { + return m_km->value(i); + } else { + return m_cursor->value(i); + } } -void orData::setQuery(orQuery *qryPassed) +QVariant orQuery::value(const QString &fld) { - m_query = qryPassed; - m_valid = (m_query != 0 && m_field.length()); + if(!m_valid) + return QVariant(); + + int i = fieldNumber(fld); + + if (m_externalData) { + return m_km->value(i); + } else { + return m_cursor->value(i); + } } -void orData::setField(const QString &qstrPPassed) +bool orQuery::moveNext() { - m_field = qstrPPassed; - m_valid = (m_query != 0 && m_field.length()); + if (!m_valid) + return false; + + if (m_externalData) { + return m_km->moveNext(); + } else { + return m_cursor->moveNext(); + } } -const QString &orData::getValue() +bool orQuery::movePrevious() { - if (m_valid && m_query->getQuery()) { - m_value = m_query->getQuery()->value(m_query->fieldNumber(m_field)).toString(); - } else { - kDebug() << "Not Valid"; - } - return m_value; + if(!m_valid) + return false; + + if (m_externalData) { + return m_km->movePrevious(); + } else { + if (m_cursor) return m_cursor->movePrev(); + } } -const QByteArray &orData::getRawValue() +bool orQuery::moveFirst() { - if (m_valid && m_query->getQuery()) { - m_rawValue = m_query->getQuery()->value(m_query->fieldNumber(m_field)).toByteArray(); - } + if(!m_valid) + return false; + + if (m_externalData) { + return m_km->moveFirst(); + } else { + if (m_cursor) return m_cursor->moveFirst(); + } +} - return m_rawValue; +bool orQuery::moveLast() +{ + if(!m_valid) + return false; + + if (m_externalData) { + return m_km->moveLast(); + } else { + if (m_cursor) return m_cursor->moveLast(); + } } +long orQuery::at() const +{ + if(!m_valid) + return 0; + + if (m_externalData) { + return 0; + } else { + return m_cursor->at(); + } +} + +long orQuery::recordCount() +{ + if (m_externalData) { + return 1; + } + else { + if (schema().table() || schema().query()) { + return KexiDB::rowCount(schema()); + } else { + return 1; + } + } +} Index: backend/renderer/orutils.h =================================================================== --- backend/renderer/orutils.h (revision 985390) +++ backend/renderer/orutils.h (working copy) @@ -23,10 +23,13 @@ #include <QString> #include <QStringList> -#include <QSqlDatabase> #include <kexidb/cursor.h> #include <kexidb/utils.h> + +#include <migration/migratemanager.h> +#include <migration/keximigrate.h> + // // These classes are used by the original orRender class and the new // ORPreRenderer class as internal structures for processing. There is @@ -50,56 +53,48 @@ KexiDB::Connection *m_connection; KexiDB::TableOrQuerySchema *m_schema; + + KexiMigration::KexiMigrate *m_km; + + bool executeInternal(); + + bool m_externalData; + bool m_valid; + KexiDB::TableSchema ts; + public: - orQuery(); - orQuery(const QString &, const QString &, bool doexec, KexiDB::Connection *conn = 0); - + orQuery(const QString &, KexiDB::Connection *conn); //Internal Data + orQuery(const QString &); //External data + virtual ~orQuery(); - - inline bool queryExecuted() const { - return (m_cursor != 0); + + inline KexiDB::Connection *connection() const { + if (!m_externalData) + return m_connection; + + return 0; } - bool execute(); - inline KexiDB::Cursor *getQuery() { - return m_cursor; - } inline const QString &getSql() const { return m_qstrQuery; } - inline const QString &getName() const { - return m_qstrName; - } uint fieldNumber(const QString &fld); - KexiDB::TableOrQuerySchema &schema(); + KexiDB::TableOrQuerySchema &schema() const; + + QVariant value(unsigned int); + QVariant value(const QString &); + + bool moveNext(); + bool movePrevious(); + bool moveFirst(); + bool moveLast(); + + long at() const; + + long recordCount(); }; - -// Data class -class orData -{ -private: - orQuery *m_query; - QString m_field; - QString m_value; - bool m_valid; - QByteArray m_rawValue; - -public: - orData(); - - void setQuery(orQuery *qryPassed); - void setField(const QString &qstrPPassed); - - inline bool isValid() const { - return m_valid; - } - - const QString &getValue(); - const QByteArray &getRawValue(); -}; - #endif // __ORUTILS_H__ Index: backend/renderer/scripting/krscripthandler.cpp =================================================================== --- backend/renderer/scripting/krscripthandler.cpp (revision 985390) +++ backend/renderer/scripting/krscripthandler.cpp (working copy) @@ -44,9 +44,9 @@ #include <renderobjects.h> #include "krscriptdraw.h" -KRScriptHandler::KRScriptHandler(const KexiDB::Cursor* cu, KRReportData* d) +KRScriptHandler::KRScriptHandler(const orQuery *cu, KRReportData* d) { - m_connection = cu->connection(); + //m_connection = cu->connection(); m_reportData = d; m_cursor = cu; Index: backend/renderer/scripting/krscriptfunctions.h =================================================================== --- backend/renderer/scripting/krscriptfunctions.h (revision 985390) +++ backend/renderer/scripting/krscriptfunctions.h (working copy) @@ -24,6 +24,7 @@ #include <QString> #include <kexidb/connection.h> #include <kexidb/cursor.h> +#include "orutils.h" /** @author @@ -32,14 +33,14 @@ { Q_OBJECT public: - KRScriptFunctions(const KexiDB::Cursor*); + KRScriptFunctions(const orQuery*); ~KRScriptFunctions(); void setWhere(const QString&); void setSource(const QString&); private: KexiDB::Connection *m_connection; - const KexiDB::Cursor *m_cursor; + const orQuery *m_cursor; QString m_source; qreal math(const QString &, const QString &); Index: backend/renderer/scripting/krscripthandler.h =================================================================== --- backend/renderer/scripting/krscripthandler.h (revision 985390) +++ backend/renderer/scripting/krscripthandler.h (working copy) @@ -26,6 +26,7 @@ #include <kross/core/action.h> #include "krscriptconstants.h" #include <kdeversion.h> +#include "orutils.h" class KRScriptFunctions; class KRScriptDebug; @@ -42,7 +43,7 @@ { Q_OBJECT public: - KRScriptHandler(const KexiDB::Cursor *, KRReportData*); + KRScriptHandler(const orQuery */*KexiDB::Cursor **/, KRReportData*); ~KRScriptHandler(); void setSource(const QString &s); QVariant evaluate(const QString&); @@ -74,9 +75,11 @@ QString scriptCode(); - KexiDB::Connection *m_connection; - const KexiDB::Cursor *m_cursor; + //KexiDB::Connection *m_connection; + //const KexiDB::Cursor *m_cursor; + const orQuery *m_cursor; + QString m_source; KRReportData *m_reportData; Index: backend/renderer/scripting/krscriptfunctions.cpp =================================================================== --- backend/renderer/scripting/krscriptfunctions.cpp (revision 985390) +++ backend/renderer/scripting/krscriptfunctions.cpp (working copy) @@ -21,9 +21,10 @@ #include <kexidb/cursor.h> #include <kdebug.h> -KRScriptFunctions::KRScriptFunctions(const KexiDB::Cursor *c) +KRScriptFunctions::KRScriptFunctions(const orQuery *c) { m_cursor = c; + m_connection = m_cursor->connection();; } @@ -99,11 +100,11 @@ } - KexiDB::QueryColumnInfo::Vector flds = m_cursor->query()->fieldsExpanded(); + KexiDB::QueryColumnInfo::Vector flds = m_cursor->schema().columns(); for (int i = 0; i < flds.size() ; ++i) { if (flds[i]->aliasOrName().toLower() == field.toLower()) { - val = const_cast<KexiDB::Cursor*>(m_cursor)->value(i); + val = const_cast<orQuery*>(m_cursor)->value(i); } } Index: backend/renderer/orprerender.cpp =================================================================== --- backend/renderer/orprerender.cpp (revision 985390) +++ backend/renderer/orprerender.cpp (working copy) @@ -91,13 +91,6 @@ orQuery* _query; QList<OROTextBox*> _postProcText; - QMap<ORDataData, qreal> _subtotPageCheckPoints; - QMap<ORDataData, qreal> * _subtotContextMap; - KRDetailSectionData * _subtotContextDetail; - bool _subtotContextPageFooter; - - bool populateData(const ORDataData &, orData &); - void createNewPage(); qreal finishCurPage(bool = false); qreal finishCurPageSize(bool = false); @@ -130,11 +123,6 @@ _pageCounter = 0; _maxHeight = _maxWidth = 0.0; _query = 0; - _subtotContextMap = 0; -// _subtotContextDetail = 0; - _subtotContextPageFooter = false; - - } ORPreRenderPrivate::~ORPreRenderPrivate() @@ -147,35 +135,11 @@ _postProcText.clear(); } -bool ORPreRenderPrivate::populateData(const ORDataData & dataSource, orData &dataTarget) -{ - - dataTarget.setQuery(_query); - dataTarget.setField(dataSource.column); - return true; - -} - void ORPreRenderPrivate::createNewPage() { if (_pageCounter > 0) finishCurPage(); -#if 0 - //TODO Totals - // get the checkpoints for the page footers - QMapIterator<ORDataData, qreal> it(_subtotPageCheckPoints); - while (it.hasNext()) { - it.next(); -// qreal d = 0.0; - ORDataData data = it.key(); -// XSqlQuery * xqry = getQuerySource ( data.query )->getQuery(); -// if ( xqry ) -// d = xqry->getFieldTotal ( data.column ); -// _subtotPageCheckPoints.insert ( it.key(), d ); - } -#endif - _pageCounter++; //Update the page count script value @@ -185,6 +149,7 @@ _page = new OROPage(0); _document->addPage(_page); + //TODO calculate past page bool lastPage = false; _yOffset = _topMargin; @@ -205,7 +170,6 @@ { qreal retval = 0.0; - _subtotContextPageFooter = true; if (lastPage && _reportData->pgfoot_last != 0) retval = renderSectionSize(* (_reportData->pgfoot_last)); else if (_pageCounter == 1 && _reportData->pgfoot_first) @@ -216,7 +180,6 @@ retval = renderSectionSize(* (_reportData->pgfoot_even)); else if (_reportData->pgfoot_any != 0) retval = renderSectionSize(* (_reportData->pgfoot_any)); - _subtotContextPageFooter = false; kDebug() << retval; return retval; @@ -229,7 +192,7 @@ qreal retval = 0.0; kDebug() << offset; - _subtotContextPageFooter = true; + if (lastPage && _reportData->pgfoot_last != 0) { kDebug() << "Last Footer"; _yOffset = offset - renderSectionSize(* (_reportData->pgfoot_last)); @@ -251,7 +214,6 @@ _yOffset = offset - renderSectionSize(* (_reportData->pgfoot_any)); retval = renderSection(* (_reportData->pgfoot_any)); } - _subtotContextPageFooter = false; return retval; } @@ -261,27 +223,19 @@ kDebug(); if (detailData.m_detailSection != 0) { - KexiDB::Cursor *curs = 0; - _subtotContextDetail = &detailData; - if (_query) { - curs = _query->getQuery(); -// //TODO init the engine earlier? + //TODO init the engine earlier? _handler->setSource(_query->getSql()); } - if (curs && !curs->eof()) { + if (_query/* && !curs->eof()*/) { QStringList keys; QStringList keyValues; bool status; int i = 0, pos = 0, cnt = 0; ORDetailGroupSectionData * grp = 0; - curs->moveFirst(); - if (_query->schema().table() || _query->schema().query()) { - _recordCount = KexiDB::rowCount(_query->schema()); - } else { - _recordCount = 1; - } + _query->moveFirst(); + _recordCount = _query->recordCount(); kDebug() << "Record Count:" << _recordCount; @@ -295,42 +249,46 @@ } keys.append(grp->column); if (!keys[i].isEmpty()) - keyValues.append(curs->value(_query->fieldNumber(keys[i])).toString()); + keyValues.append(_query->value(_query->fieldNumber(keys[i])).toString()); else keyValues.append(QString()); - - _subtotContextMap = & (grp->_subtotCheckPoints); - + //Tell interested parties we're about to render a header kDebug() << "EMIT1"; emit(enteredGroup(keys[i], keyValues[i])); if (grp->head) renderSection(* (grp->head)); - _subtotContextMap = 0; } do { - int l = curs->at(); + kDebug() << "...getting pos"; + long l = _query->at(); kDebug() << "At:" << l << "Y:" << _yOffset; if (renderSectionSize(* (detailData.m_detailSection)) + finishCurPageSize((l + 1 == _recordCount)) + _bottomMargin + _yOffset >= _maxHeight) { - if (l > 0) - curs->movePrev(); - createNewPage(); - if (l > 0) - curs->moveNext(); + if (l > 0) { + kDebug() << "...moving prev"; + _query->movePrevious(); + kDebug() << "...creating new page"; + createNewPage(); + kDebug() << "...moving next"; + _query->moveNext(); + } } renderSection(* (detailData.m_detailSection)); - - status = curs->moveNext(); + kDebug() << "...moving next"; + if (_query) + status = _query->moveNext(); + kDebug() << "...done"; + if (status == true && keys.count() > 0) { // check to see where it is we need to start pos = -1; // if it's still -1 by the time we are done then no keyValues changed for (i = 0; i < keys.count(); i++) { - if (keyValues[i] != curs->value(_query->fieldNumber(keys[i])).toString()) { + if (keyValues[i] != _query->value(_query->fieldNumber(keys[i])).toString()) { pos = i; break; } @@ -339,7 +297,7 @@ // don't bother if nothing has changed if (pos != -1) { // roll back the query and go ahead if all is good - status = curs->movePrev(); + status = _query->movePrevious(); if (status == true) { // print the footers as needed // any changes made in this for loop need to be duplicated @@ -350,50 +308,38 @@ createNewPage(); do_break = false; grp = detailData.m_groupList[i]; - _subtotContextMap = & (grp->_subtotCheckPoints); + if (grp->foot) { if (renderSectionSize(* (grp->foot)) + finishCurPageSize() + _bottomMargin + _yOffset >= _maxHeight) createNewPage(); renderSection(* (grp->foot)); } - _subtotContextMap = 0; - // reset the sub-total values for this group - QMapIterator<ORDataData, qreal> it(grp->_subtotCheckPoints); - while (it.hasNext()) { - it.next(); - qreal d = 0.0; - ORDataData data = it.key(); - KexiDB::Cursor * xqry = _query->getQuery(); - if (xqry) { -//TODO field totals d = xqry->getFieldTotal ( data.column ); - } - grp->_subtotCheckPoints.insert(it.key(), d); - } + if (ORDetailGroupSectionData::BreakAfterGroupFoot == grp->pagebreak) do_break = true; } // step ahead to where we should be and print the needed headers // if all is good - status = curs->moveNext(); + status = _query->moveNext(); if (do_break) createNewPage(); if (status == true) { for (i = pos; i < cnt; i++) { grp = detailData.m_groupList[i]; - _subtotContextMap = & (grp->_subtotCheckPoints); + if (grp->head) { if (renderSectionSize(* (grp->head)) + finishCurPageSize() + _bottomMargin + _yOffset >= _maxHeight) { - curs->movePrev(); + _query->movePrevious(); createNewPage(); - curs->moveNext(); + _query->moveNext(); } renderSection(* (grp->head)); } - _subtotContextMap = 0; + if (!keys[i].isEmpty()) - keyValues[i] = curs->value(_query->fieldNumber(keys[i])).toString(); + keyValues[i] = _query->value(_query->fieldNumber(keys[i])).toString(); //Tell interested parties thak key values changed kDebug() << "EMIT2"; @@ -405,35 +351,21 @@ } } while (status == true); - if (keys.size() > 0 && curs->movePrev()) { + if (keys.size() > 0 && _query->movePrevious()) { // finish footers // duplicated changes from above here for (i = cnt - 1; i >= 0; i--) { grp = detailData.m_groupList[i]; - _subtotContextMap = & (grp->_subtotCheckPoints); + if (grp->foot) { if (renderSectionSize(* (grp->foot)) + finishCurPageSize() + _bottomMargin + _yOffset >= _maxHeight) createNewPage(); renderSection(* (grp->foot)); emit(exitedGroup(keys[i], keyValues[i])); } - _subtotContextMap = 0; - // reset the sub-total values for this group - QMapIterator<ORDataData, qreal> it(grp->_subtotCheckPoints); - while (it.hasNext()) { - it.next(); - qreal d = 0.0; - ORDataData data = it.key(); - KexiDB::Cursor * xqry = _query->getQuery(); - if (xqry) { -//TODO field totals d = xqry->getFieldTotal ( data.column ); - } - grp->_subtotCheckPoints.insert(it.key(), d); - } } } } - _subtotContextDetail = 0; if (KRDetailSectionData::BreakAtEnd == detailData.m_pageBreak) createNewPage(); } @@ -454,13 +386,8 @@ // TODO: See if this can be simplified anymore than it already is. // All we need to know is how much stretch we are going to get. if (elemThis->type() == KRObjectData::EntityText) { - orData dataThis; KRTextData * t = elemThis->toText(); - populateData(t->data(), dataThis); - - //dataThis.setQuery(); - dataThis.setField(t->m_controlSource->value().toString()); QPointF pos = t->m_pos.toScene(); QSizeF size = t->m_size.toScene(); pos += QPointF(_leftMargin, _yOffset); @@ -473,7 +400,7 @@ QFont f = t->m_font->value().value<QFont>(); - qstrValue = dataThis.getValue(); + qstrValue = _query->value(t->m_controlSource->value().toString()).toString(); if (qstrValue.length()) { int pos = 0; int idx; @@ -524,7 +451,7 @@ qreal intHeight = POINT_TO_INCH(sectionData.height()) * KoGlobal::dpiY(); kDebug() << "Name: " << sectionData.name() << " Height: " << intHeight << "Objects: " << sectionData.objects().count(); - _handler->populateEngineParameters(_query->getQuery()); + //_handler->populateEngineParameters(_query->getQuery()); emit(renderingSection(const_cast<KRSectionData*>(§ionData), _page, QPointF(_leftMargin, _yOffset))); @@ -569,7 +496,6 @@ tb2->setPosition(l->m_pos.toPoint()); sec->addPrimitive(tb2); } else if (elemThis->type() == KRObjectData::EntityField) { - orData dataThis; KRFieldData* f = elemThis->toField(); QPointF pos = f->m_pos.toScene(); @@ -607,11 +533,12 @@ } else if (cs.left(1) == "$") { //Everything past $ is treated as a string str = cs.mid(1); } else { - QString qry = "Data Source"; + //QString qry = "Data Source"; QString clm = f->m_controlSource->value().toString(); - populateData(f->data(), dataThis); - str = dataThis.getValue(); + //populateData(f->data(), dataThis); + //str = dataThis.getValue(); + str = _query->value(clm).toString(); } tb->setText(str); _page->addPrimitive(tb); @@ -623,7 +550,6 @@ } else if (elemThis->type() == KRObjectData::EntityText) { QString qstrValue; - orData dataThis; KRTextData * t = elemThis->toText(); QString cs = t->m_controlSource->value().toString(); @@ -633,8 +559,7 @@ if (cs.left(1) == "$") { //Everything past $ is treated as a string qstrValue = cs.mid(1); } else { - populateData(t->data(), dataThis); - qstrValue = dataThis.getValue(); + qstrValue = _query->value(t->m_controlSource->value().toString()).toString(); } QPointF pos = t->m_pos.toScene(); @@ -748,7 +673,6 @@ sec->addPrimitive(l2); } else if (elemThis->type() == KRObjectData::EntityBarcode) { KRBarcodeData * bc = elemThis->toBarcode(); - orData dataThis; QPointF pos = bc->m_pos.toScene(); QSizeF size = bc->m_size.toScene(); @@ -756,24 +680,23 @@ QRectF rect = QRectF(pos, size); - populateData(bc->data(), dataThis); - + QString val = _query->value(bc->m_controlSource->value().toString()).toString(); QString fmt = bc->m_format->value().toString(); int align = bc->alignment(); if (fmt == "3of9") - render3of9(_page, rect, dataThis.getValue(), align); + render3of9(_page, rect, val, align); else if (fmt == "3of9+") - renderExtended3of9(_page, rect, dataThis.getValue(), align); + renderExtended3of9(_page, rect, val, align); else if (fmt == "128") - renderCode128(_page, rect, dataThis.getValue(), align); + renderCode128(_page, rect, val, align); else if (fmt == "ean13") - renderCodeEAN13(_page, rect, dataThis.getValue(), align); + renderCodeEAN13(_page, rect, val, align); else if (fmt == "ean8") - renderCodeEAN8(_page, rect, dataThis.getValue(), align); + renderCodeEAN8(_page, rect, val, align); else if (fmt == "upc-a") - renderCodeUPCA(_page, rect, dataThis.getValue(), align); + renderCodeUPCA(_page, rect, val, align); else if (fmt == "upc-e") - renderCodeUPCE(_page, rect, dataThis.getValue(), align); + renderCodeUPCE(_page, rect, val, align); else { //logMessage("Encountered unknown barcode format: %s",(const char*)bc->format); } @@ -782,9 +705,9 @@ QString uudata; QByteArray imgdata; if (!im->isInline()) { - orData dataThis; - populateData(im->data(), dataThis); - imgdata = dataThis.getRawValue(); +//TODO orData dataThis; +// populateData(im->data(), dataThis); +// imgdata = dataThis.getRawValue(); } else { uudata = im->inlineImageData(); imgdata = KCodecs::base64Decode(uudata.toLatin1()); @@ -818,7 +741,7 @@ QStringList masterFields = ch->masterFields(); for (int i = 0; i < masterFields.size(); ++i){ if (!masterFields[i].simplified().isEmpty()){ - ch->setLinkData(masterFields[i], _query->getQuery()->value(_query->fieldNumber(masterFields[i]))); + // ch->setLinkData(masterFields[i], _query->getQuery()->value(_query->fieldNumber(masterFields[i]))); } } ch->populateData(); @@ -844,7 +767,6 @@ sec->addPrimitive(p2); } } else if (elemThis->type() == KRObjectData::EntityCheck) { - orData dataThis; KRCheckData *cd = elemThis->toCheck(); OROCheck *chk = new OROCheck(); @@ -871,11 +793,8 @@ str = _handler->evaluate(cd->entityName()).toString(); #endif } else { - QString qry = "Data Source"; QString clm = cd->m_controlSource->value().toString(); - - populateData(cd->data(), dataThis); - str = dataThis.getValue(); + str = _query->value(clm).toString(); } bool v = false; @@ -899,59 +818,13 @@ _yOffset += intHeight; + kDebug() << _yOffset; return intHeight; } -qreal ORPreRenderPrivate::getNearestSubTotalCheckPoint(const ORDataData & d) -{ - // use the various contexts setup to determine what we should be - // doing and try and locate the nearest subtotal check point value - // and return that value... if we are unable to locate one then we - // will just return 0.0 which will case the final value to be a - // running total - - if (_subtotContextPageFooter) { - // first check to see if it's a page footer context - // as that can happen from anywhere at any time. - - // TODO Totals - if (_subtotPageCheckPoints.contains(d)) - return _subtotPageCheckPoints[d]; - - } else if (_subtotContextMap != 0) { - // next if an explicit map is set then we are probably - // rendering a group head/foot now so we will use the - // available their.. if it's not then we made a mistake - - if (_subtotContextMap->contains(d)) - return (*_subtotContextMap)[d]; - - } else if (_subtotContextDetail != 0) { - // finally if we are in a detail section then we will simply - // traverse that details sections groups from the most inner - // to the most outer and use the first check point we find - - // in actuallity we search from the outer most group to the - // inner most group and just take the last value found which - // would be the inner most group - - qreal dbl = 0.0; - ORDetailGroupSectionData * grp = 0; - for (int i = 0; i < (int) _subtotContextDetail->m_groupList.count(); i++) { - grp = _subtotContextDetail->m_groupList[i]; - if (grp->_subtotCheckPoints.contains(d)) - dbl = grp->_subtotCheckPoints[d]; - } - return dbl; - - } - - return 0.0; -} - void ORPreRenderPrivate::initEngine() { - _handler = new KRScriptHandler(_query->getQuery(), _reportData); + _handler = new KRScriptHandler(_query, _reportData); connect(this, SIGNAL(enteredGroup(const QString&, const QVariant&)), _handler, SLOT(slotEnteredGroup(const QString&, const QVariant&))); @@ -1058,20 +931,13 @@ d->_document->setPageOptions(rpo); -// QuerySource * qs = 0; - - d->_query = (new orQuery("Data Source", d->_reportData->query(), true, d->_conn)); - -//TODO field totals -// _internal->_subtotPageCheckPoints.clear(); -// for ( int i = 0; i < _internal->_reportData->trackTotal.count(); i++ ) -// { -// _internal->_subtotPageCheckPoints.insert ( _internal->_reportData->trackTotal[i], 0 ); -// XSqlQuery * xqry = _internal->getQuerySource ( _internal->_reportData->trackTotal[i].query )->getQuery(); -// if ( xqry ) -// xqry->trackFieldTotal ( _internal->_reportData->trackTotal[i].column ); -// } - + if (!d->_reportData->externalData()) { + d->_query = (new orQuery(d->_reportData->query(), d->_conn)); + } + else { + d->_query = new orQuery( d->_reportData->query() ); + } + d->initEngine(); d->createNewPage(); if (!label.isNull()) { @@ -1106,10 +972,10 @@ KRDetailSectionData * detailData = d->_reportData->detailsection; if (detailData->m_detailSection != 0) { orQuery *orqThis = d->_query; - KexiDB::Cursor *query; + //KexiDB::Cursor *query; - if ((orqThis != 0) && !((query = orqThis->getQuery())->eof())) { - query->moveFirst(); + if ((orqThis != 0))/* && !((query = orqThis->getQuery())->eof()))*/ { + //orqThis->moveFirst(); do { tmp = d->_yOffset; // store the value as renderSection changes it d->renderSection(* (detailData->m_detailSection)); @@ -1128,7 +994,7 @@ d->createNewPage(); } } - } while (query->moveNext()); + } while (orqThis->moveNext()); } } Index: backend/common/krreportdata.h =================================================================== --- backend/common/krreportdata.h (revision 985390) +++ backend/common/krreportdata.h (working copy) @@ -81,6 +81,11 @@ QString interpreter() { return m_interpreter; } + + bool externalData() { + return m_externalData; + } + KRDetailSectionData* detail() { return detailsection; } @@ -94,6 +99,7 @@ QString m_query; QString m_script; QString m_interpreter; + bool m_externalData; ReportPageOptions page; Index: backend/common/krbarcodedata.h =================================================================== --- backend/common/krbarcodedata.h (revision 985390) +++ backend/common/krbarcodedata.h (working copy) @@ -53,10 +53,6 @@ QString format(); void setFormat(const QString&); - ORDataData data() { - return ORDataData("Data Source", m_controlSource->value().toString()); - } - protected: QRect _rect(); KRSize m_size; Index: backend/common/krreportdata.cpp =================================================================== --- backend/common/krreportdata.cpp (revision 985390) +++ backend/common/krreportdata.cpp (working copy) @@ -59,9 +59,10 @@ QDomElement elemThis = section.item(nodeCounter).toElement(); if (elemThis.tagName() == "title") m_title = elemThis.text(); - else if (elemThis.tagName() == "datasource") + else if (elemThis.tagName() == "datasource") { m_query = elemThis.text(); - else if (elemThis.tagName() == "script") { + m_externalData = elemThis.attribute("external").toInt(); + } else if (elemThis.tagName() == "script") { m_script = elemThis.text(); m_interpreter = elemThis.attribute("interpreter"); } else if (elemThis.tagName() == "size") { Index: backend/wrtembed/reportdesigner.h =================================================================== --- backend/wrtembed/reportdesigner.h (revision 985390) +++ backend/wrtembed/reportdesigner.h (working copy) @@ -29,8 +29,6 @@ #include <QVBoxLayout> #include <QCloseEvent> -//#include "parsexmlutils.h" - #include <krreportdata.h> #include <kexidb/connection.h> #include <koproperty/Set.h> @@ -38,6 +36,9 @@ #include <kdebug.h> #include <krobjectdata.h> +#include <migration/keximigrate.h> +#include <migration/migratemanager.h> + class ReportGridOptions; class QDomDocument; class QGraphicsScene; @@ -62,8 +63,7 @@ { Q_OBJECT public: - - + ReportDesigner(QWidget *, KexiDB::Connection *); ReportDesigner(QWidget *, KexiDB::Connection *, const QString&); ~ReportDesigner(); @@ -185,6 +185,9 @@ void init(); bool m_modified; // true if this document has been modified, false otherwise KexiDB::Connection *m_conn; + KexiMigration::KexiMigrate *m_external; + QString m_externalTableName; + QStringList pageFormats(); virtual void resizeEvent(QResizeEvent * event); @@ -195,6 +198,7 @@ KoProperty::Set* m_itmset; KoProperty::Property* m_title; KoProperty::Property* m_dataSource; + KoProperty::Property* m_externalData; KoProperty::Property* m_pageSize; KoProperty::Property* m_orientation; KoProperty::Property* m_unit; Index: backend/wrtembed/reportdesigner.cpp =================================================================== --- backend/wrtembed/reportdesigner.cpp (revision 985390) +++ backend/wrtembed/reportdesigner.cpp (working copy) @@ -63,6 +63,7 @@ #include <QSplitter> #include <kexidb/connection.h> +#include <kexidb/connectiondata.h> #include <kexidb/utils.h> #include <kexidb/schemadata.h> #include <kexiutils/tristate.h> @@ -144,6 +145,7 @@ : QWidget(parent), d(new Private()) { m_conn = cn; + m_external = 0; init(); } void ReportDesigner::init() @@ -161,7 +163,6 @@ pageHeadFirst = pageHeadOdd = pageHeadEven = pageHeadLast = pageHeadAny = 0; pageFootFirst = pageFootOdd = pageFootEven = pageFootLast = pageFootAny = 0; - d->grid = new QGridLayout(this); d->grid->setSpacing(0); d->grid->setMargin(0); @@ -234,6 +235,7 @@ setReportTitle(it.firstChild().nodeValue()); } else if (n == "datasource") { setReportDataSource(it.firstChild().nodeValue()); + m_externalData->setValue(it.toElement().attribute("external")); } else if (n == "script") { m_interpreter->setValue(it.toElement().attribute("interpreter")); m_script->setValue(it.firstChild().nodeValue()); @@ -605,6 +607,7 @@ root.appendChild(title); QDomElement rds = doc.createElement("datasource"); + rds.setAttribute("external", m_externalData->value().toBool()); rds.appendChild(doc.createTextNode(reportDataSource())); root.appendChild(rds); @@ -822,18 +825,34 @@ QStringList qs; qs << ""; - if (isConnected()) { - //Get the list of fields in the selected query - KexiDB::TableOrQuerySchema *flds = new KexiDB::TableOrQuerySchema(m_conn, m_dataSource->value().toString().toLocal8Bit()); + if (!m_externalData->value().toBool()) { + if (isConnected()) { + //Get the list of fields in the selected query + KexiDB::TableOrQuerySchema *flds = new KexiDB::TableOrQuerySchema(m_conn, m_dataSource->value().toString().toLocal8Bit()); - KexiDB::QueryColumnInfo::Vector cs = flds->columns(); + KexiDB::QueryColumnInfo::Vector cs = flds->columns(); - for (int i = 0 ; i < cs.count(); ++i) { - qs << cs[i]->field->name(); - } - } else { + for (int i = 0 ; i < cs.count(); ++i) { + qs << cs[i]->field->name(); + } + } + else { kDebug() << "Cannot return field list"; + } } + else + { + if (!m_externalTableName.isEmpty()) { + KexiDB::TableSchema ts; + m_external->readTableSchema(m_externalTableName, ts); + + for (unsigned int i = 0; i < ts.fieldCount(); ++i) { + qs << ts.field(i)->name(); + } + } + + } + kDebug() << qs; return qs; } @@ -893,7 +912,10 @@ keys = queryList(); m_dataSource = new KoProperty::Property("DataSource", keys, keys, "", "Data Source"); - + m_dataSource->setOption("extraValueAllowed", "true"); + + m_externalData = new KoProperty::Property("ExternalData", QVariant(false), "External Data", "External Data"); + keys.clear(); keys = pageFormats(); m_pageSize = new KoProperty::Property("PageSize", keys, keys, "A4", "Page Size"); @@ -930,6 +952,7 @@ m_script = new KoProperty::Property("Script", keys, keys, "", "Object Script"); m_set->addProperty(m_title); + m_set->addProperty(m_externalData); m_set->addProperty(m_dataSource); m_set->addProperty(m_pageSize); m_set->addProperty(m_orientation); @@ -966,6 +989,22 @@ m_set->property("TopMargin").setOption("unit", newstr); m_set->property("BottomMargin").setOption("unit", newstr); } + if ((p.name() == "DataSource" || p.name() == "ExternalData") && m_externalData->value().toBool()) + { + KexiMigration::MigrateManager mm; + QStringList md = m_dataSource->value().toString().split("|"); + if (md.size() == 3) { //Need 3 paramters + m_external = mm.driver(md[0]); + KexiDB::ConnectionData cd; + cd.setFileName(md[1]); + m_externalTableName = md[2]; + KexiMigration::Data dat; + dat.source = &cd; + m_external->setData(&dat); + m_external->connectSource(); + } + + } } /** Index: CMakeLists.txt =================================================================== --- CMakeLists.txt (revision 985390) +++ CMakeLists.txt (working copy) @@ -104,7 +104,7 @@ target_link_libraries(pgzkexireportpart2 ${KDE4_KDEUI_LIBS} ${QT_QTGUI_LIBRARY} ${QT_QTSCRIPT_LIBRARY} ${KDE4_KPARTS_LIBS} kexidb kexicore keximain ${KOPROPERTY_LIBS} ${QT_QT3SUPPORT_LIBRARY} kexiguiutils - kexiextendedwidgets kdchart ${KDE4_KROSSCORE_LIBS}) + kexiextendedwidgets kdchart keximigrate ${KDE4_KROSSCORE_LIBS}) if (SHOULD_BUILD_KSPREAD) target_link_libraries(pgzkexireportpart2 kspreadcommon) endif (SHOULD_BUILD_KSPREAD) _______________________________________________ Kexi mailing list Kexi@... https://mail.kde.org/mailman/listinfo/kexi |
|
|
Re: Keximigrate extension2009/6/22 Adam Pigg <piggz1@...>:
> Lo > > Attached is 3 patches to kexi. > > 1. Extend the keximigrate api to add a cursor style api - fix the txt plugin > to use this api Thanks! Missing readertest.cpp? And I suggest to move to test/ subdir. keximigrate.h: - please add space after //! - please remove ; after } bool TxtMigrate::drv_connect(): - check if m_migrateData->source->dbPath() an existing dir, otherwise return false and dont set mFolder - similarly in KSpreadMigrate::drv_connect() bool TxtMigrate::drv_disconnect(): - clear mFolder - delete(mDataFile) here TxtMigrate::TxtMigrate - init mDataFile to 0 bool TxtMigrate::drv_readFromTable(const QString & tableName): - possible MEMORY LEAK? first delete(mDataFile) here (yes, and in TxtMigrate::drv_disconnect() too) ^^ and file lock on Windows because it's not closed afterwards bool KSpreadMigrate::drv_disconnect() - for sanity add mKSDoc = 0 bool KSpreadMigrate::drv_tableNames(QStringList& tablenames) - use foreach() kspreadmigrate.cpp, kspreadmigrate.h - unset the executable bit kspreadmigrate.h - add standard file header that we use in KDE, update year backend/renderer/orutils: use more meaningful names for these members: - KexiMigration::KexiMigrate *m_km - KexiDB::TableSchema ts backend/common/krreportdata.h - add const to: bool externalData() General: - please use m_ prefix for member variables PS: I don't discuss the API now - before predicate we have no place for bigger refactorings... -- regards / pozdrawiam, Jaroslaw Staniek Kexi & KOffice (http://www.kexi-project.org, http://www.koffice.org) KDE Libraries for MS Windows (http://windows.kde.org) http://www.linkedin.com/in/jstaniek _______________________________________________ Kexi mailing list Kexi@... https://mail.kde.org/mailman/listinfo/kexi |
| Free embeddable forum powered by Nabble | Forum Help |