diff --git a/kexi/plugins/reports/kexidbreportdata.cpp b/kexi/plugins/reports/kexidbreportdata.cpp
index 578a3bf8e72..f93585c0340 100644
--- a/kexi/plugins/reports/kexidbreportdata.cpp
+++ b/kexi/plugins/reports/kexidbreportdata.cpp
@@ -1,406 +1,412 @@
/*
* Kexi Report Plugin
* Copyright (C) 2007-2009 by Adam Pigg (adam@piggz.co.uk)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
*/
#include "kexidbreportdata.h"
#include
#include
#include
#include
#include
class KexiDBReportData::Private
{
public:
explicit Private(KDbConnection *pDb)
: cursor(0), connection(pDb), originalSchema(0), copySchema(0)
{
}
~Private()
{
delete copySchema;
delete originalSchema;
delete cursor;
}
QString objectName;
KDbCursor *cursor;
KDbConnection *connection;
KDbQuerySchema *originalSchema;
KDbQuerySchema *copySchema;
};
KexiDBReportData::KexiDBReportData (const QString &objectName,
KDbConnection * pDb)
: d(new Private(pDb))
{
d->objectName = objectName;
getSchema();
}
KexiDBReportData::KexiDBReportData(const QString& objectName,
const QString& pluginId,
KDbConnection* pDb)
: d(new Private(pDb))
{
d->objectName = objectName;
getSchema(pluginId);
}
void KexiDBReportData::setSorting(const QList& sorting)
{
if (d->copySchema) {
if (sorting.isEmpty())
return;
KDbOrderByColumnList order;
for (int i = 0; i < sorting.count(); i++) {
order.appendField(d->copySchema, sorting[i].field, sorting[i].order == Qt::AscendingOrder);
}
d->copySchema->setOrderByColumnList(order);
} else {
qDebug() << "Unable to sort null schema";
}
}
void KexiDBReportData::addExpression(const QString& field, const QVariant& value, char relation)
{
if (d->copySchema) {
KDbField *fld = d->copySchema->findTableField(field);
if (fld) {
d->copySchema->addToWhereExpression(fld, value, KDbToken(relation));
}
} else {
qDebug() << "Unable to add expresstion to null schema";
}
}
KexiDBReportData::~KexiDBReportData()
{
close();
delete d;
}
bool KexiDBReportData::open()
{
if ( d->connection && d->cursor == 0 )
{
if ( d->objectName.isEmpty() )
{
return false;
}
else if ( d->copySchema)
{
qDebug() << "Opening cursor.." << *d->copySchema;
d->cursor = d->connection->executeQuery ( d->copySchema, 1 );
}
if ( d->cursor )
{
qDebug() << "Moving to first record..";
return d->cursor->moveFirst();
}
else
return false;
}
return false;
}
bool KexiDBReportData::close()
{
if ( d->cursor )
{
const bool ok = d->cursor->close();
delete d->cursor;
d->cursor = 0;
return ok;
}
return true;
}
bool KexiDBReportData::getSchema(const QString& pluginId)
{
if (d->connection)
{
delete d->originalSchema;
d->originalSchema = 0;
delete d->copySchema;
d->copySchema = 0;
if ((pluginId.isEmpty() || pluginId == "org.kexi-project.table")
&& d->connection->tableSchema(d->objectName))
{
qDebug() << d->objectName << "is a table..";
d->originalSchema = new KDbQuerySchema(d->connection->tableSchema(d->objectName));
}
else if ((pluginId.isEmpty() || pluginId == "org.kexi-project.query")
&& d->connection->querySchema(d->objectName))
{
qDebug() << d->objectName << "is a query..";
qDebug() << *d->connection->querySchema(d->objectName);
d->originalSchema = new KDbQuerySchema(*(d->connection->querySchema(d->objectName)));
}
if (d->originalSchema) {
const KDbNativeStatementBuilder builder(d->connection);
KDbEscapedString sql;
if (builder.generateSelectStatement(&sql, d->originalSchema)) {
qDebug() << "Original:" << sql;
} else {
qDebug() << "Original: ERROR";
}
qDebug() << *d->originalSchema;
d->copySchema = new KDbQuerySchema(*d->originalSchema);
qDebug() << *d->copySchema;
if (builder.generateSelectStatement(&sql, d->copySchema)) {
qDebug() << "Copy:" << sql;
} else {
qDebug() << "Copy: ERROR";
}
}
return true;
}
return false;
}
QString KexiDBReportData::sourceName() const
{
return d->objectName;
}
int KexiDBReportData::fieldNumber ( const QString &fld ) const
{
if (!d->cursor || !d->cursor->query()) {
return -1;
}
const KDbQueryColumnInfo::Vector fieldsExpanded(
d->cursor->query()->fieldsExpanded(KDbQuerySchema::Unique));
for (int i = 0; i < fieldsExpanded.size() ; ++i) {
if (0 == QString::compare(fld, fieldsExpanded[i]->aliasOrName(), Qt::CaseInsensitive)) {
return i;
}
}
return -1;
}
QStringList KexiDBReportData::fieldNames() const
{
if (!d->originalSchema) {
return QStringList();
}
QStringList names;
const KDbQueryColumnInfo::Vector fieldsExpanded(
d->originalSchema->fieldsExpanded(KDbQuerySchema::Unique));
for (int i = 0; i < fieldsExpanded.size(); i++) {
//! @todo in some Kexi mode captionOrAliasOrName() would be used here (more user-friendly)
names.append(fieldsExpanded[i]->aliasOrName());
}
return names;
}
QVariant KexiDBReportData::value ( unsigned int i ) const
{
if ( d->cursor )
return d->cursor->value ( i );
return QVariant();
}
QVariant KexiDBReportData::value ( const QString &fld ) const
{
int i = fieldNumber ( fld );
- if ( d->cursor )
+ if (d->cursor && i >= 0)
return d->cursor->value ( i );
return QVariant();
}
bool KexiDBReportData::moveNext()
{
if ( d->cursor )
return d->cursor->moveNext();
return false;
}
bool KexiDBReportData::movePrevious()
{
if ( d->cursor ) return d->cursor->movePrev();
return false;
}
bool KexiDBReportData::moveFirst()
{
if ( d->cursor ) return d->cursor->moveFirst();
return false;
}
bool KexiDBReportData::moveLast()
{
if ( d->cursor )
return d->cursor->moveLast();
return false;
}
qint64 KexiDBReportData::at() const
{
if ( d->cursor )
return d->cursor->at();
return 0;
}
qint64 KexiDBReportData::recordCount() const
{
if ( d->copySchema )
{
return KDb::recordCount ( d->copySchema );
}
return 1;
}
-#ifdef KREPORT_SCRIPTING
-QStringList KexiDBReportData::scriptList(const QString& interpreter) const
+static bool isInterpreterSupported(const QString &interpreterName)
+{
+ return 0 == interpreterName.compare(QLatin1String("javascript"), Qt::CaseInsensitive)
+ || 0 == interpreterName.compare(QLatin1String("qtscript"), Qt::CaseInsensitive);
+}
+
+QStringList KexiDBReportData::scriptList() const
{
QStringList scripts;
if( d->connection) {
QList scriptids = d->connection->objectIds(KexiPart::ScriptObjectType);
QStringList scriptnames = d->connection->objectNames(KexiPart::ScriptObjectType);
qDebug() << scriptids << scriptnames;
- qDebug() << interpreter;
//A blank entry
scripts << "";
int i = 0;
foreach(int id, scriptids) {
qDebug() << "ID:" << id;
tristate res;
QString script;
res = d->connection->loadDataBlock(id, &script, QString());
if (res == true) {
QDomDocument domdoc;
bool parsed = domdoc.setContent(script, false);
QDomElement scriptelem = domdoc.namedItem("script").toElement();
if (parsed && !scriptelem.isNull()) {
- if (interpreter == scriptelem.attribute("language") && scriptelem.attribute("scripttype") == "object") {
+ if (scriptelem.attribute("scripttype") == "object"
+ && isInterpreterSupported(scriptelem.attribute("language")))
+ {
scripts << scriptnames[i];
}
} else {
qDebug() << "Unable to parse script";
}
} else {
qDebug() << "Unable to loadDataBlock";
}
++i;
}
qDebug() << scripts;
}
return scripts;
}
-QString KexiDBReportData::scriptCode(const QString& scriptname, const QString& language) const
+QString KexiDBReportData::scriptCode(const QString& scriptname) const
{
QString scripts;
if (d->connection) {
QList scriptids = d->connection->objectIds(KexiPart::ScriptObjectType);
QStringList scriptnames = d->connection->objectNames(KexiPart::ScriptObjectType);
int i = 0;
foreach(int id, scriptids) {
qDebug() << "ID:" << id;
tristate res;
QString script;
res = d->connection->loadDataBlock(id, &script, QString());
if (res == true) {
QDomDocument domdoc;
bool parsed = domdoc.setContent(script, false);
if (! parsed) {
qDebug() << "XML parsing error";
return QString();
}
QDomElement scriptelem = domdoc.namedItem("script").toElement();
if (scriptelem.isNull()) {
qDebug() << "script domelement is null";
return QString();
}
QString interpretername = scriptelem.attribute("language");
- qDebug() << language << interpretername;
qDebug() << scriptelem.attribute("scripttype");
qDebug() << scriptname << scriptnames[i];
- if (language == interpretername && (scriptelem.attribute("scripttype") == "module" || scriptname == scriptnames[i])) {
+ if ((isInterpreterSupported(interpretername) && scriptelem.attribute("scripttype") == "module")
+ || scriptname == scriptnames[i])
+ {
scripts += '\n' + scriptelem.text().toUtf8();
}
++i;
} else {
qDebug() << "Unable to loadDataBlock";
}
}
}
return scripts;
}
-#endif
QStringList KexiDBReportData::dataSources() const
{
//Get the list of queries in the database
QStringList qs;
if (d->connection && d->connection->isConnected()) {
QList tids = d->connection->tableIds();
qs << "";
for (int i = 0; i < tids.size(); ++i) {
KDbTableSchema* tsc = d->connection->tableSchema(tids[i]);
if (tsc)
qs << tsc->name();
}
QList qids = d->connection->queryIds();
qs << "";
for (int i = 0; i < qids.size(); ++i) {
KDbQuerySchema* qsc = d->connection->querySchema(qids[i]);
if (qsc)
qs << qsc->name();
}
}
return qs;
}
KoReportData* KexiDBReportData::data(const QString& source)
{
return new KexiDBReportData(source, d->connection);
}
diff --git a/kexi/plugins/reports/kexidbreportdata.h b/kexi/plugins/reports/kexidbreportdata.h
index 579a631965f..1538574fbe2 100644
--- a/kexi/plugins/reports/kexidbreportdata.h
+++ b/kexi/plugins/reports/kexidbreportdata.h
@@ -1,83 +1,82 @@
/*
* Kexi Report Plugin
* Copyright (C) 2007-2009 by Adam Pigg (adam@piggz.co.uk)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
*/
#ifndef __KEXIDBREPORTDATA_H__
#define __KEXIDBREPORTDATA_H__
#include
#include
#include
#include
+#include
#include
/**
*/
class KexiDBReportData : public KoReportData
{
public:
KexiDBReportData(const QString &objectName, KDbConnection *conn);
/*!
* @a pluginId specifies type of @a objectName, a table or query.
* Types accepted:
* -"org.kexi-project.table"
* -"org.kexi-project.query"
* -empty QString() - attempt to resolve @a objectName
*/
KexiDBReportData(const QString &objectName, const QString& pluginId, KDbConnection *conn);
virtual ~KexiDBReportData();
virtual QStringList fieldNames() const;
virtual void setSorting(const QList& sorting);
virtual void addExpression(const QString &field, const QVariant &value, char relation = '=');
virtual QString sourceName() const;
virtual int fieldNumber(const QString &field) const;
virtual QVariant value(unsigned int) const;
virtual QVariant value(const QString &field) const;
virtual bool open();
virtual bool close();
virtual bool moveNext();
virtual bool movePrevious();
virtual bool moveFirst();
virtual bool moveLast();
virtual qint64 at() const;
virtual qint64 recordCount() const;
//Utility Functions
-#ifdef KREPORT_SCRIPTING
- virtual QStringList scriptList(const QString& language) const;
- virtual QString scriptCode(const QString& script, const QString& language) const;
-#endif
+ virtual QStringList scriptList() const;
+ virtual QString scriptCode(const QString& script) const;
virtual QStringList dataSources() const;
virtual KoReportData* data(const QString&);
private:
class Private;
Private * const d;
bool getSchema(const QString& pluginId = QString());
};
#endif
diff --git a/kexi/plugins/reports/kexireportview.cpp b/kexi/plugins/reports/kexireportview.cpp
index 34f1d9b1036..4da7c0a34fe 100644
--- a/kexi/plugins/reports/kexireportview.cpp
+++ b/kexi/plugins/reports/kexireportview.cpp
@@ -1,521 +1,511 @@
/*
* Kexi Report Plugin
* Copyright (C) 2007-2008 by Adam Pigg (adam@piggz.co.uk)
Copyright (C) 2014 Jarosław Staniek
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
*/
#include "kexireportview.h"
#include
#include "kexidbreportdata.h"
#ifndef KEXI_MOBILE
#include
//! @todo KEXI3
#if 0
#include "keximigratereportdata.h"
#endif
#endif
#include
#include
#include
-#ifdef KREPORT_SCRIPTING
-#include "../scripting/kexiscripting/kexiscriptadaptor.h"
-#endif
+//! @todo KEXI3 #include "../scripting/kexiscripting/kexiscriptadaptor.h"
#include
#include
#include
+#include
#include "krscriptfunctions.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
KexiReportView::KexiReportView(QWidget *parent)
: KexiView(parent), m_preRenderer(0), m_reportDocument(0) //! @todo KEXI3, m_kexi(0), m_functions(0)
{
setObjectName("KexiReportDesigner_DataView");
m_reportView = new KReportView(this);
layout()->addWidget(m_reportView);
#ifndef KEXI_MOBILE
m_pageSelector = new KexiRecordNavigator(*m_reportView->scrollArea(), m_reportView);
m_pageSelector->setInsertingButtonVisible(false);
m_pageSelector->setInsertingEnabled(false);
m_pageSelector->setLabelText(xi18nc("Page selector label", "Page:"));
m_pageSelector->setButtonToolTipText(KexiRecordNavigator::ButtonFirst, xi18n("Go to first page"));
m_pageSelector->setButtonWhatsThisText(KexiRecordNavigator::ButtonFirst, xi18n("Goes to first page"));
m_pageSelector->setButtonToolTipText(KexiRecordNavigator::ButtonPrevious, xi18n("Go to previous page"));
m_pageSelector->setButtonWhatsThisText(KexiRecordNavigator::ButtonPrevious, xi18n("Goes to previous page"));
m_pageSelector->setButtonToolTipText(KexiRecordNavigator::ButtonNext, xi18n("Go to next page"));
m_pageSelector->setButtonWhatsThisText(KexiRecordNavigator::ButtonNext, xi18n("Goes to next page"));
m_pageSelector->setButtonToolTipText(KexiRecordNavigator::ButtonLast, xi18n("Go to last page"));
m_pageSelector->setButtonWhatsThisText(KexiRecordNavigator::ButtonLast, xi18n("Goes to last page"));
m_pageSelector->setNumberFieldToolTips(xi18n("Current page number"), xi18n("Number of pages"));
m_pageSelector->setRecordHandler(this);
#endif
// -- setup local actions
QList viewActions;
QAction* a;
#ifndef KEXI_MOBILE
viewActions << (a = new QAction(koIcon("document-print"), xi18n("Print"), this));
a->setObjectName("print_report");
a->setToolTip(xi18n("Print report"));
a->setWhatsThis(xi18n("Prints the current report."));
connect(a, SIGNAL(triggered()), this, SLOT(slotPrintReport()));
KActionMenu *exportMenu = new KActionMenu(koIcon("document-export"), xi18nc("@title:menu","E&xport As"), this);
exportMenu->setObjectName("report_export_as");
exportMenu->setDelayed(false);
#endif
#ifdef KEXI_MOBILE
viewActions << (a = new QAction(xi18n("Export:"), this));
a->setEnabled(false); //!TODO this is a bit of a dirty way to add what looks like a label to the toolbar!
// " ", not "", is said to be needed in maemo, the icon didn't display properly without it
viewActions << (a = new QAction(koIcon("application-vnd.oasis.opendocument.text"), QLatin1String(" "), this));
#else
exportMenu->addAction(a = new QAction(koIcon("application-vnd.oasis.opendocument.text"),
xi18nc("open dialog to export as text document", "Text Document..."), this));
#endif
a->setObjectName("export_as_text_document");
a->setToolTip(xi18n("Export the report as a text document (in OpenDocument Text format)"));
a->setWhatsThis(xi18n("Exports the report as a text document (in OpenDocument Text format)."));
a->setEnabled(true);
connect(a, SIGNAL(triggered()), this, SLOT(slotExportAsTextDocument()));
#ifdef KEXI_MOBILE
viewActions << (a = new QAction(koIcon("application-pdf"), QLatin1String(" "), this));
#else
exportMenu->addAction(a = new QAction(koIcon("application-pdf"),
xi18nc("Portable Document Format...", "PDF..."), this));
#endif
a->setObjectName("export_as_pdf");
a->setToolTip(xi18n("Export as PDF"));
a->setWhatsThis(xi18n("Exports the current report as PDF."));
a->setEnabled(true);
connect(a, SIGNAL(triggered()), this, SLOT(slotExportAsPdf()));
#ifdef KEXI_MOBILE
viewActions << (a = new QAction(koIcon("application-vnd.oasis.opendocument.spreadsheet"), QLatin1String(" "), this));
#else
exportMenu->addAction(a = new QAction(koIcon("application-vnd.oasis.opendocument.spreadsheet"),
xi18nc("open dialog to export as spreadsheet", "Spreadsheet..."), this));
#endif
a->setObjectName("export_as_spreadsheet");
a->setToolTip(xi18n("Export the report as a spreadsheet (in OpenDocument Spreadsheet format)"));
a->setWhatsThis(xi18n("Exports the report as a spreadsheet (in OpenDocument Spreadsheet format)."));
a->setEnabled(true);
connect(a, SIGNAL(triggered()), this, SLOT(slotExportAsSpreadsheet()));
#ifdef KEXI_MOBILE
viewActions << (a = new QAction(koIcon("text-html"), QLatin1String(" "), this));
#else
exportMenu->addAction(a = new QAction(koIcon("text-html"),
xi18nc("open dialog to export as web page", "Web Page..."), this));
#endif
a->setObjectName("export_as_web_page");
a->setToolTip(xi18n("Export the report as a web page (in HTML format)"));
a->setWhatsThis(xi18n("Exports the report as a web page (in HTML format)."));
a->setEnabled(true);
connect(a, SIGNAL(triggered()), this, SLOT(slotExportAsWebPage()));
setViewActions(viewActions);
#ifndef KEXI_MOBILE
// setup main menu actions
QList mainMenuActions;
mainMenuActions << exportMenu;
setMainMenuActions(mainMenuActions);
connect(m_pageSelector, SIGNAL(nextButtonClicked()), this, SLOT(nextPage()));
connect(m_pageSelector, SIGNAL(prevButtonClicked()), this, SLOT(prevPage()));
connect(m_pageSelector, SIGNAL(firstButtonClicked()), this, SLOT(firstPage()));
connect(m_pageSelector, SIGNAL(lastButtonClicked()), this, SLOT(lastPage()));
#endif
}
KexiReportView::~KexiReportView()
{
qDebug();
delete m_preRenderer;
-#ifdef KREPORT_SCRIPTING
- delete m_kexi;
- delete m_functions;
-#endif
delete m_reportDocument;
}
void KexiReportView::slotPrintReport()
{
QPrinter printer(QPrinter::HighResolution);
QPainter painter;
KoReportRendererBase *renderer;
renderer = m_factory.createInstance("print");
QPointer dialog = new QPrintDialog(&printer, this);
if (dialog->exec() == QDialog::Accepted) {
KoReportRendererContext cxt;
cxt.printer = &printer;
cxt.painter = &painter;
renderer->render(cxt, m_reportDocument);
}
delete dialog;
delete renderer;
}
void KexiReportView::slotExportAsPdf()
{
QScopedPointer renderer(m_factory.createInstance("print"));
if (renderer) {
KoReportRendererContext cxt;
cxt.destinationUrl = getExportUrl(QLatin1String("application/pdf"),
xi18n("Export Report as PDF"),
"kfiledialog:///LastVisitedPDFExportPath/",
"pdf");
if (!cxt.destinationUrl.isValid()) {
return;
}
QPrinter printer;
QPainter painter;
printer.setOutputFileName(cxt.destinationUrl.path());
printer.setOutputFormat(QPrinter::PdfFormat);
printer.setColorMode(QPrinter::Color);
painter.begin(&printer);
cxt.printer = &printer;
cxt.painter = &painter;
if (!renderer->render(cxt, m_reportDocument)) {
KMessageBox::error(this,
xi18n("Exporting the report as PDF to %1 failed.", cxt.destinationUrl.toDisplayString()),
xi18n("Export Failed"));
} else {
openExportedDocument(cxt.destinationUrl);
}
}
}
QUrl KexiReportView::getExportUrl(const QString &mimetype, const QString &caption,
const QString &lastExportPath, const QString &extension)
{
QUrl result;
QString defaultSavePath;
if (lastExportPath.startsWith("kfiledialog:///")) {
defaultSavePath = lastExportPath + window()->partItem()->captionOrName() + "." + extension;
}
// loop until an url has been chosen or the file selection has been cancelled
const QMimeDatabase db;
const QString filterString = db.mimeTypeForName(mimetype).filterString();
while (true) {
QUrl result = QFileDialog::getSaveFileUrl(this, caption, QUrl::fromLocalFile(defaultSavePath),
filterString);
// not cancelled?
if (result.isValid()) {
if (KIO::NetAccess::exists(result, KIO::NetAccess::DestinationSide, this)) {
const KMessageBox::ButtonCode answer = KMessageBox::warningContinueCancel(this,
xi18n("The file %1 exists.\nDo you want to overwrite it?", result.path()),
caption, KGuiItem(xi18nc("@action:button Overwrite File", "Overwrite")));
// if overwriting not wanted, let select another url
if (answer == KMessageBox::Cancel) {
continue;
}
}
}
// decision has been made, leave loop
break;
}
return result;
}
void KexiReportView::openExportedDocument(const QUrl &destination)
{
const int answer =
KMessageBox::questionYesNo(
this,
xi18n("Do you want to open exported document?"),
QString(),
KStandardGuiItem::open(),
KStandardGuiItem::close());
if (answer == KMessageBox::Yes) {
(void)new KRun(destination, this->topLevelWidget());
}
}
void KexiReportView::slotExportAsSpreadsheet()
{
KoReportRendererBase *renderer;
KoReportRendererContext cxt;
renderer = m_factory.createInstance("ods");
if (renderer) {
cxt.destinationUrl = getExportUrl(QLatin1String("application/vnd.oasis.opendocument.spreadsheet"),
xi18n("Export Report as Spreadsheet"),
"kfiledialog:///LastVisitedODSExportPath/",
"ods");
if (!cxt.destinationUrl.isValid()) {
return;
}
if (!renderer->render(cxt, m_reportDocument)) {
KMessageBox::error(this,
xi18n("Failed to export the report as spreadsheet to %1.", cxt.destinationUrl.toDisplayString()),
xi18n("Export Failed"));
} else {
openExportedDocument(cxt.destinationUrl);
}
}
}
void KexiReportView::slotExportAsTextDocument()
{
KoReportRendererBase *renderer;
KoReportRendererContext cxt;
renderer = m_factory.createInstance("odt");
if (renderer) {
cxt.destinationUrl = getExportUrl(QLatin1String("application/vnd.oasis.opendocument.text"),
xi18n("Export Report as Text Document"),
"kfiledialog:///LastVisitedODTExportPath/",
"odt");
if (!cxt.destinationUrl.isValid()) {
return;
}
if (!renderer->render(cxt, m_reportDocument)) {
KMessageBox::error(this,
xi18n("Exporting the report as text document to %1 failed.", cxt.destinationUrl.toDisplayString()),
xi18n("Export Failed"));
} else {
openExportedDocument(cxt.destinationUrl);
}
}
}
void KexiReportView::slotExportAsWebPage()
{
KoReportRendererContext cxt;
KoReportRendererBase *renderer;
const QString dialogTitle = xi18n("Export Report as Web Page");
cxt.destinationUrl = getExportUrl(QLatin1String("text/html"),
dialogTitle,
"kfiledialog:///LastVisitedHTMLExportPath/",
"html");
if (!cxt.destinationUrl.isValid()) {
return;
}
const int answer =
KMessageBox::questionYesNo(
this,
xi18n("Would you like to export using a Cascading Style Sheet (CSS), "
"which will give an output closer to the original, "
"or export using a HTML Table, which outputs a much simpler format?"),
dialogTitle,
KGuiItem(xi18nc("@action:button", "Use CSS")),
KGuiItem(xi18nc("@action:button", "Use Table")));
if (answer == KMessageBox::Yes) {
renderer = m_factory.createInstance("htmlcss");
}
else {
renderer = m_factory.createInstance("htmltable");
}
if (!renderer->render(cxt, m_reportDocument)) {
KMessageBox::error(this,
xi18n("Exporting the report as web page to %1 failed.", cxt.destinationUrl.toDisplayString()),
xi18n("Export Failed"));
} else {
openExportedDocument(cxt.destinationUrl);
}
}
tristate KexiReportView::beforeSwitchTo(Kexi::ViewMode mode, bool *dontStore)
{
Q_UNUSED(mode);
Q_UNUSED(dontStore);
return true;
}
tristate KexiReportView::afterSwitchFrom(Kexi::ViewMode mode)
{
Q_UNUSED(mode);
qDebug();
if (tempData()->reportSchemaChangedInPreviousView) {
qDebug() << "Schema changed";
delete m_preRenderer;
qDebug() << tempData()->reportDefinition.tagName();
m_preRenderer = new KoReportPreRenderer(tempData()->reportDefinition);
if (m_preRenderer->isValid()) {
KoReportData *reportData = 0;
if (!tempData()->connectionDefinition.isNull()) {
reportData = sourceData(tempData()->connectionDefinition);
}
m_preRenderer->setSourceData(reportData);
m_preRenderer->setName(window()->partItem()->name());
-#ifdef KREPORT_SCRIPTING
//Add a kexi object to provide kexidb and extra functionality
- if(!m_kexi) {
- m_kexi = new KexiScriptAdaptor();
- }
- m_preRenderer->registerScriptObject(m_kexi, "Kexi");
+//! @todo KEXI3 if we want this if(!m_kexi) {
+// m_kexi = new KexiScriptAdaptor();
+// }
+// m_preRenderer->registerScriptObject(m_kexi, "Kexi");
//If using a kexidb source, add a functions scripting object
if (tempData()->connectionDefinition.attribute("type") == "internal") {
- //Delete old functions
- if (m_functions) {
- delete m_functions;
- }
-
m_functions = new KRScriptFunctions(reportData, KexiMainWindowIface::global()->project()->dbConnection());
m_preRenderer->registerScriptObject(m_functions, "field");
+ connect(m_preRenderer, SIGNAL(groupChanged(QMap)),
+ m_functions, SLOT(setGroupData(QMap)));
}
-#endif
if (m_reportDocument) {
qDebug() << "=======================================Deleting old document";
delete m_reportDocument;
}
m_reportDocument = m_preRenderer->generate();
if (m_reportDocument) {
m_reportView->setDocument(m_reportDocument);
#ifndef KEXI_MOBILE
m_pageSelector->setRecordCount(m_reportView->pageCount());
m_pageSelector->setCurrentRecordNumber(1);
#endif
}
} else {
KMessageBox::error(this, xi18n("Report schema appears to be invalid or corrupt"), xi18n("Opening failed"));
}
tempData()->reportSchemaChangedInPreviousView = false;
}
return true;
}
KoReportData* KexiReportView::sourceData(QDomElement e)
{
KoReportData *kodata = 0;
if (e.attribute("type") == "internal" && !e.attribute("source").isEmpty()) {
kodata = new KexiDBReportData(e.attribute("source"), KexiMainWindowIface::global()->project()->dbConnection());
}
#ifndef KEXI_MOBILE
//! @todo KEXI3
#if 0
if (e.attribute("type") == "external") {
kodata = new KexiMigrateReportData(e.attribute("source"));
}
#endif
#endif
return kodata;
}
KexiReportPart::TempData* KexiReportView::tempData() const
{
return static_cast(window()->data());
}
void KexiReportView::addNewRecordRequested()
{
}
void KexiReportView::moveToFirstRecordRequested()
{
m_reportView->moveToFirstPage();
#ifndef KEXI_MOBILE
m_pageSelector->setCurrentRecordNumber(m_reportView->currentPage());
#endif
}
void KexiReportView::moveToLastRecordRequested()
{
m_reportView->moveToLastPage();
#ifndef KEXI_MOBILE
m_pageSelector->setCurrentRecordNumber(m_reportView->currentPage());
#endif
}
void KexiReportView::moveToNextRecordRequested()
{
m_reportView->moveToNextPage();
#ifndef KEXI_MOBILE
m_pageSelector->setCurrentRecordNumber(m_reportView->currentPage());
#endif
}
void KexiReportView::moveToPreviousRecordRequested()
{
m_reportView->moveToPreviousPage();
#ifndef KEXI_MOBILE
m_pageSelector->setCurrentRecordNumber(m_reportView->currentPage());
#endif
}
void KexiReportView::moveToRecordRequested(int r)
{
Q_UNUSED(r);
}
int KexiReportView::currentRecord() const
{
return m_reportView->currentPage();
}
int KexiReportView::recordCount() const
{
return m_reportView->pageCount();
}
diff --git a/kexi/plugins/reports/kexireportview.h b/kexi/plugins/reports/kexireportview.h
index bcc6ccb4cfc..05fc6de0477 100644
--- a/kexi/plugins/reports/kexireportview.h
+++ b/kexi/plugins/reports/kexireportview.h
@@ -1,96 +1,93 @@
/*
* Kexi Report Plugin
* Copyright (C) 2007-2008 by Adam Pigg (adam@piggz.co.uk)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
*/
#ifndef KEXIREPORTVIEW_H
#define KEXIREPORTVIEW_H
#include
#include
+#include
#include
#include
#include
#include "kexireportpart.h"
class KoReportPreRenderer;
class ORODocument;
class KReportView;
-#ifdef KREPORT_SCRIPTING
-class KexiScriptAdaptor;
+//! @todo KEXI3 class KexiScriptAdaptor;
class KRScriptFunctions;
-#endif
#ifndef KEXI_MOBILE
class KexiRecordNavigator;
#endif
/**
@author Adam Pigg
*/
class KexiReportView : public KexiView, public KexiRecordNavigatorHandler
{
Q_OBJECT
public:
explicit KexiReportView(QWidget *parent);
~KexiReportView();
virtual tristate afterSwitchFrom(Kexi::ViewMode mode);
virtual tristate beforeSwitchTo(Kexi::ViewMode mode, bool *dontStore);
virtual void addNewRecordRequested();
virtual void moveToFirstRecordRequested();
virtual void moveToLastRecordRequested();
virtual void moveToNextRecordRequested();
virtual void moveToPreviousRecordRequested();
virtual void moveToRecordRequested(int r);
virtual int currentRecord() const;
virtual int recordCount() const;
private:
KoReportPreRenderer *m_preRenderer;
ORODocument *m_reportDocument;
KReportView *m_reportView;
#ifndef KEXI_MOBILE
KexiRecordNavigator *m_pageSelector;
#endif
KexiReportPart::TempData* tempData() const;
KoReportData* sourceData(QDomElement e);
-#ifdef KREPORT_SCRIPTING
- KexiScriptAdaptor *m_kexi;
+ //! @todo KEXI3 KexiScriptAdaptor *m_kexi;
KRScriptFunctions *m_functions;
-#endif
KoReportRendererFactory m_factory;
//! @todo KEXI3 add equivalent of kfiledialog:/// for lastExportPathOrVariable
QUrl getExportUrl(const QString &mimetype, const QString &caption,
const QString &lastExportPathOrVariable, const QString &extension);
private Q_SLOTS:
void slotPrintReport();
void slotExportAsPdf();
void slotExportAsSpreadsheet();
void slotExportAsWebPage();
void slotExportAsTextDocument();
void openExportedDocument(const QUrl &destination);
};
#endif
diff --git a/kexi/plugins/reports/krscriptfunctions.cpp b/kexi/plugins/reports/krscriptfunctions.cpp
index ac7e1aa78c6..760d2add926 100644
--- a/kexi/plugins/reports/krscriptfunctions.cpp
+++ b/kexi/plugins/reports/krscriptfunctions.cpp
@@ -1,108 +1,122 @@
/*
* Kexi Report Plugin
* Copyright (C) 2007-2008 by Adam Pigg
* Copyright (C) 2012 Jarosław Staniek
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
*/
#include "krscriptfunctions.h"
#include
#include
#include
KRScriptFunctions::KRScriptFunctions(const KoReportData* kodata, KDbConnection* conn)
{
m_cursor = kodata;
m_connection = conn;
- m_source = kodata->sourceName();
+
+ if (kodata) {
+ m_source = kodata->sourceName();
+ }
}
KRScriptFunctions::~KRScriptFunctions()
{
}
-void KRScriptFunctions::setWhere(const KDbEscapedString&w)
+void KRScriptFunctions::setGroupData(const QMap& groupData)
{
- m_where = w;
+ m_groupData = groupData;
}
qreal KRScriptFunctions::math(const QString &function, const QString &field)
{
- qreal ret;
+ QString ret = QLatin1String("0.0");
+
+ if (!m_connection) {
+ return 0.0;
+ }
+
KDbEscapedString sql = KDbEscapedString("SELECT " + function + "(" + field + ") FROM (" + m_source + ")");
- if (!m_where.isEmpty()) {
- sql += " WHERE(" + m_where + ')';
+ if (!m_groupData.isEmpty()) {
+ sql += " WHERE(" + where() + ')';
}
qDebug() << sql;
- KDbCursor *curs = m_connection->executeQuery(sql);
- if (curs) {
- ret = curs->value(0).toDouble();
- } else {
- ret = 0.0;
- }
- delete curs;
+ m_connection->querySingleString(sql,&ret);
- return ret;
+ return ret.toDouble();
}
qreal KRScriptFunctions::sum(const QString &field)
{
return math("SUM", field);
}
qreal KRScriptFunctions::avg(const QString &field)
{
return math("AVG", field);
}
qreal KRScriptFunctions::min(const QString &field)
{
return math("MIN", field);
}
qreal KRScriptFunctions::max(const QString &field)
{
return math("MAX", field);
}
qreal KRScriptFunctions::count(const QString &field)
{
return math("COUNT", field);
}
QVariant KRScriptFunctions::value(const QString &field)
{
QVariant val;
if (!m_cursor) {
qDebug() << "No cursor to get value of field " << field;
return val;
}
QStringList fields = m_cursor->fieldNames();
val = m_cursor->value(fields.indexOf(field));
if (val.type() == QVariant::String) {
// UTF-8 values are expected so convert this
return val.toString().toUtf8();
}
return val;
}
+KDbEscapedString KRScriptFunctions::where()
+{
+ QByteArray w;
+ QMap::const_iterator i = m_groupData.constBegin();
+ while (i != m_groupData.constEnd()) {
+ w += QLatin1Char('(') + i.key() + QLatin1String(" = '") + i.value().toString() + QLatin1String("') AND ");
+ ++i;
+ }
+ w.chop(4);
+ //kreportDebug() << w;
+ return KDbEscapedString(w);
+}
diff --git a/kexi/plugins/reports/krscriptfunctions.h b/kexi/plugins/reports/krscriptfunctions.h
index f1830029ff3..2b300667bc7 100644
--- a/kexi/plugins/reports/krscriptfunctions.h
+++ b/kexi/plugins/reports/krscriptfunctions.h
@@ -1,59 +1,63 @@
/*
* Kexi Report Plugin
* Copyright (C) 2007-2008 by Adam Pigg (adam@piggz.co.uk)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
*/
#ifndef KRSCRIPTFUNCTIONS_H
#define KRSCRIPTFUNCTIONS_H
#include
#include
#include
#include
#include
+#include
/**
@author
*/
-class KRScriptFunctions : public QObject
+class KRScriptFunctions : public KReportGroupTracker
{
Q_OBJECT
public:
KRScriptFunctions(const KoReportData *, KDbConnection*);
~KRScriptFunctions();
private:
KDbConnection *m_connection;
const KoReportData *m_cursor;
QString m_source;
qreal math(const QString &, const QString &);
- KDbEscapedString m_where;
+ QMap m_groupData;
+
+ KDbEscapedString where();
+
public Q_SLOTS:
- void setWhere(const KDbEscapedString&);
+ virtual void setGroupData(const QMap &groupData);
qreal sum(const QString &);
qreal avg(const QString &);
qreal min(const QString &);
qreal max(const QString &);
qreal count(const QString &);
QVariant value(const QString &);
};
#endif