0
0
mirror of https://github.com/fralx/LimeReport.git synced 2025-04-02 23:43:45 +03:00

Merge tag '1.6.7' into develop

Finish 1.6.7
This commit is contained in:
Alexander Arin 2022-08-23 01:31:26 +03:00
commit 40073d6eb3
56 changed files with 1978 additions and 517 deletions

View File

@ -3,15 +3,17 @@ cmake_minimum_required(VERSION 3.14)
set(LIMEREPORT_VERSION_MAJOR 1) set(LIMEREPORT_VERSION_MAJOR 1)
set(LIMEREPORT_VERSION_MINOR 6) set(LIMEREPORT_VERSION_MINOR 6)
set(LIMEREPORT_VERSION_RELEASE 6) set(LIMEREPORT_VERSION_RELEASE 8)
option(ENABLE_ZINT "Enable libzint build for barcode support" OFF) option(ENABLE_ZINT "Enable libzint build for barcode support" OFF)
option(LIMEREPORT_STATIC "Build LimeReport as static library" OFF) option(LIMEREPORT_STATIC "Build LimeReport as static library" OFF)
option(USE_QT6 "Use Qt6" OFF)
find_package( if(USE_QT6)
QT NAMES Qt6 Qt5 find_package(QT NAMES Qt6)
COMPONENTS Core Widgets Sql Network Xml Svg Qml PrintSupport REQUIRED else()
) find_package(QT NAMES Qt5)
endif(USE_QT6)
find_package( find_package(
Qt${QT_VERSION_MAJOR} Qt${QT_VERSION_MAJOR}
COMPONENTS Core Widgets Sql Network Xml Svg Qml PrintSupport REQUIRED COMPONENTS Core Widgets Sql Network Xml Svg Qml PrintSupport REQUIRED
@ -36,7 +38,7 @@ endif()
add_subdirectory(3rdparty) add_subdirectory(3rdparty)
add_subdirectory(designer EXCLUDE_FROM_ALL) add_subdirectory(designer EXCLUDE_FROM_ALL)
add_subdirectory(demo_r1 EXCLUDE_FROM_ALL) add_subdirectory(demo_r1 EXCLUDE_FROM_ALL)
set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON) set(CMAKE_AUTOUIC ON)
@ -78,6 +80,7 @@ ${PROJECT_NAME}/items/editors/lrtextalignmenteditorwidget.cpp
${PROJECT_NAME}/items/lrabstractlayout.cpp ${PROJECT_NAME}/items/lrabstractlayout.cpp
${PROJECT_NAME}/items/lralignpropitem.cpp ${PROJECT_NAME}/items/lralignpropitem.cpp
${PROJECT_NAME}/items/lrchartitem.cpp ${PROJECT_NAME}/items/lrchartitem.cpp
${PROJECT_NAME}/items/lrchartaxiseditor.cpp
${PROJECT_NAME}/items/lrchartitemeditor.cpp ${PROJECT_NAME}/items/lrchartitemeditor.cpp
${PROJECT_NAME}/items/lrhorizontallayout.cpp ${PROJECT_NAME}/items/lrhorizontallayout.cpp
${PROJECT_NAME}/items/lrimageitem.cpp ${PROJECT_NAME}/items/lrimageitem.cpp
@ -189,6 +192,7 @@ ${PROJECT_NAME}/items/editors/lrtextalignmenteditorwidget.h
${PROJECT_NAME}/items/lrabstractlayout.h ${PROJECT_NAME}/items/lrabstractlayout.h
${PROJECT_NAME}/items/lralignpropitem.h ${PROJECT_NAME}/items/lralignpropitem.h
${PROJECT_NAME}/items/lrchartitem.h ${PROJECT_NAME}/items/lrchartitem.h
${PROJECT_NAME}/items/lrchartaxiseditor.h
${PROJECT_NAME}/items/lrchartitemeditor.h ${PROJECT_NAME}/items/lrchartitemeditor.h
${PROJECT_NAME}/items/lreditableimageitemintf.h ${PROJECT_NAME}/items/lreditableimageitemintf.h
${PROJECT_NAME}/items/lrhorizontallayout.h ${PROJECT_NAME}/items/lrhorizontallayout.h
@ -285,6 +289,7 @@ ${PROJECT_NAME}/databrowser/lrsqleditdialog.ui
${PROJECT_NAME}/databrowser/lrvariabledialog.ui ${PROJECT_NAME}/databrowser/lrvariabledialog.ui
${PROJECT_NAME}/dialogdesigner/templates/Dialog.ui ${PROJECT_NAME}/dialogdesigner/templates/Dialog.ui
${PROJECT_NAME}/items/lrchartitemeditor.ui ${PROJECT_NAME}/items/lrchartitemeditor.ui
${PROJECT_NAME}/items/lrchartaxiseditor.ui
${PROJECT_NAME}/items/lrimageitemeditor.ui ${PROJECT_NAME}/items/lrimageitemeditor.ui
${PROJECT_NAME}/items/lrtextitemeditor.ui ${PROJECT_NAME}/items/lrtextitemeditor.ui
${PROJECT_NAME}/lraboutdialog.ui ${PROJECT_NAME}/lraboutdialog.ui
@ -340,6 +345,8 @@ set(GLOBAL_HEADERS
${CMAKE_CURRENT_BINARY_DIR}/config.h ${CMAKE_CURRENT_BINARY_DIR}/config.h
) )
set(PROJECT_NAME ${PROJECT_NAME}-qt${QT_VERSION_MAJOR})
if (LIMEREPORT_STATIC) if (LIMEREPORT_STATIC)
message(STATUS "STATIC LIBRARY") message(STATUS "STATIC LIBRARY")
add_library(${PROJECT_NAME} STATIC ${EXTRA_FILES} ${LIMEREPORT_SOURCES}) add_library(${PROJECT_NAME} STATIC ${EXTRA_FILES} ${LIMEREPORT_SOURCES})

View File

@ -3,8 +3,6 @@
## Official LimeReport web site [http://limereport.ru](http://limereport.ru) ## Official LimeReport web site [http://limereport.ru](http://limereport.ru)
## Donation [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.me/arinalex)
## Features ## Features
* Multi-platform support * Multi-platform support

View File

@ -141,7 +141,7 @@ RCC_DIR = $${ARCH_DIR}/$${BUILD_TYPE}/rcc
LIMEREPORT_VERSION_MAJOR = 1 LIMEREPORT_VERSION_MAJOR = 1
LIMEREPORT_VERSION_MINOR = 6 LIMEREPORT_VERSION_MINOR = 6
LIMEREPORT_VERSION_RELEASE = 0 LIMEREPORT_VERSION_RELEASE = 8
LIMEREPORT_VERSION = '$${LIMEREPORT_VERSION_MAJOR}.$${LIMEREPORT_VERSION_MINOR}.$${LIMEREPORT_VERSION_RELEASE}' LIMEREPORT_VERSION = '$${LIMEREPORT_VERSION_MAJOR}.$${LIMEREPORT_VERSION_MINOR}.$${LIMEREPORT_VERSION_RELEASE}'
DEFINES *= LIMEREPORT_VERSION_STR=\\\"$${LIMEREPORT_VERSION}\\\" DEFINES *= LIMEREPORT_VERSION_STR=\\\"$${LIMEREPORT_VERSION}\\\"

View File

@ -18,6 +18,6 @@ target_link_libraries(demo_r1 PRIVATE
Qt${QT_VERSION_MAJOR}::PrintSupport Qt${QT_VERSION_MAJOR}::PrintSupport
Qt${QT_VERSION_MAJOR}::Qml Qt${QT_VERSION_MAJOR}::Qml
Qt${QT_VERSION_MAJOR}::Sql Qt${QT_VERSION_MAJOR}::Sql
${PROJECT_NAME} ${PROJECT_NAME}-qt${QT_VERSION_MAJOR}
) )

View File

@ -14,5 +14,7 @@ target_include_directories(LRDesigner PUBLIC ${PROJECT_SOURCE_DIR}/include)
target_link_libraries(LRDesigner PUBLIC target_link_libraries(LRDesigner PUBLIC
Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Widgets
${PROJECT_NAME} Qt${QT_VERSION_MAJOR}::PrintSupport
Qt${QT_VERSION_MAJOR}::Qml
${PROJECT_NAME}-qt${QT_VERSION_MAJOR}
) )

View File

@ -104,7 +104,7 @@ namespace Const{
QString extractClassName(QString className); QString extractClassName(QString className);
QString escapeSimbols(const QString& value); QString escapeSimbols(const QString& value);
QString replaceHTMLSymbols(const QString &value); QString replaceHTMLSymbols(const QString &value);
#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 3) #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 1)
QVector<QString> normalizeCaptures(const QRegularExpressionMatch &reg); QVector<QString> normalizeCaptures(const QRegularExpressionMatch &reg);
#else #else
QVector<QString> normalizeCaptures(const QRegExp &reg); QVector<QString> normalizeCaptures(const QRegExp &reg);
@ -157,6 +157,16 @@ namespace Const{
#else #else
typedef QStyleOptionViewItem StyleOptionViewItem; typedef QStyleOptionViewItem StyleOptionViewItem;
#endif #endif
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 1)
QRegularExpression getRegEx(QString expression);
QRegularExpression getVariableRegEx();
QRegularExpression getFieldRegEx();
QRegularExpression getScriptRegEx();
QRegularExpression getGroupFunctionRegEx(QString functionName);
QRegularExpression getGroupFunctionNameRegEx(QString functionName);
QRegularExpression getNamedVariableRegEx(QString variableName);
#endif
class Enums class Enums
{ {

View File

@ -36,7 +36,11 @@ namespace LimeReport {
DataBrowserTree::DataBrowserTree(QWidget *parent) : DataBrowserTree::DataBrowserTree(QWidget *parent) :
QTreeWidget(parent){} QTreeWidget(parent){}
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
QMimeData *DataBrowserTree::mimeData(const QList<QTreeWidgetItem *> &items) const
#else
QMimeData *DataBrowserTree::mimeData(const QList<QTreeWidgetItem *> items) const QMimeData *DataBrowserTree::mimeData(const QList<QTreeWidgetItem *> items) const
#endif
{ {
QMimeData* result = QTreeWidget::mimeData(items); QMimeData* result = QTreeWidget::mimeData(items);
if (items.at(0)->type()==Row){ if (items.at(0)->type()==Row){

View File

@ -42,7 +42,11 @@ public:
enum NodeType{Connection, Table, Row, Category, Variable, ExternalVariable}; enum NodeType{Connection, Table, Row, Category, Variable, ExternalVariable};
explicit DataBrowserTree(QWidget *parent = 0); explicit DataBrowserTree(QWidget *parent = 0);
protected: protected:
QMimeData* mimeData(const QList<QTreeWidgetItem *> items) const; #if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
virtual QMimeData *mimeData(const QList<QTreeWidgetItem *> &items) const;
#else
virtual QMimeData *mimeData(const QList<QTreeWidgetItem*> items) const;
#endif
public slots: public slots:

View File

@ -28,20 +28,18 @@
* GNU General Public License for more details. * * GNU General Public License for more details. *
****************************************************************************/ ****************************************************************************/
#include "lrsqleditdialog.h" #include "lrsqleditdialog.h"
#include "ui_lrsqleditdialog.h"
#include "lrreportengine_p.h" #include "lrreportengine_p.h"
#include "ui_lrsqleditdialog.h"
#include <QDebug> #include <QDebug>
#include <QSqlDatabase>
#include <QMessageBox> #include <QMessageBox>
#include <QSqlDatabase>
namespace LimeReport{ namespace LimeReport {
SQLEditDialog::SQLEditDialog(QWidget *parent, LimeReport::DataSourceManager *dataSources, SQLDialogMode dialogMode) : SQLEditDialog::SQLEditDialog(QWidget *parent, LimeReport::DataSourceManager *dataSources, SQLDialogMode dialogMode)
QDialog(parent), : QDialog(parent), ui(new Ui::SQLEditDialog), m_datasources(dataSources), m_dialogMode(dialogMode),
ui(new Ui::SQLEditDialog),m_datasources(dataSources),m_dialogMode(dialogMode), m_oldDatasourceName(""), m_oldDatasourceName(""), m_settings(0), m_ownedSettings(false) {
m_settings(0), m_ownedSettings(false)
{
ui->setupUi(this); ui->setupUi(this);
m_masterDatasources = new QCompleter(this); m_masterDatasources = new QCompleter(this);
ui->leMaster->setCompleter(m_masterDatasources); ui->leMaster->setCompleter(m_masterDatasources);
@ -54,72 +52,72 @@ SQLEditDialog::SQLEditDialog(QWidget *parent, LimeReport::DataSourceManager *dat
ui->rbSubQuery->setVisible(false); ui->rbSubQuery->setVisible(false);
ui->leMaster->setVisible(false); ui->leMaster->setVisible(false);
ui->lbMaster->setVisible(false); ui->lbMaster->setVisible(false);
ui->fieldsMap->setHorizontalHeaderItem(0,new QTableWidgetItem("master")); ui->fieldsMap->setHorizontalHeaderItem(0, new QTableWidgetItem("master"));
ui->fieldsMap->setHorizontalHeaderItem(1,new QTableWidgetItem("detail")); ui->fieldsMap->setHorizontalHeaderItem(1, new QTableWidgetItem("detail"));
#ifdef HAVE_QT5
ui->fieldsMap->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); ui->fieldsMap->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
#else
ui->fieldsMap->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
#endif
ui->pnlChildDatasource->setVisible(false); ui->pnlChildDatasource->setVisible(false);
connect(ui->pbPreview, SIGNAL(pressed()), this, SLOT(slotPreviewData())); connect(ui->pbPreview, SIGNAL(pressed()), this, SLOT(slotPreviewData()));
connect(ui->pbHidePreview, SIGNAL(pressed()), this, SLOT(slotHidePreview())); connect(ui->pbHidePreview, SIGNAL(pressed()), this, SLOT(slotHidePreview()));
} }
SQLEditDialog::~SQLEditDialog() SQLEditDialog::~SQLEditDialog() {
{
delete ui; delete ui;
if (m_settings && m_ownedSettings) if (m_settings && m_ownedSettings)
delete m_settings; delete m_settings;
} }
QSettings *SQLEditDialog::settings(){ QSettings *SQLEditDialog::settings() {
if (m_settings){ if (m_settings) {
return m_settings; return m_settings;
} else { } else {
m_settings = new QSettings("LimeReport",QCoreApplication::applicationName()); m_settings = new QSettings("LimeReport", QCoreApplication::applicationName());
m_ownedSettings = true; m_ownedSettings = true;
return m_settings; return m_settings;
} }
} }
void SQLEditDialog::setSettings(QSettings *value, bool owned){ void SQLEditDialog::setSettings(QSettings *value, bool owned) {
if (m_settings && m_ownedSettings) delete m_settings; if (m_settings && m_ownedSettings)
delete m_settings;
m_settings = value; m_settings = value;
m_ownedSettings = owned; m_ownedSettings = owned;
} }
void SQLEditDialog::accept() void SQLEditDialog::accept() {
{
SQLEditResult result; SQLEditResult result;
if (ui->tabWidget->currentIndex() == 1){ if (ui->tabWidget->currentIndex() == 1) {
result.resultMode = SQLEditResult::CSVText; result.resultMode = SQLEditResult::CSVText;
} else if (!ui->cbSubdetail->isChecked()){ } else if (!ui->cbSubdetail->isChecked()) {
result.resultMode=SQLEditResult::Query; result.resultMode = SQLEditResult::Query;
} else { } else {
if (ui->rbSubQuery->isChecked()) result.resultMode = SQLEditResult::SubQuery; if (ui->rbSubQuery->isChecked())
else result.resultMode=SQLEditResult::SubProxy; result.resultMode = SQLEditResult::SubQuery;
else
result.resultMode = SQLEditResult::SubProxy;
} }
result.connectionName = ConnectionDesc::connectionNameForReport(ui->cbbConnection->currentText()); result.connectionName = ConnectionDesc::connectionNameForReport(ui->cbbConnection->currentText());
result.datasourceName=ui->leDatasourceName->text(); result.datasourceName = ui->leDatasourceName->text();
result.sql = ui->sqlText->toPlainText(); result.sql = ui->sqlText->toPlainText();
result.csv = ui->csvText->toPlainText(); result.csv = ui->csvText->toPlainText();
result.dialogMode = m_dialogMode; result.dialogMode = m_dialogMode;
result.oldDatasourceName = m_oldDatasourceName; result.oldDatasourceName = m_oldDatasourceName;
result.subdetail = ui->cbSubdetail->isChecked(); result.subdetail = ui->cbSubdetail->isChecked();
result.masterDatasource=ui->leMaster->text(); result.masterDatasource = ui->leMaster->text();
result.childDataSource=ui->leChild->text(); result.childDataSource = ui->leChild->text();
result.separator = ui->leSeparator->text(); result.separator = ui->leSeparator->text();
result.firstRowIsHeader = ui->cbUseFirstRowAsHeader->isChecked(); result.firstRowIsHeader = ui->cbUseFirstRowAsHeader->isChecked();
if (ui->fieldsMap->rowCount() > 0){ if (ui->fieldsMap->rowCount() > 0) {
for(int i=0; i< ui->fieldsMap->rowCount(); ++i){ for (int i = 0; i < ui->fieldsMap->rowCount(); ++i) {
LimeReport::FieldsCorrelation fieldsCorrelation; LimeReport::FieldsCorrelation fieldsCorrelation;
fieldsCorrelation.master = ui->fieldsMap->item(i,0) ? ui->fieldsMap->item(i,0)->data(Qt::DisplayRole).toString() : ""; fieldsCorrelation.master =
fieldsCorrelation.detail = ui->fieldsMap->item(i,1) ? ui->fieldsMap->item(i,1)->data(Qt::DisplayRole).toString() : ""; 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() : "";
result.fieldMap.append(fieldsCorrelation); result.fieldMap.append(fieldsCorrelation);
} }
} }
@ -128,87 +126,83 @@ void SQLEditDialog::accept()
check(); check();
emit signalSqlEditingFinished(result); emit signalSqlEditingFinished(result);
QDialog::accept(); QDialog::accept();
}catch(LimeReport::ReportError &exception){ } catch (LimeReport::ReportError &exception) {
QMessageBox::critical(this,tr("Error"),exception.what()); QMessageBox::critical(this, tr("Error"), exception.what());
} }
} }
void SQLEditDialog::showEvent(QShowEvent *) void SQLEditDialog::showEvent(QShowEvent *) {
{
ui->lblInfo->setVisible(false); ui->lblInfo->setVisible(false);
initConnections(); initConnections();
readSettings(); readSettings();
} }
void SQLEditDialog::closeEvent(QCloseEvent *) void SQLEditDialog::closeEvent(QCloseEvent *) { writeSetting(); }
{
writeSetting();
}
void SQLEditDialog::hideEvent(QHideEvent *) void SQLEditDialog::hideEvent(QHideEvent *) { writeSetting(); }
{
writeSetting();
}
void SQLEditDialog::check() void SQLEditDialog::check() {
{ if (ui->leDatasourceName->text().isEmpty())
if (ui->leDatasourceName->text().isEmpty()) throw LimeReport::ReportError(tr("Datasource Name is empty!")); throw LimeReport::ReportError(tr("Datasource Name is empty!"));
if (ui->sqlText->toPlainText().isEmpty() && (!ui->rbProxy) ) throw LimeReport::ReportError(tr("SQL is empty!")); if (ui->sqlText->toPlainText().isEmpty() && (!ui->rbProxy))
if (m_dialogMode==AddMode){ throw LimeReport::ReportError(tr("SQL is empty!"));
if (m_datasources->containsDatasource(ui->leDatasourceName->text())){ if (m_dialogMode == AddMode) {
throw LimeReport::ReportError(QString(tr("Datasource with name: \"%1\" already exists!")).arg(ui->leDatasourceName->text())); if (m_datasources->containsDatasource(ui->leDatasourceName->text())) {
throw LimeReport::ReportError(
QString(tr("Datasource with name: \"%1\" already exists!")).arg(ui->leDatasourceName->text()));
} }
} }
} }
void SQLEditDialog::initConnections() void SQLEditDialog::initConnections() {
{ foreach (QString connectionName, QSqlDatabase::connectionNames()) {
foreach(QString connectionName, QSqlDatabase::connectionNames()){ ui->cbbConnection->addItem(QIcon(":/databrowser/images/plug-connect.png"),
ui->cbbConnection->addItem(QIcon(":/databrowser/images/plug-connect.png"),ConnectionDesc::connectionNameForUser(connectionName)); ConnectionDesc::connectionNameForUser(connectionName));
} }
foreach(QString connectionName, m_datasources->connectionNames()){ foreach (QString connectionName, m_datasources->connectionNames()) {
connectionName = (connectionName.compare(QSqlDatabase::defaultConnection)==0) ? connectionName =
tr("defaultConnection") : connectionName; (connectionName.compare(QSqlDatabase::defaultConnection) == 0) ? tr("defaultConnection") : connectionName;
if (ui->cbbConnection->findText(connectionName,Qt::MatchExactly )==-1) if (ui->cbbConnection->findText(connectionName, Qt::MatchExactly) == -1)
ui->cbbConnection->addItem(QIcon(":/databrowser/images/plug-disconnect.png"),ConnectionDesc::connectionNameForUser(connectionName)); ui->cbbConnection->addItem(QIcon(":/databrowser/images/plug-disconnect.png"),
ConnectionDesc::connectionNameForUser(connectionName));
} }
ui->cbbConnection->setCurrentIndex(ui->cbbConnection->findText(m_defaultConnection)); ui->cbbConnection->setCurrentIndex(ui->cbbConnection->findText(m_defaultConnection));
if (!m_oldDatasourceName.isEmpty()){ if (!m_oldDatasourceName.isEmpty()) {
ui->cbbConnection->setCurrentIndex(ui->cbbConnection->findText(ConnectionDesc::connectionNameForUser(m_datasources->connectionName(m_oldDatasourceName)))); ui->cbbConnection->setCurrentIndex(ui->cbbConnection->findText(
ConnectionDesc::connectionNameForUser(m_datasources->connectionName(m_oldDatasourceName))));
} }
} }
void SQLEditDialog::setDataSources(LimeReport::DataSourceManager *dataSources, QString datasourceName) void SQLEditDialog::setDataSources(LimeReport::DataSourceManager *dataSources, QString datasourceName) {
{ m_datasources = dataSources;
m_datasources=dataSources; if (!datasourceName.isEmpty()) {
if (!datasourceName.isEmpty()){
ui->cbSubdetail->setEnabled(true); ui->cbSubdetail->setEnabled(true);
m_oldDatasourceName=datasourceName; m_oldDatasourceName = datasourceName;
ui->leDatasourceName->setText(datasourceName); ui->leDatasourceName->setText(datasourceName);
ui->sqlText->setText(dataSources->queryText(datasourceName)); ui->sqlText->setText(dataSources->queryText(datasourceName));
if (dataSources->isQuery(datasourceName)){ if (dataSources->isQuery(datasourceName)) {
initQueryMode(); initQueryMode();
} }
if (dataSources->isSubQuery(datasourceName)){ if (dataSources->isSubQuery(datasourceName)) {
initSubQueryMode(); initSubQueryMode();
ui->leMaster->setText(dataSources->subQueryByName(datasourceName)->master()); ui->leMaster->setText(dataSources->subQueryByName(datasourceName)->master());
} }
if (dataSources->isProxy(datasourceName)){ if (dataSources->isProxy(datasourceName)) {
initProxyMode(); initProxyMode();
LimeReport::ProxyDesc* proxyDesc = dataSources->proxyByName(datasourceName); LimeReport::ProxyDesc *proxyDesc = dataSources->proxyByName(datasourceName);
ui->leChild->setText(proxyDesc->child()); ui->leChild->setText(proxyDesc->child());
ui->leMaster->setText(proxyDesc->master()); ui->leMaster->setText(proxyDesc->master());
int curIndex=0; int curIndex = 0;
foreach(LimeReport::FieldMapDesc* fields, *proxyDesc->fieldsMap()){ foreach (LimeReport::FieldMapDesc *fields, *proxyDesc->fieldsMap()) {
ui->fieldsMap->setRowCount(curIndex+1); ui->fieldsMap->setRowCount(curIndex + 1);
ui->fieldsMap->setItem(curIndex,0,new QTableWidgetItem(fields->master())); ui->fieldsMap->setItem(curIndex, 0, new QTableWidgetItem(fields->master()));
ui->fieldsMap->setItem(curIndex,1,new QTableWidgetItem(fields->detail())); ui->fieldsMap->setItem(curIndex, 1, new QTableWidgetItem(fields->detail()));
curIndex++; curIndex++;
} }
} }
if (dataSources->isCSV(datasourceName)){ if (dataSources->isCSV(datasourceName)) {
ui->csvText->setPlainText(dataSources->csvByName(datasourceName)->csvText()); ui->csvText->setPlainText(dataSources->csvByName(datasourceName)->csvText());
ui->leSeparator->setText(dataSources->csvByName(datasourceName)->separator()); ui->leSeparator->setText(dataSources->csvByName(datasourceName)->separator());
ui->cbUseFirstRowAsHeader->setChecked(dataSources->csvByName(datasourceName)->firstRowIsHeader()); ui->cbUseFirstRowAsHeader->setChecked(dataSources->csvByName(datasourceName)->firstRowIsHeader());
@ -217,59 +211,55 @@ void SQLEditDialog::setDataSources(LimeReport::DataSourceManager *dataSources, Q
} }
} }
void SQLEditDialog::setDefaultConnection(QString defaultConnection) void SQLEditDialog::setDefaultConnection(QString defaultConnection) {
{
m_defaultConnection = ConnectionDesc::connectionNameForUser(defaultConnection); m_defaultConnection = ConnectionDesc::connectionNameForUser(defaultConnection);
} }
void SQLEditDialog::slotDataSourceNameEditing() void SQLEditDialog::slotDataSourceNameEditing() {
{ if (m_dialogMode == AddMode) {
if (m_dialogMode==AddMode){ QPalette palette = ui->leDatasourceName->palette();
QPalette palette=ui->leDatasourceName->palette(); if (m_datasources->containsDatasource(ui->leDatasourceName->text())) {
if (m_datasources->containsDatasource(ui->leDatasourceName->text())){ palette.setColor(QPalette::Text, Qt::red);
palette.setColor(QPalette::Text,Qt::red);
ui->leDatasourceName->setPalette(palette); ui->leDatasourceName->setPalette(palette);
ui->lblInfo->setText(QString(tr("Datasource with name %1 already exist")).arg(ui->leDatasourceName->text())); ui->lblInfo->setText(
QString(tr("Datasource with name %1 already exist")).arg(ui->leDatasourceName->text()));
ui->lblInfo->setVisible(true); ui->lblInfo->setVisible(true);
} else { } else {
palette.setColor(QPalette::Text,QApplication::palette().text().color()); palette.setColor(QPalette::Text, QApplication::palette().text().color());
ui->leDatasourceName->setPalette(palette); ui->leDatasourceName->setPalette(palette);
ui->lblInfo->setVisible(false); ui->lblInfo->setVisible(false);
} }
} }
} }
void SQLEditDialog::on_cbSubdetail_clicked(bool checked) void SQLEditDialog::on_cbSubdetail_clicked(bool checked) {
{ if (checked) {
if (checked){ m_masterDatasources->setModel(new QStringListModel(m_datasources->dataSourceNames(), m_datasources));
m_masterDatasources->setModel(new QStringListModel(m_datasources->dataSourceNames(),m_datasources));
} }
ui->leMaster->setEnabled(checked); ui->leMaster->setEnabled(checked);
ui->rbProxy->setEnabled(checked); ui->rbProxy->setEnabled(checked);
ui->rbSubQuery->setEnabled(checked); ui->rbSubQuery->setEnabled(checked);
if ((checked)&&(ui->rbProxy->isChecked())) initProxyMode(); if ((checked) && (ui->rbProxy->isChecked()))
if ((checked)&&(ui->rbSubQuery->isChecked())) initSubQueryMode(); initProxyMode();
if (!checked) initQueryMode(); if ((checked) && (ui->rbSubQuery->isChecked()))
initSubQueryMode();
if (!checked)
initQueryMode();
} }
void SQLEditDialog::on_rbProxy_clicked(bool checked) void SQLEditDialog::on_rbProxy_clicked(bool checked) {
{ if (checked)
if (checked) initProxyMode(); initProxyMode();
} }
void SQLEditDialog::on_rbSubQuery_clicked(bool checked) void SQLEditDialog::on_rbSubQuery_clicked(bool checked) {
{ if (checked)
if (checked) initSubQueryMode(); initSubQueryMode();
} }
void SQLEditDialog::on_pbAddField_clicked() void SQLEditDialog::on_pbAddField_clicked() { ui->fieldsMap->setRowCount(ui->fieldsMap->rowCount() + 1); }
{
ui->fieldsMap->setRowCount(ui->fieldsMap->rowCount()+1);
}
void SQLEditDialog::initQueryMode() {
void SQLEditDialog::initQueryMode()
{
ui->gbSQL->setVisible(true); ui->gbSQL->setVisible(true);
ui->gbFieldsMap->setVisible(false); ui->gbFieldsMap->setVisible(false);
ui->pnlChildDatasource->setVisible(false); ui->pnlChildDatasource->setVisible(false);
@ -278,12 +268,11 @@ void SQLEditDialog::initQueryMode()
ui->cbSubdetail->setChecked(false); ui->cbSubdetail->setChecked(false);
ui->leMaster->setVisible(false); ui->leMaster->setVisible(false);
ui->lbMaster->setVisible(false); ui->lbMaster->setVisible(false);
//ui->tabWidget->removeTab(1); // ui->tabWidget->removeTab(1);
ui->tabWidget->addTab(ui->csvTab, tr("CSV")); ui->tabWidget->addTab(ui->csvTab, tr("CSV"));
} }
void SQLEditDialog::initSubQueryMode() void SQLEditDialog::initSubQueryMode() {
{
ui->gbSQL->setVisible(true); ui->gbSQL->setVisible(true);
ui->gbFieldsMap->setVisible(false); ui->gbFieldsMap->setVisible(false);
ui->pnlChildDatasource->setVisible(false); ui->pnlChildDatasource->setVisible(false);
@ -297,8 +286,7 @@ void SQLEditDialog::initSubQueryMode()
ui->tabWidget->removeTab(1); ui->tabWidget->removeTab(1);
} }
void SQLEditDialog::initProxyMode() void SQLEditDialog::initProxyMode() {
{
ui->gbSQL->setVisible(false); ui->gbSQL->setVisible(false);
ui->gbFieldsMap->setVisible(true); ui->gbFieldsMap->setVisible(true);
ui->pnlChildDatasource->setVisible(true); ui->pnlChildDatasource->setVisible(true);
@ -313,23 +301,17 @@ void SQLEditDialog::initProxyMode()
ui->tabWidget->removeTab(1); ui->tabWidget->removeTab(1);
} }
void SQLEditDialog::initCSVMode() void SQLEditDialog::initCSVMode() { ui->tabWidget->setCurrentWidget(ui->csvTab); }
{
ui->tabWidget->setCurrentWidget(ui->csvTab);
}
void SQLEditDialog::slotPreviewData() void SQLEditDialog::slotPreviewData() {
{ if (ui->cbbConnection->currentText().isEmpty()) {
if (ui->cbbConnection->currentText().isEmpty()){ QMessageBox::critical(this, tr("Attention"), tr("Connection is not specified"));
QMessageBox::critical(this,tr("Attention"),tr("Connection is not specified"));
return; return;
} }
m_previewModel = m_datasources->previewSQL( m_previewModel =
ConnectionDesc::connectionNameForReport(ui->cbbConnection->currentText()), m_datasources->previewSQL(ConnectionDesc::connectionNameForReport(ui->cbbConnection->currentText()),
ui->sqlText->toPlainText(), ui->sqlText->toPlainText(), ui->leMaster->text());
ui->leMaster->text() if (m_previewModel) {
);
if (m_previewModel){
ui->tvPreview->setModel(m_previewModel.data()); ui->tvPreview->setModel(m_previewModel.data());
ui->gbDataPreview->setVisible(true); ui->gbDataPreview->setVisible(true);
ui->pbPreview->setText(tr("Refresh")); ui->pbPreview->setText(tr("Refresh"));
@ -337,49 +319,37 @@ void SQLEditDialog::slotPreviewData()
} else { } else {
if (ui->gbDataPreview->isVisible()) if (ui->gbDataPreview->isVisible())
hidePreview(); hidePreview();
QMessageBox::critical(this,tr("Attention"),m_datasources->lastError()); QMessageBox::critical(this, tr("Attention"), m_datasources->lastError());
} }
} }
void SQLEditDialog::slotHidePreview() void SQLEditDialog::slotHidePreview() { hidePreview(); }
{
hidePreview();
}
void SQLEditDialog::writeSetting() void SQLEditDialog::writeSetting() {
{ if (settings() != 0) {
if (settings()!=0){
settings()->beginGroup("SQLEditor"); settings()->beginGroup("SQLEditor");
settings()->setValue("Geometry",saveGeometry()); settings()->setValue("Geometry", saveGeometry());
settings()->endGroup(); settings()->endGroup();
} }
} }
void SQLEditDialog::readSettings() void SQLEditDialog::readSettings() {
{ if (settings() == 0)
if (settings()==0) return; return;
settings()->beginGroup("SQLEditor"); settings()->beginGroup("SQLEditor");
QVariant v = settings()->value("Geometry"); QVariant v = settings()->value("Geometry");
if (v.isValid()){ if (v.isValid()) {
restoreGeometry(v.toByteArray()); restoreGeometry(v.toByteArray());
} }
settings()->endGroup(); settings()->endGroup();
} }
void SQLEditDialog::hidePreview() void SQLEditDialog::hidePreview() {
{
ui->gbDataPreview->setVisible(false); ui->gbDataPreview->setVisible(false);
ui->pbPreview->setText(tr("Preview")); ui->pbPreview->setText(tr("Preview"));
ui->pbHidePreview->setVisible(false); ui->pbHidePreview->setVisible(false);
} }
void SQLEditDialog::on_pbDelField_clicked() void SQLEditDialog::on_pbDelField_clicked() { ui->fieldsMap->removeRow(ui->fieldsMap->currentRow()); }
{
ui->fieldsMap->removeRow(ui->fieldsMap->currentRow());
}
} // namespace LimeReport } // namespace LimeReport

View File

@ -30,6 +30,7 @@ SOURCES += \
$$REPORT_PATH/objectinspector/propertyItems/lrcontentpropitem.cpp \ $$REPORT_PATH/objectinspector/propertyItems/lrcontentpropitem.cpp \
$$REPORT_PATH/objectinspector/propertyItems/lrmarginpropitem.cpp \ $$REPORT_PATH/objectinspector/propertyItems/lrmarginpropitem.cpp \
$$REPORT_PATH/objectinspector/propertyItems/lrseriespropitem.cpp \ $$REPORT_PATH/objectinspector/propertyItems/lrseriespropitem.cpp \
$$REPORT_PATH/objectinspector/propertyItems/lraxispropitem.cpp \
$$REPORT_PATH/objectinspector/editors/lrtextitempropertyeditor.cpp \ $$REPORT_PATH/objectinspector/editors/lrtextitempropertyeditor.cpp \
$$REPORT_PATH/objectinspector/editors/lrcomboboxeditor.cpp \ $$REPORT_PATH/objectinspector/editors/lrcomboboxeditor.cpp \
$$REPORT_PATH/objectinspector/editors/lrcheckboxeditor.cpp \ $$REPORT_PATH/objectinspector/editors/lrcheckboxeditor.cpp \
@ -80,6 +81,7 @@ HEADERS += \
$$REPORT_PATH/objectinspector/propertyItems/lrcolorpropitem.h \ $$REPORT_PATH/objectinspector/propertyItems/lrcolorpropitem.h \
$$REPORT_PATH/objectinspector/propertyItems/lrmarginpropitem.h \ $$REPORT_PATH/objectinspector/propertyItems/lrmarginpropitem.h \
$$REPORT_PATH/objectinspector/propertyItems/lrseriespropitem.h \ $$REPORT_PATH/objectinspector/propertyItems/lrseriespropitem.h \
$$REPORT_PATH/objectinspector/propertyItems/lraxispropitem.h \
$$REPORT_PATH/objectinspector/editors/lrtextitempropertyeditor.h \ $$REPORT_PATH/objectinspector/editors/lrtextitempropertyeditor.h \
$$REPORT_PATH/objectinspector/editors/lrcomboboxeditor.h \ $$REPORT_PATH/objectinspector/editors/lrcomboboxeditor.h \
$$REPORT_PATH/objectinspector/editors/lrcheckboxeditor.h \ $$REPORT_PATH/objectinspector/editors/lrcheckboxeditor.h \

View File

@ -70,7 +70,12 @@ void LinesChart::drawDesignMode(QPainter* painter, qreal hStep, qreal vStep, qre
qreal LinesChart::calculatePos(const AxisData &data, qreal value, qreal rectSize) const qreal LinesChart::calculatePos(const AxisData &data, qreal value, qreal rectSize) const
{ {
return (data.rangeMax() - value) / data.delta() * rectSize; if (data.type() == AxisData::XAxis || (data.reverseDirection() && data.rangeMin() >= 0)) {
// Not flipping for minimum less than 0 because lower number is at the bottom.
return (1 - (data.rangeMax() - value) / data.delta()) * rectSize;
} else {
return (data.rangeMax() - value) / data.delta() * rectSize;
}
} }
void LinesChart::paintSeries(QPainter *painter, SeriesItem *series, QRectF barsRect) void LinesChart::paintSeries(QPainter *painter, SeriesItem *series, QRectF barsRect)

View File

@ -143,7 +143,7 @@ void PieChart::paintChartLegend(QPainter *painter, QRectF legendRect)
} }
} }
QSizeF PieChart::calcChartLegendSize(const QFont &font) QSizeF PieChart::calcChartLegendSize(const QFont &font, qreal)
{ {
QFontMetrics fm(font); QFontMetrics fm(font);

View File

@ -8,7 +8,7 @@ namespace LimeReport{
class PieChart : public AbstractChart{ class PieChart : public AbstractChart{
public: public:
PieChart(ChartItem* chartItem):AbstractChart(chartItem){} PieChart(ChartItem* chartItem):AbstractChart(chartItem){}
QSizeF calcChartLegendSize(const QFont &font); QSizeF calcChartLegendSize(const QFont &font, qreal maxWidth = 0);
void paintChart(QPainter *painter, QRectF chartRect); void paintChart(QPainter *painter, QRectF chartRect);
void paintChartLegend(QPainter *painter, QRectF legendRect); void paintChartLegend(QPainter *painter, QRectF legendRect);
protected: protected:

View File

@ -71,8 +71,6 @@ void VerticalBarChart::paintVerticalBars(QPainter *painter, QRectF barsRect)
qreal hStep = (barsRect.width() / valuesCount()) / (barSeriesCount == 0 ? 1 : barSeriesCount); qreal hStep = (barsRect.width() / valuesCount()) / (barSeriesCount == 0 ? 1 : barSeriesCount);
qreal topShift = (delta - (maxValue() - minValue())) * vStep + barsRect.top(); qreal topShift = (delta - (maxValue() - minValue())) * vStep + barsRect.top();
qDebug() << "vStep" << vStep << "hStep" << hStep;
if (!m_chartItem->series().isEmpty() && (m_chartItem->itemMode() != DesignMode)){ if (!m_chartItem->series().isEmpty() && (m_chartItem->itemMode() != DesignMode)){
int curSeries = 0; int curSeries = 0;
foreach (SeriesItem* series, m_chartItem->series()) { foreach (SeriesItem* series, m_chartItem->series()) {

View File

@ -48,7 +48,6 @@ void AbstractLayout::setLayoutType(const LayoutType& layoutType)
void AbstractLayout::addChild(BaseDesignIntf* item, bool updateSize) void AbstractLayout::addChild(BaseDesignIntf* item, bool updateSize)
{ {
placeItemInLayout(item); placeItemInLayout(item);
m_children.append(item); m_children.append(item);
@ -57,22 +56,7 @@ void AbstractLayout::addChild(BaseDesignIntf* item, bool updateSize)
item->setFixedPos(true); item->setFixedPos(true);
item->setPossibleResizeDirectionFlags(ResizeRight | ResizeBottom); item->setPossibleResizeDirectionFlags(ResizeRight | ResizeBottom);
connect( connectToLayout(item);
item, SIGNAL(destroyed(QObject*)),
this, SLOT(slotOnChildDestroy(QObject*))
);
connect(
item,SIGNAL(geometryChanged(QObject*,QRectF,QRectF)),
this,SLOT(slotOnChildGeometryChanged(QObject*,QRectF,QRectF))
);
connect(
item, SIGNAL(itemVisibleHasChanged(BaseDesignIntf*)),
this, SLOT(slotOnChildVisibleHasChanged(BaseDesignIntf*))
);
connect(
item, SIGNAL(itemSelectedHasBeenChanged(BaseDesignIntf*,bool)),
this, SLOT(slotOnChildSelectionHasChanged(BaseDesignIntf*,bool))
);
if (updateSize){ if (updateSize){
relocateChildren(); relocateChildren();
@ -80,19 +64,23 @@ void AbstractLayout::addChild(BaseDesignIntf* item, bool updateSize)
} }
} }
void AbstractLayout::removeChild(BaseDesignIntf *item)
{
if (!item) {
return;
}
m_children.removeAll(item);
disconnectFromLayout(item);
}
void AbstractLayout::restoreChild(BaseDesignIntf* item) void AbstractLayout::restoreChild(BaseDesignIntf* item)
{ {
if (m_children.contains(item)) return; if (m_children.contains(item)) return;
m_isRelocating=true; m_isRelocating=true;
insertItemInLayout(item); insertItemInLayout(item);
connect(item,SIGNAL(destroyed(QObject*)),this,SLOT(slotOnChildDestroy(QObject*))); connectToLayout(item);
connect(item,SIGNAL(geometryChanged(QObject*,QRectF,QRectF)),
this,SLOT(slotOnChildGeometryChanged(QObject*,QRectF,QRectF)));
connect(item, SIGNAL(itemAlignChanged(BaseDesignIntf*,ItemAlign,ItemAlign)),
this, SLOT(slotOnChildItemAlignChanged(BaseDesignIntf*,ItemAlign,ItemAlign)));
item->setFixedPos(true); item->setFixedPos(true);
item->setPossibleResizeDirectionFlags(ResizeRight | ResizeBottom); item->setPossibleResizeDirectionFlags(ResizeRight | ResizeBottom);
@ -267,6 +255,54 @@ void AbstractLayout::rebuildChildrenIfNeeded(){
} }
} }
void AbstractLayout::connectToLayout(BaseDesignIntf *item)
{
connect(
item, SIGNAL(destroyed(QObject*)),
this, SLOT(slotOnChildDestroy(QObject*))
);
connect(
item,SIGNAL(geometryChanged(QObject*,QRectF,QRectF)),
this,SLOT(slotOnChildGeometryChanged(QObject*,QRectF,QRectF))
);
connect(
item, SIGNAL(itemVisibleHasChanged(BaseDesignIntf*)),
this, SLOT(slotOnChildVisibleHasChanged(BaseDesignIntf*))
);
connect(
item, SIGNAL(itemSelectedHasBeenChanged(BaseDesignIntf*,bool)),
this, SLOT(slotOnChildSelectionHasChanged(BaseDesignIntf*,bool))
);
connect(
item, SIGNAL(itemAlignChanged(BaseDesignIntf*, const ItemAlign&, const ItemAlign&)),
this, SLOT(slotOnChildItemAlignChanged(BaseDesignIntf*,const ItemAlign&,const ItemAlign&))
);
}
void AbstractLayout::disconnectFromLayout(BaseDesignIntf *item)
{
disconnect(
item, SIGNAL(destroyed(QObject*)),
this, SLOT(slotOnChildDestroy(QObject*))
);
disconnect(
item,SIGNAL(geometryChanged(QObject*,QRectF,QRectF)),
this,SLOT(slotOnChildGeometryChanged(QObject*,QRectF,QRectF))
);
disconnect(
item, SIGNAL(itemVisibleHasChanged(BaseDesignIntf*)),
this, SLOT(slotOnChildVisibleHasChanged(BaseDesignIntf*))
);
disconnect(
item, SIGNAL(itemSelectedHasBeenChanged(BaseDesignIntf*,bool)),
this, SLOT(slotOnChildSelectionHasChanged(BaseDesignIntf*,bool))
);
disconnect(
item, SIGNAL(itemAlignChanged(BaseDesignIntf*, const ItemAlign&, const ItemAlign&)),
this, SLOT(slotOnChildItemAlignChanged(BaseDesignIntf*,const ItemAlign&,const ItemAlign&))
);
}
BaseDesignIntf *AbstractLayout::findNext(BaseDesignIntf *item) BaseDesignIntf *AbstractLayout::findNext(BaseDesignIntf *item)
{ {
rebuildChildrenIfNeeded(); rebuildChildrenIfNeeded();
@ -288,7 +324,7 @@ BaseDesignIntf *AbstractLayout::findPrior(BaseDesignIntf *item)
void AbstractLayout::slotOnChildDestroy(QObject* child) void AbstractLayout::slotOnChildDestroy(QObject* child)
{ {
m_children.removeAll(static_cast<BaseDesignIntf*>(child)); m_children.removeAll(static_cast<BaseDesignIntf*>(child));
if (m_children.count()<2){ if (m_children.count() < 2 && !static_cast<LayoutDesignIntf*>(child)){
beforeDelete(); beforeDelete();
} else { } else {
relocateChildren(); relocateChildren();
@ -316,7 +352,7 @@ void AbstractLayout::slotOnChildGeometryChanged(QObject* item, QRectF newGeometr
} }
} }
void AbstractLayout::slotOnChildItemAlignChanged(BaseDesignIntf* item, const BaseDesignIntf::ItemAlign&, const BaseDesignIntf::ItemAlign&) void AbstractLayout::slotOnChildItemAlignChanged(BaseDesignIntf* item, const ItemAlign&, const ItemAlign&)
{ {
item->setPossibleResizeDirectionFlags(ResizeBottom | ResizeRight); item->setPossibleResizeDirectionFlags(ResizeBottom | ResizeRight);
} }

View File

@ -28,6 +28,7 @@ public:
void setLayoutType(const LayoutType& layoutType); void setLayoutType(const LayoutType& layoutType);
void addChild(BaseDesignIntf *item,bool updateSize=true); void addChild(BaseDesignIntf *item,bool updateSize=true);
void removeChild(BaseDesignIntf *item);
void restoreChild(BaseDesignIntf *item); void restoreChild(BaseDesignIntf *item);
bool isEmpty() const; bool isEmpty() const;
void paintChild(BaseDesignIntf* child, QPointF parentPos, QPainter* painter); void paintChild(BaseDesignIntf* child, QPointF parentPos, QPainter* painter);
@ -52,6 +53,8 @@ protected:
QVariant itemChange(GraphicsItemChange change, const QVariant &value); QVariant itemChange(GraphicsItemChange change, const QVariant &value);
void updateItemSize(DataSourceManager* dataManager, RenderPass pass, int maxHeight); void updateItemSize(DataSourceManager* dataManager, RenderPass pass, int maxHeight);
void rebuildChildrenIfNeeded(); void rebuildChildrenIfNeeded();
void connectToLayout(BaseDesignIntf* item);
void disconnectFromLayout(BaseDesignIntf* item);
private: private:
virtual void sortChildren() = 0; virtual void sortChildren() = 0;
virtual void divideSpace() = 0; virtual void divideSpace() = 0;

View File

@ -0,0 +1,142 @@
#include "lrchartaxiseditor.h"
#include "ui_lrchartaxiseditor.h"
#include "lraxisdata.h"
#include "lrbasedesignintf.h"
ChartAxisEditor::ChartAxisEditor(LimeReport::ChartItem *item, LimeReport::PageDesignIntf *page, bool isXAxis, QSettings *settings, QWidget *parent):
QWidget(parent), ui(new Ui::ChartAxisEditor), m_chartItem(item), m_page(page),
m_settings(settings), m_isXAxis(isXAxis)
{
ui->setupUi(this);
readSetting();
init();
}
ChartAxisEditor::~ChartAxisEditor()
{
#if defined(Q_OS_WIN) || defined(Q_OS_MAC)
writeSetting();
#endif
delete ui;
}
QSettings* ChartAxisEditor::settings()
{
if (m_settings){
return m_settings;
}
m_settings = new QSettings("LimeReport",QCoreApplication::applicationName());
return m_settings;
}
void ChartAxisEditor::readSetting()
{
if (settings() == 0) return;
settings()->beginGroup("ChartAxisEditor");
QVariant v = settings()->value("Geometry");
if (v.isValid()) {
restoreGeometry(v.toByteArray());
}
settings()->endGroup();
}
void ChartAxisEditor::writeSetting()
{
if (settings() == 0) {
return;
}
settings()->beginGroup("ChartAxisEditor");
settings()->setValue("Geometry",saveGeometry());
settings()->endGroup();
}
void ChartAxisEditor::init()
{
ui->gbAxis->setTitle(m_isXAxis ? QObject::tr("X Axis") : QObject::tr("Y Axis"));
ui->direction_checkbox->setVisible(!m_isXAxis);
LimeReport::AxisData *axisData = m_isXAxis ? m_chartItem->xAxisData() : m_chartItem->yAxisData();
ui->minimumSpinBox->setValue(axisData->manualMinimum());
ui->maximumSpinBox->setValue(axisData->manualMaximum());
ui->stepSpinBox->setValue(axisData->manualStep());
ui->minimumCheckBox->setChecked(axisData->isMinimumAutomatic());
ui->maximumCheckBox->setChecked(axisData->isMaximumAutomatic());
ui->stepCheckBox->setChecked(axisData->isStepAutomatic());
ui->direction_checkbox->setChecked(axisData->reverseDirection());
const bool isScaleCalcEnabled = axisData->calculateAxisScale();
ui->enableScaleCalculation_checkbox->setChecked(isScaleCalcEnabled);
on_enableScaleCalculation_checkbox_stateChanged(isScaleCalcEnabled);
}
void ChartAxisEditor::on_minimumCheckBox_stateChanged(int arg1)
{
const bool isAutomatic = (bool)arg1;
ui->minimumSpinBox->setEnabled(!isAutomatic);
}
void ChartAxisEditor::on_maximumCheckBox_stateChanged(int arg1)
{
const bool isAutomatic = (bool)arg1;
ui->maximumSpinBox->setEnabled(!isAutomatic);
}
void ChartAxisEditor::on_stepCheckBox_stateChanged(int arg1)
{
const bool isAutomatic = (bool)arg1;
ui->stepSpinBox->setEnabled(!isAutomatic);
}
void ChartAxisEditor::on_pushButtonOk_clicked()
{
LimeReport::AxisData *axisData = m_isXAxis ? m_chartItem->xAxisData() : m_chartItem->yAxisData();
if (!m_isXAxis) {
axisData->setReverseDirection(ui->direction_checkbox->isChecked());
}
axisData->setIsStepAutomatic(ui->stepCheckBox->isChecked());
axisData->setManualStep(ui->stepSpinBox->value());
axisData->setIsMinimumAutomatic(ui->minimumCheckBox->isChecked());
axisData->setManualMinimum(ui->minimumSpinBox->value());
axisData->setIsMaximumAutomatic(ui->maximumCheckBox->isChecked());
axisData->setManualMaximum(ui->maximumSpinBox->value());
axisData->setCalculateAxisScale(ui->enableScaleCalculation_checkbox->isChecked());
if (m_chartItem->itemMode() == LimeReport::DesignMode) {
axisData->updateForDesignMode();
} else {
axisData->update();
}
m_chartItem->update();
close();
}
void ChartAxisEditor::on_enableScaleCalculation_checkbox_stateChanged(int arg1)
{
const bool isEnabled = (bool)arg1;
ui->minimumCheckBox->setEnabled(isEnabled);
ui->maximumCheckBox->setEnabled(isEnabled);
ui->stepCheckBox->setEnabled(isEnabled);
ui->minimumSpinBox->setEnabled(!ui->minimumCheckBox->isChecked() && isEnabled);
ui->maximumSpinBox->setEnabled(!ui->maximumCheckBox->isChecked() && isEnabled);
ui->stepSpinBox->setEnabled(!ui->stepCheckBox->isChecked() && isEnabled);
ui->minimumCheckBox->setEnabled(isEnabled);
ui->maximumCheckBox->setEnabled(isEnabled);
ui->stepCheckBox->setEnabled(isEnabled);
}
void ChartAxisEditor::on_cancelButton_clicked()
{
close();
}

View File

@ -0,0 +1,41 @@
#ifndef CHARTAXISEDITOR_H
#define CHARTAXISEDITOR_H
#include <QWidget>
#include "lrchartitem.h"
namespace Ui {
class ChartAxisEditor;
}
class ChartAxisEditor : public QWidget
{
Q_OBJECT
public:
ChartAxisEditor(LimeReport::ChartItem* item, LimeReport::PageDesignIntf* page, bool isXAxis,
QSettings* settings=0, QWidget *parent = 0);
~ChartAxisEditor();
QSettings *settings();
private slots:
void on_minimumCheckBox_stateChanged(int arg1);
void on_maximumCheckBox_stateChanged(int arg1);
void on_stepCheckBox_stateChanged(int arg1);
void on_pushButtonOk_clicked();
void on_enableScaleCalculation_checkbox_stateChanged(int arg1);
void on_cancelButton_clicked();
private:
void readSetting();
void writeSetting();
void init();
Ui::ChartAxisEditor *ui;
LimeReport::ChartItem* m_chartItem;
LimeReport::PageDesignIntf* m_page;
QSettings* m_settings;
bool m_isXAxis;
};
#endif // CHARTAXISEDITOR_H

View File

@ -0,0 +1,212 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ChartAxisEditor</class>
<widget class="QWidget" name="ChartAxisEditor">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>380</width>
<height>268</height>
</rect>
</property>
<property name="windowTitle">
<string>Axis editor</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QGroupBox" name="gbAxis">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Axis</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QCheckBox" name="direction_checkbox">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Reverse direction</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="enableScaleCalculation_checkbox">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Enable scale calculation</string>
</property>
</widget>
</item>
<item>
<layout class="QGridLayout" name="gridLayout">
<property name="sizeConstraint">
<enum>QLayout::SetFixedSize</enum>
</property>
<item row="2" column="0">
<widget class="QLabel" name="stepLabel">
<property name="text">
<string>Step</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="maximumLabel">
<property name="text">
<string>Maximum</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QDoubleSpinBox" name="minimumSpinBox">
<property name="showGroupSeparator" stdset="0">
<bool>false</bool>
</property>
<property name="minimum">
<double>-99999999.000000000000000</double>
</property>
<property name="maximum">
<double>99999999.000000000000000</double>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="minimumLabel">
<property name="text">
<string>Minimum</string>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QCheckBox" name="stepCheckBox">
<property name="text">
<string>Automatic</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QCheckBox" name="minimumCheckBox">
<property name="text">
<string>Automatic</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QCheckBox" name="maximumCheckBox">
<property name="text">
<string>Automatic</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QDoubleSpinBox" name="stepSpinBox">
<property name="minimum">
<double>0.000000000000000</double>
</property>
<property name="maximum">
<double>9999999.990000000223517</double>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QDoubleSpinBox" name="maximumSpinBox">
<property name="minimum">
<double>-9999999.000000000000000</double>
</property>
<property name="maximum">
<double>99999999.000000000000000</double>
</property>
</widget>
</item>
<item row="1" column="4">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="cancelButton">
<property name="text">
<string>Cancel</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButtonOk">
<property name="text">
<string>Ok</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
<slots>
<slot>slotAddSeries()</slot>
<slot>slotDeleteSeries()</slot>
</slots>
</ui>

View File

@ -8,6 +8,7 @@
#include "lrpagedesignintf.h" #include "lrpagedesignintf.h"
#include "lrreportengine_p.h" #include "lrreportengine_p.h"
#include "lrdatadesignintf.h" #include "lrdatadesignintf.h"
#include "lrchartaxiseditor.h"
#include "charts/lrpiechart.h" #include "charts/lrpiechart.h"
#include "charts/lrverticalbarchart.h" #include "charts/lrverticalbarchart.h"
@ -141,13 +142,18 @@ void SeriesItem::setPreferredType(const SeriesItemPreferredType& type)
ChartItem::ChartItem(QObject *owner, QGraphicsItem *parent) ChartItem::ChartItem(QObject *owner, QGraphicsItem *parent)
: ItemDesignIntf(xmlTag, owner, parent), m_legendBorder(true), : ItemDesignIntf(xmlTag, owner, parent), m_legendBorder(true),
m_legendAlign(LegendAlignCenter), m_titleAlign(TitleAlignCenter), m_legendAlign(LegendAlignRightCenter), m_titleAlign(TitleAlignCenter),
m_chartType(Pie), m_labelsField(""), m_isEmpty(true), m_chartType(Pie), m_labelsField(""), m_isEmpty(true),
m_showLegend(true), m_drawPoints(true), m_seriesLineWidth(4), m_showLegend(true), m_drawPoints(true), m_seriesLineWidth(4),
m_horizontalAxisOnTop(false), m_gridChartLines(AllLines) m_horizontalAxisOnTop(false), m_gridChartLines(AllLines),
m_legendStyle(LegendPoints)
{ {
m_xAxisData = new AxisData(AxisData::XAxis, this);
m_xAxisData->setReverseDirection(true);
m_yAxisData = new AxisData(AxisData::YAxis, this);
m_labels<<"First"<<"Second"<<"Thrid"; m_labels<<"First"<<"Second"<<"Thrid";
m_chart = new PieChart(this); m_chart = new PieChart(this);
m_chart->setTitleFont(font());
} }
ChartItem::~ChartItem() ChartItem::~ChartItem()
@ -182,20 +188,36 @@ void ChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
painter->setRenderHint(QPainter::Antialiasing,true); painter->setRenderHint(QPainter::Antialiasing,true);
painter->setRenderHint(QPainter::TextAntialiasing,true); painter->setRenderHint(QPainter::TextAntialiasing,true);
qreal borderMargin = (rect().height()*0.01>10)?(10):(rect().height()*0.01); qreal borderMargin = (rect().height()*0.01>10)?(10):(rect().height()*0.01);
qreal maxTitleHeight = rect().height()*0.2; qreal maxTitleHeight = rect().height()*0.5;
QFont tmpFont = painter->font(); QFont tmpFont = painter->font();
qreal titleOffset = !m_title.isEmpty()?(((painter->fontMetrics().height()+borderMargin*2)<maxTitleHeight)? qreal titleOffset = 0;
(painter->fontMetrics().height()+borderMargin*2): if (!m_title.isEmpty()) {
(maxTitleHeight)):0; QFontMetrics fm(titleFont());
const qreal titleHeight = fm.boundingRect(rect().toRect(), Qt::TextWordWrap,chartTitle()).height() + borderMargin * 2;
titleOffset = std::min(titleHeight, maxTitleHeight);
}
QRectF titleRect = QRectF(borderMargin,borderMargin,rect().width()-borderMargin*2,titleOffset); const QRectF titleRect = QRectF(borderMargin,borderMargin,rect().width()-borderMargin*2,titleOffset);
QRectF legendRect = QRectF(0,0,0,0); QRectF legendRect = QRectF(0, 0, 0, 0);
if (m_showLegend) QRectF diagramRect = rect().adjusted(borderMargin, titleOffset + borderMargin,
-(borderMargin * 2), -borderMargin);
if (m_showLegend) {
legendRect = m_chart->calcChartLegendRect(painter->font(), rect(), false, borderMargin, titleOffset); legendRect = m_chart->calcChartLegendRect(painter->font(), rect(), false, borderMargin, titleOffset);
QRectF diagramRect = rect().adjusted(borderMargin,titleOffset+borderMargin, switch(legendAlign()) {
-(legendRect.width()+borderMargin*2),-borderMargin); case LegendAlignRightTop:
case LegendAlignRightBottom:
case LegendAlignRightCenter:
diagramRect.adjust(0, 0, -legendRect.width(), 0);
break;
case LegendAlignBottomLeft:
case LegendAlignBottomCenter:
case LegendAlignBottomRight:
diagramRect.adjust(0, 0, 0, -(legendRect.height() + borderMargin * 2));
break;
}
}
paintChartTitle(painter, titleRect); paintChartTitle(painter, titleRect);
if (m_showLegend) if (m_showLegend)
@ -206,6 +228,47 @@ void ChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
ItemDesignIntf::paint(painter,option,widget); ItemDesignIntf::paint(painter,option,widget);
} }
QObject *ChartItem::xAxisSettings()
{
return m_xAxisData;
}
void ChartItem::setYAxisSettings(QObject *axis)
{
AxisData *data = dynamic_cast<AxisData*>(axis);
if (data) {
m_yAxisData->copy(data);
}
}
QObject *ChartItem::yAxisSettings()
{
return m_yAxisData;
}
void ChartItem::setXAxisSettings(QObject *axis)
{
AxisData *data = static_cast<AxisData*>(axis);
if (data) {
m_xAxisData->copy(data);
}
}
AxisData *ChartItem::xAxisData()
{
return m_xAxisData;
}
AxisData *ChartItem::yAxisData()
{
return m_yAxisData;
}
void ChartItem::showAxisEditorDialog(bool isXAxis)
{
showDialog(new ChartAxisEditor(this, page(), isXAxis, settings()));
}
BaseDesignIntf *ChartItem::createSameTypeItem(QObject *owner, QGraphicsItem *parent) BaseDesignIntf *ChartItem::createSameTypeItem(QObject *owner, QGraphicsItem *parent)
{ {
ChartItem* result = new ChartItem(owner,parent); ChartItem* result = new ChartItem(owner,parent);
@ -271,10 +334,7 @@ void ChartItem::fillLabels(IDataSource *dataSource)
QWidget *ChartItem::defaultEditor() QWidget *ChartItem::defaultEditor()
{ {
QSettings* l_settings = (page()->settings() != 0) ? QWidget* editor = new ChartItemEditor(this, page(), settings());
page()->settings() :
(page()->reportEditor()!=0) ? page()->reportEditor()->settings() : 0;
QWidget* editor = new ChartItemEditor(this, page(), l_settings);
editor->setAttribute(Qt::WA_DeleteOnClose); editor->setAttribute(Qt::WA_DeleteOnClose);
return editor; return editor;
} }
@ -284,6 +344,18 @@ bool ChartItem::isNeedUpdateSize(RenderPass pass) const
return pass == FirstPass && m_isEmpty; return pass == FirstPass && m_isEmpty;
} }
QSettings *ChartItem::settings()
{
PageDesignIntf *page = this->page();
if (page->settings()) {
return page->settings();
}
if (page->reportEditor()) {
return page->reportEditor()->settings();
}
return 0;
}
bool ChartItem::showLegend() const bool ChartItem::showLegend() const
{ {
return m_showLegend; return m_showLegend;
@ -329,6 +401,7 @@ void ChartItem::setChartType(const ChartType &chartType)
if (m_chartType != chartType){ if (m_chartType != chartType){
ChartType oldValue = m_chartType; ChartType oldValue = m_chartType;
m_chartType = chartType; m_chartType = chartType;
QFont oldTitleFont = m_chart->titleFont();
delete m_chart; delete m_chart;
switch (m_chartType) { switch (m_chartType) {
case Pie: case Pie:
@ -347,6 +420,7 @@ void ChartItem::setChartType(const ChartType &chartType)
m_chart = new GridLinesChart(this); m_chart = new GridLinesChart(this);
break; break;
} }
m_chart->setTitleFont(oldTitleFont);
notify("chartType",oldValue,m_chartType); notify("chartType",oldValue,m_chartType);
update(); update();
} }
@ -365,13 +439,16 @@ void ChartItem::setDatasource(const QString &datasource)
void ChartItem::paintChartTitle(QPainter *painter, QRectF titleRect) void ChartItem::paintChartTitle(QPainter *painter, QRectF titleRect)
{ {
painter->save(); painter->save();
QFont tmpFont = painter->font(); QFont tmpFont = transformToSceneFont(titleFont());
QFontMetrics fm(tmpFont); QRect titleBoundingRect = QFontMetrics(tmpFont).boundingRect(rect().toRect(), Qt::TextWordWrap, chartTitle());
while ((fm.height()>titleRect.height() || fm.boundingRect(m_title).width()>titleRect.width())
&& tmpFont.pixelSize()>1) { while ((titleBoundingRect.height() > titleRect.height() || titleBoundingRect.width() > titleRect.width())
&& tmpFont.pixelSize() > 1)
{
tmpFont.setPixelSize(tmpFont.pixelSize()-1); tmpFont.setPixelSize(tmpFont.pixelSize()-1);
fm = QFontMetrics(tmpFont); titleBoundingRect = QFontMetrics(tmpFont).boundingRect(rect().toRect(), Qt::TextWordWrap, chartTitle());
} }
painter->setFont(tmpFont); painter->setFont(tmpFont);
Qt::AlignmentFlag align = Qt::AlignCenter; Qt::AlignmentFlag align = Qt::AlignCenter;
switch (m_titleAlign) { switch (m_titleAlign) {
@ -385,7 +462,7 @@ void ChartItem::paintChartTitle(QPainter *painter, QRectF titleRect)
align = Qt::AlignRight; align = Qt::AlignRight;
break; break;
} }
painter->drawText(titleRect, align, m_title); painter->drawText(titleRect, align | Qt::TextWordWrap, m_title);
painter->restore(); painter->restore();
} }
@ -405,6 +482,22 @@ void ChartItem::setLegendAlign(const LegendAlign &legendAlign)
} }
} }
ChartItem::LegendStyle ChartItem::legendStyle() const
{
return m_legendStyle;
}
void ChartItem::setLegendStyle(const LegendStyle &legendStyle)
{
if (m_legendStyle == legendStyle) {
return;
}
LegendStyle oldValue = m_legendStyle;
m_legendStyle = legendStyle;
notify("legendStyle", oldValue, m_legendStyle);
update();
}
bool ChartItem::drawLegendBorder() const bool ChartItem::drawLegendBorder() const
{ {
return m_legendBorder; return m_legendBorder;
@ -527,6 +620,33 @@ void ChartItem::setGridChartLines(GridChartLines flags)
notify("gridChartLines",QVariant(oldValue),QVariant(flags)); notify("gridChartLines",QVariant(oldValue),QVariant(flags));
} }
void ChartItem::setCharItemFont(QFont value)
{
if (font() == value) {
return;
}
QFont oldValue = font();
setFont(value);
if (!isLoading()) update();
notify("font",oldValue,value);
}
QFont ChartItem::titleFont() const
{
return m_chart->titleFont();
}
void ChartItem::setTitleFont(QFont value)
{
if (m_chart->titleFont() == value){
return;
}
QFont oldValue = value;
m_chart->setTitleFont(value);
if (!isLoading()) update();
notify("titleFont", oldValue, value);
}
AbstractChart::AbstractChart(ChartItem *chartItem) AbstractChart::AbstractChart(ChartItem *chartItem)
:m_chartItem(chartItem) :m_chartItem(chartItem)
{ {
@ -535,54 +655,110 @@ AbstractChart::AbstractChart(ChartItem *chartItem)
QRectF AbstractChart::calcChartLegendRect(const QFont &font, const QRectF &parentRect, bool takeAllRect, qreal borderMargin, qreal titleOffset) QRectF AbstractChart::calcChartLegendRect(const QFont &font, const QRectF &parentRect, bool takeAllRect, qreal borderMargin, qreal titleOffset)
{ {
QSizeF legendSize = calcChartLegendSize(font); const QSizeF legendSize = calcChartLegendSize(font, parentRect.width() * 0.9);
qreal legendTopMargin = 0; qreal legendTopMargin = 0;
qreal legendBottomMargin = 0; qreal legendBottomMargin = 0;
qreal legendLeftMargin = 0;
bool isVertical = true;
switch (m_chartItem->legendAlign()) { switch (m_chartItem->legendAlign()) {
case ChartItem::LegendAlignTop: case ChartItem::LegendAlignRightTop:
legendTopMargin = titleOffset+borderMargin; legendTopMargin = titleOffset + borderMargin;
legendBottomMargin = parentRect.height()-(legendSize.height()+titleOffset); legendBottomMargin = parentRect.height() - (legendSize.height() + titleOffset);
isVertical = true;
break; break;
case ChartItem::LegendAlignCenter: case ChartItem::LegendAlignRightCenter:
legendTopMargin = titleOffset+(parentRect.height()-titleOffset-legendSize.height())/2; legendTopMargin = titleOffset + (parentRect.height() - titleOffset - legendSize.height()) / 2;
legendBottomMargin = (parentRect.height()-titleOffset-legendSize.height())/2; legendBottomMargin = (parentRect.height() - titleOffset - legendSize.height()) / 2;
isVertical = true;
break; break;
case ChartItem::LegendAlignBottom: case ChartItem::LegendAlignRightBottom:
legendTopMargin = parentRect.height()-(legendSize.height()+titleOffset); legendTopMargin = parentRect.height() - (legendSize.height() + titleOffset);
legendBottomMargin = borderMargin; legendBottomMargin = borderMargin;
isVertical = true;
break;
case ChartItem::LegendAlignBottomLeft:
legendLeftMargin = QFontMetrics(font).height() / 2;
isVertical = false;
break;
case ChartItem::LegendAlignBottomCenter:
legendLeftMargin = (parentRect.width() - legendSize.width()) / 2;
isVertical = false;
break;
case ChartItem::LegendAlignBottomRight:
legendLeftMargin = parentRect.width() - legendSize.width() - QFontMetrics(font).height() / 2;
isVertical = false;
break; break;
} }
qreal rightOffset = !takeAllRect?((legendSize.width()>parentRect.width()/2-borderMargin)? if (isVertical) {
(parentRect.width()/2): qreal rightOffset = !takeAllRect ? ((legendSize.width() > parentRect.width() / 2 - borderMargin) ?
(parentRect.width()-legendSize.width())):0; (parentRect.width() / 2) :
(parentRect.width() - legendSize.width())) : 0;
return parentRect.adjusted(
rightOffset,
(legendSize.height()>(parentRect.height()-titleOffset))?(titleOffset):(legendTopMargin),
-borderMargin,
(legendSize.height()>(parentRect.height()-titleOffset))?(0):(-legendBottomMargin)
);
} else {
const qreal verticalOffset = borderMargin * 2;
return parentRect.adjusted(
legendLeftMargin,
(parentRect.height()) - (legendSize.height() + verticalOffset),
-(parentRect.width() - (legendSize.width() + legendLeftMargin)),
-verticalOffset
);
}
}
QRectF legendRect = parentRect.adjusted(
rightOffset,
(legendSize.height()>(parentRect.height()-titleOffset))?(titleOffset):(legendTopMargin),
-borderMargin,
(legendSize.height()>(parentRect.height()-titleOffset))?(0):(-legendBottomMargin)
);
return legendRect; QFont AbstractChart::titleFont()
{
return m_titleFont;
}
void AbstractChart::setTitleFont(const QFont &value)
{
m_titleFont = value;
} }
void AbstractChart::prepareLegendToPaint(QRectF &legendRect, QPainter *painter) void AbstractChart::prepareLegendToPaint(QRectF &legendRect, QPainter *painter)
{ {
QFont tmpFont = painter->font(); QFont tmpFont = painter->font();
QSizeF legendSize = calcChartLegendSize(tmpFont); switch(m_chartItem->legendAlign()) {
case ChartItem::LegendAlignBottomLeft:
if ((legendSize.height()>legendRect.height() || legendSize.width()>legendRect.width())){ case ChartItem::LegendAlignBottomCenter:
while ( (legendSize.height()>legendRect.height() || legendSize.width()>legendRect.width()) case ChartItem::LegendAlignBottomRight: {
&& tmpFont.pixelSize()>1) const qreal maxWidth = legendRect.width() * 0.95;
qreal legendWidth = std::accumulate(m_legendColumnWidths.cbegin(), m_legendColumnWidths.cend(), 0.0);
if (legendWidth < maxWidth) {
return;
}
while ( (legendWidth > maxWidth) && tmpFont.pixelSize() > 1) {
tmpFont.setPixelSize(tmpFont.pixelSize() - 1);
calcChartLegendSize(tmpFont, legendRect.width());
legendWidth = std::accumulate(m_legendColumnWidths.cbegin(), m_legendColumnWidths.cend(), 0.0);
}
painter->setFont(tmpFont);
break;
}
case ChartItem::LegendAlignRightTop:
case ChartItem::LegendAlignRightCenter:
case ChartItem::LegendAlignRightBottom:
QSizeF legendSize = calcChartLegendSize(tmpFont, legendRect.width());
if ((legendSize.height() <= legendRect.height() && legendSize.width() <= legendRect.width())) {
return;
}
while ((legendSize.height() > legendRect.height() || legendSize.width() > legendRect.width())
&& tmpFont.pixelSize() > 1)
{ {
tmpFont.setPixelSize(tmpFont.pixelSize()-1); tmpFont.setPixelSize(tmpFont.pixelSize() - 1);
painter->setFont(tmpFont); legendSize = calcChartLegendSize(tmpFont, legendRect.width());
legendSize = calcChartLegendSize(tmpFont);
} }
painter->setFont(tmpFont); painter->setFont(tmpFont);
legendRect = calcChartLegendRect(tmpFont, legendRect, true, 0, 0); legendRect = calcChartLegendRect(tmpFont, legendRect, true, 0, 0);
break;
} }
} }
@ -602,56 +778,58 @@ AbstractSeriesChart::AbstractSeriesChart(ChartItem *chartItem)
qreal AbstractSeriesChart::maxValue() qreal AbstractSeriesChart::maxValue()
{ {
return m_yAxisData.maxValue(); return m_chartItem->yAxisData()->maxValue();
} }
qreal AbstractSeriesChart::minValue() qreal AbstractSeriesChart::minValue()
{ {
return m_yAxisData.minValue(); return m_chartItem->yAxisData()->minValue();
} }
AxisData AbstractSeriesChart::yAxisData() AxisData &AbstractSeriesChart::xAxisData() const
{ {
return m_yAxisData; return *m_chartItem->xAxisData();
} }
AxisData AbstractSeriesChart::xAxisData() AxisData &AbstractSeriesChart::yAxisData() const
{ {
return m_xAxisData; return *m_chartItem->yAxisData();
} }
void AbstractSeriesChart::updateMinAndMaxValues() void AbstractSeriesChart::updateMinAndMaxValues()
{ {
qreal maxYValue = 0;
qreal minYValue = 0;
qreal maxXValue = 0;
qreal minXValue = 0;
if (m_chartItem->itemMode() == DesignMode) { if (m_chartItem->itemMode() == DesignMode) {
maxYValue = 40; m_chartItem->xAxisData()->updateForDesignMode();
maxXValue = 40; m_chartItem->yAxisData()->updateForDesignMode();
} else { return;
for (SeriesItem* series : m_chartItem->series()){ }
for (qreal value : series->data()->values()){
minYValue = std::min(minYValue, value); qreal maxYValue = 0;
maxYValue = std::max(maxYValue, value); qreal minYValue = std::numeric_limits<qreal>::max();
} qreal maxXValue = 0;
if (series->data()->xAxisValues().isEmpty()) { qreal minXValue = std::numeric_limits<qreal>::max();
// Grid plot starts from 0 on x axis so x range must be decresed by 1
const bool startingFromZero = m_chartItem->chartType() == ChartItem::GridLines; for (SeriesItem* series : m_chartItem->series()){
const qreal valuesCount = this->valuesCount() - (startingFromZero ? 1 : 0); for (qreal value : series->data()->values()){
minXValue = std::min(0.0, minXValue); minYValue = std::min(minYValue, value);
maxXValue = std::max(valuesCount, maxXValue); maxYValue = std::max(maxYValue, value);
} else { }
for (qreal value : series->data()->xAxisValues()){ if (series->data()->xAxisValues().isEmpty()) {
minXValue = std::min(value, minXValue); // Grid plot starts from 0 on x axis so x range must be decresed by 1
maxXValue = std::max(value, maxXValue); const bool startingFromZero = m_chartItem->chartType() == ChartItem::GridLines;
} const qreal valuesCount = this->valuesCount() - (startingFromZero ? 1 : 0);
minXValue = std::min(0.0, minXValue);
maxXValue = std::max(valuesCount, maxXValue);
} else {
for (qreal value : series->data()->xAxisValues()){
minXValue = std::min(value, minXValue);
maxXValue = std::max(value, maxXValue);
} }
} }
} }
m_yAxisData = AxisData(minYValue, maxYValue); m_chartItem->xAxisData()->update(minXValue, maxXValue);
m_xAxisData = AxisData(minXValue, maxXValue); m_chartItem->yAxisData()->update(minYValue, maxYValue);
} }
qreal AbstractSeriesChart::hPadding(QRectF chartRect) qreal AbstractSeriesChart::hPadding(QRectF chartRect)
@ -676,28 +854,54 @@ int AbstractSeriesChart::seriesCount()
return m_chartItem->series().count(); return m_chartItem->series().count();
} }
QSizeF AbstractSeriesChart::calcChartLegendSize(const QFont &font) QSizeF AbstractSeriesChart::calcChartLegendSize(const QFont &font, const qreal maxWidth)
{ {
QFontMetrics fm(font); QFontMetrics fm(font);
qreal cw = 0; switch(m_chartItem->legendAlign()) {
qreal maxWidth = 0; case ChartItem::LegendAlignBottomLeft:
case ChartItem::LegendAlignBottomCenter:
if (!m_chartItem->series().isEmpty()){ case ChartItem::LegendAlignBottomRight: {
foreach(SeriesItem* series, m_chartItem->series()){ const qreal seriesCount = m_chartItem->series().isEmpty() ? m_designLabels.size() : m_chartItem->series().size();
cw += fm.height(); const qreal indicatorWidth = fm.height() * 1.5;
if (maxWidth<fm.boundingRect(series->name()).width()) m_legendColumnWidths.clear();
maxWidth = fm.boundingRect(series->name()).width()+10; while (!calculateLegendColumnWidths(indicatorWidth, maxWidth, fm)) {
// Nothing to do here
} }
} else { if (m_legendColumnWidths.isEmpty()) {
foreach(QString label, m_designLabels){ m_legendColumnWidths.append(0);
cw += fm.height();
if (maxWidth<fm.boundingRect(label).width())
maxWidth = fm.boundingRect(label).width()+10;
} }
const qreal columnCount = m_legendColumnWidths.size();
const qreal rowCount = std::ceil(seriesCount / columnCount);
QSizeF legendSize(std::accumulate(m_legendColumnWidths.cbegin(), m_legendColumnWidths.cend(), 0.0) + fm.height() / 2,
(rowCount + 1) * fm.height());
if (legendSize.width() > maxWidth) {
legendSize.setWidth(maxWidth);
}
return legendSize;
} }
cw += fm.height(); default: {
return QSizeF(maxWidth+fm.height()*2,cw); qreal cw = 0;
qreal maxWidth = 0;
if (m_chartItem->series().isEmpty()) {
foreach(QString label, m_designLabels){
cw += fm.height();
if (maxWidth<fm.boundingRect(label).width())
maxWidth = fm.boundingRect(label).width()+10;
}
} else {
foreach(SeriesItem* series, m_chartItem->series()){
cw += fm.height();
if (maxWidth<fm.boundingRect(series->name()).width())
maxWidth = fm.boundingRect(series->name()).width()+10;
}
}
cw += fm.height();
return QSizeF(maxWidth+fm.height()*2,cw);
}
}
return QSizeF();
} }
bool AbstractSeriesChart::verticalLabels(QPainter* painter, QRectF labelsRect) bool AbstractSeriesChart::verticalLabels(QPainter* painter, QRectF labelsRect)
@ -829,7 +1033,7 @@ void AbstractSeriesChart::paintGrid(QPainter *painter, QRectF gridRect)
painter->save(); painter->save();
const AxisData &yAxisData = this->yAxisData(); const AxisData &yAxisData = this->yAxisData();
const AxisData &xAxisData = this->xAxisData(); AxisData &xAxisData = this->xAxisData();
painter->setRenderHint(QPainter::Antialiasing,false); painter->setRenderHint(QPainter::Antialiasing,false);
@ -874,20 +1078,19 @@ void AbstractSeriesChart::paintGrid(QPainter *painter, QRectF gridRect)
if (m_chartItem->horizontalAxisOnTop()) { if (m_chartItem->horizontalAxisOnTop()) {
painter->drawLine(x, gridRect.top() - gridOffset.height(), painter->drawLine(x, gridRect.top() - gridOffset.height(),
x, (drawFullLine ? gridRect.bottom() : gridRect.top())); x, (drawFullLine ? gridRect.bottom() : gridRect.top()));
painter->drawText(QRectF(x - painter->fontMetrics().width(text) / 2, painter->drawText(QRectF(x - painter->fontMetrics().boundingRect(text).width() / 2,
gridRect.top() - (fontHeight + gridOffset.height()), gridRect.top() - (fontHeight + gridOffset.height()),
hStep, fontHeight), hStep, fontHeight),
text); text);
} else { } else {
painter->drawLine(x, gridRect.bottom() + gridOffset.height(), painter->drawLine(x, gridRect.bottom() + gridOffset.height(),
x, (drawFullLine ? gridRect.top() : gridRect.bottom())); x, (drawFullLine ? gridRect.top() : gridRect.bottom()));
painter->drawText(QRectF(x - painter->fontMetrics().width(text) / 2, painter->drawText(QRectF(x - painter->fontMetrics().boundingRect(text).width() / 2,
gridRect.bottom() + halfFontHeight * 0 + gridOffset.height(), gridRect.bottom() + halfFontHeight * 0 + gridOffset.height(),
hStep, fontHeight), hStep, fontHeight),
text); text);
} }
} }
painter->restore(); painter->restore();
} }
@ -973,7 +1176,12 @@ QString AbstractSeriesChart::axisLabel(int i, const AxisData &axisData)
{ {
const qreal min = axisData.rangeMin(); const qreal min = axisData.rangeMin();
const qreal step = axisData.step(); const qreal step = axisData.step();
qreal value = min + i * step; qreal value = 0;
if (axisData.type() == AxisData::YAxis && axisData.reverseDirection() && min >= 0) {
value = min + (axisData.segmentCount() - i) * step;
} else {
value = min + i * step;
}
if (std::floor(step) == step) { if (std::floor(step) == step) {
return QString::number(value); return QString::number(value);
} }
@ -981,48 +1189,128 @@ QString AbstractSeriesChart::axisLabel(int i, const AxisData &axisData)
return QString::number(round(value * 100.0) / 100.0); return QString::number(round(value * 100.0) / 100.0);
} }
bool AbstractSeriesChart::calculateLegendColumnWidths(qreal indicatorWidth, qreal maxWidth, const QFontMetrics &fm)
{
// This method is called in the loop, because to handle case when we get
// 3 small series names in first row and then in second row small name and long name.
// In this case we need to set maximum column count to 2 and iterate from the start to recalculate
// all the sizes
qreal currentRowWidth = 0;
int currentColumn = 0;
// During first iteration it is updated when moving to second row
// After first iteration some column width are already calculated and are set as max,
// because all rows need to have same column count (except last one)
int maxColumnCount = m_legendColumnWidths.size();
if (m_chartItem->series().isEmpty()) {
for (int i=0 ; i < m_designLabels.size() ; ++i) {
const qreal itemWidth = (qreal)(fm.boundingRect(m_designLabels[i]).width()) + indicatorWidth;
if (!calculateLegendSingleColumnWidth(currentRowWidth, currentColumn, maxColumnCount, itemWidth, maxWidth)) {
return false;
}
}
} else {
for (int i = 0 ; i < m_chartItem->series().size() ; ++i) {
SeriesItem* series = m_chartItem->series().at(i);
const qreal itemWidth = (qreal)(fm.boundingRect(series->name()).width()) + indicatorWidth;
if (!calculateLegendSingleColumnWidth(currentRowWidth, currentColumn, maxColumnCount, itemWidth, maxWidth)) {
return false;
}
}
}
return true;
}
bool AbstractSeriesChart::calculateLegendSingleColumnWidth(qreal &currentRowWidth, int &currentColumn, int &maxColumnCount,
const qreal itemWidth, const qreal maxRowWidth)
{
const bool maxColumnCountDefined = maxColumnCount > 0;
// Check if there is enough space for current item in the row
const bool isEnoughSpaceInRowForItem = currentRowWidth + itemWidth > maxRowWidth;
// Check if it is last column already
const bool lastColumnReached = (maxColumnCountDefined && currentColumn >= maxColumnCount);
if (isEnoughSpaceInRowForItem || lastColumnReached) {
// Move to next row
currentColumn = 0;
// Set column count when moving to second row (next rows cannot have more columns)
if (!maxColumnCountDefined) {
maxColumnCount = currentColumn + 1;
}
currentRowWidth = itemWidth;
} else {
// Add next column in the row
currentRowWidth += itemWidth;
}
// Add new column or update already existing column width
if (currentColumn >= m_legendColumnWidths.size()) {
// Append new column
m_legendColumnWidths.append(itemWidth);
} else if (m_legendColumnWidths.at(currentColumn) < itemWidth) {
// Update size if item in column is bigger than items in same column in previous rows
m_legendColumnWidths[currentColumn] = itemWidth;
// After any updating column size we must recheck if all columns fit in the max row width
qreal rowWidth = itemWidth;
for (int c = 1 ; c < m_legendColumnWidths.size() ; c++) {
rowWidth += m_legendColumnWidths.at(c);
// When column widths exceed max row width remove columns at the end
if (rowWidth > maxRowWidth) {
m_legendColumnWidths.remove(c, m_legendColumnWidths.size() - c);
break;
}
}
// Return back and re-iterate from start to make sure everything fits
return false;
}
++currentColumn;
return true;
}
QVector<qreal> AbstractChart::legendColumnWidths() const
{
return m_legendColumnWidths;
}
void AbstractBarChart::paintChartLegend(QPainter *painter, QRectF legendRect) void AbstractBarChart::paintChartLegend(QPainter *painter, QRectF legendRect)
{ {
prepareLegendToPaint(legendRect, painter); prepareLegendToPaint(legendRect, painter);
int indicatorSize = painter->fontMetrics().height()/2;
painter->setPen(Qt::black); painter->setPen(Qt::black);
painter->setRenderHint(QPainter::Antialiasing,false); painter->setRenderHint(QPainter::Antialiasing,false);
if (m_chartItem->drawLegendBorder()) if (m_chartItem->drawLegendBorder())
painter->drawRect(legendRect); painter->drawRect(legendRect);
painter->setRenderHint(QPainter::Antialiasing,true); painter->setRenderHint(QPainter::Antialiasing,true);
QRectF indicatorsRect = legendRect.adjusted(painter->fontMetrics().height()/2,painter->fontMetrics().height()/2,0,0);
const qreal halfFontSize = painter->fontMetrics().height() / 2;
int indicatorSize = halfFontSize;
const QRectF indicatorsRect = legendRect.adjusted(halfFontSize, halfFontSize, 0, 0);
bool isHorizontal = false;
switch(m_chartItem->legendAlign()) {
case ChartItem::LegendAlignBottomLeft:
case ChartItem::LegendAlignBottomCenter:
case ChartItem::LegendAlignBottomRight:
isHorizontal = true;
break;
default:
isHorizontal = false;
break;
}
if (!m_chartItem->series().isEmpty()){ if (!m_chartItem->series().isEmpty()){
qreal cw = 0; for (int i = 0 ; i < m_chartItem->series().size() ; ++i) {
foreach(SeriesItem* series, m_chartItem->series()){ SeriesItem* series = m_chartItem->series().at(i);
QString label = series->name(); if (isHorizontal) {
painter->drawText(indicatorsRect.adjusted(indicatorSize+indicatorSize/2,cw,0,0),label); drawHorizontalLegendItem(painter, i, series->name(), indicatorSize, indicatorsRect, series->color());
painter->setBrush(series->color()); } else {
painter->drawEllipse( drawVerticalLegendItem(painter, i, series->name(), indicatorSize, indicatorsRect, series->color());
indicatorsRect.adjusted( }
0,
cw+indicatorSize/2,
-(indicatorsRect.width()-indicatorSize),
-(indicatorsRect.height()-(cw+indicatorSize+indicatorSize/2))
)
);
cw += painter->fontMetrics().height();
} }
} else if (m_chartItem->itemMode() == DesignMode){ } else if (m_chartItem->itemMode() == DesignMode) {
qreal cw = 0; for (int i = 0 ; i < m_designLabels.size() ; ++i){
for (int i=0;i<m_designLabels.size();++i){ if (isHorizontal) {
QString label = m_designLabels.at(i); drawHorizontalLegendItem(painter, i, m_designLabels.at(i), indicatorSize, indicatorsRect, color_map[i]);
painter->drawText(indicatorsRect.adjusted(indicatorSize+indicatorSize/2,cw,0,0),label); } else {
painter->setBrush(color_map[i]); drawVerticalLegendItem(painter, i, m_designLabels.at(i), indicatorSize, indicatorsRect, color_map[i]);
painter->drawEllipse( }
indicatorsRect.adjusted(
0,
cw+indicatorSize/2,
-(indicatorsRect.width()-indicatorSize),
-(indicatorsRect.height()-(cw+indicatorSize+indicatorSize/2))
)
);
cw += painter->fontMetrics().height();
} }
} }
@ -1058,4 +1346,66 @@ QRectF AbstractBarChart::horizontalLabelsRect(QPainter *painter, QRectF labelsRe
return labelsRect.adjusted(0, (labelsRect.height() - maxWidth), 0, 0); return labelsRect.adjusted(0, (labelsRect.height() - maxWidth), 0, 0);
} }
void AbstractBarChart::drawVerticalLegendItem(QPainter *painter, int i, const QString &text, int indicatorSize,
const QRectF &indicatorsRect, const QColor &indicatorColor)
{
const qreal y = i * painter->fontMetrics().height();
painter->drawText(indicatorsRect.adjusted(indicatorSize+indicatorSize * 1.5, y, 0, 0),text);
switch(m_chartItem->legendStyle()) {
case ChartItem::LegendPoints: {
painter->setBrush(indicatorColor);
painter->drawEllipse(
indicatorsRect.adjusted(
0,
y+indicatorSize/2,
-(indicatorsRect.width()-indicatorSize),
-(indicatorsRect.height()-(y+indicatorSize+indicatorSize/2))
)
);
break;
}
case ChartItem::LegendLines: {
const QPen tmpPen = painter->pen();
QPen indicatorPen(indicatorColor);
indicatorPen.setWidth(4);
painter->setPen(indicatorPen);
const QPointF linePos = QPointF(indicatorsRect.left(), indicatorsRect.top() + y + painter->fontMetrics().height()/2);
painter->drawLine(linePos, linePos + QPointF(indicatorSize, 0));
painter->setPen(tmpPen);
break;
}
}
}
void AbstractBarChart::drawHorizontalLegendItem(QPainter *painter, int i, const QString &text,
int indicatorSize, const QRectF &indicatorsRect, const QColor &indicatorColor)
{
const QVector<qreal> &columnWidths = legendColumnWidths();
if (columnWidths.isEmpty())
return;
const int column = i % columnWidths.size();
const int row = std::floor(i / columnWidths.size());
const qreal halfTextSize = painter->fontMetrics().height() / 2;
const qreal x = indicatorsRect.x() + std::accumulate(columnWidths.cbegin(), columnWidths.cbegin() + column, 0.0);
const qreal y = indicatorsRect.y() + (row + 1) * painter->fontMetrics().height();
painter->drawText(QPointF(x + indicatorSize * 1.5, y), text);
switch(m_chartItem->legendStyle()) {
case ChartItem::LegendPoints: {
painter->setBrush(indicatorColor);
painter->drawEllipse(x, y - halfTextSize, indicatorSize, indicatorSize);
break;
}
case ChartItem::LegendLines: {
const QPen tmpPen = painter->pen();
QPen indicatorPen(indicatorColor);
indicatorPen.setWidth(4);
painter->setPen(indicatorPen);
painter->drawLine(x, y - halfTextSize * 0.7, x + indicatorSize, y - halfTextSize * 0.7);
painter->setPen(tmpPen);
break;
}
}
}
} // namespace LimeReport } // namespace LimeReport

View File

@ -76,28 +76,36 @@ public:
virtual ~AbstractChart(){} virtual ~AbstractChart(){}
virtual void paintChart(QPainter *painter, QRectF rect) = 0; virtual void paintChart(QPainter *painter, QRectF rect) = 0;
virtual void paintChartLegend(QPainter *painter, QRectF legendRect) =0; virtual void paintChartLegend(QPainter *painter, QRectF legendRect) =0;
virtual QSizeF calcChartLegendSize(const QFont &font) = 0; virtual QSizeF calcChartLegendSize(const QFont &font, qreal maxWidth = 0) = 0;
virtual QRectF calcChartLegendRect(const QFont& font, const QRectF& parentRect, bool takeAllRect, qreal borderMargin, qreal titleOffset); virtual QRectF calcChartLegendRect(const QFont& font, const QRectF& parentRect, bool takeAllRect, qreal borderMargin, qreal titleOffset);
QFont titleFont();
void setTitleFont(const QFont &value);
protected: protected:
QVector<qreal> legendColumnWidths() const;
virtual void prepareLegendToPaint(QRectF& legendRect, QPainter *painter); virtual void prepareLegendToPaint(QRectF& legendRect, QPainter *painter);
protected: protected:
// Title font must be placed here instead of CharItem, becuase
// it would cause crash when creating CharItem object on embedded
QFont m_titleFont;
ChartItem* m_chartItem; ChartItem* m_chartItem;
QList<QString> m_designLabels; QList<QString> m_designLabels;
QVector<qreal> m_legendColumnWidths;
}; };
class AbstractSeriesChart: public AbstractChart{ class AbstractSeriesChart: public AbstractChart{
public: public:
AbstractSeriesChart(ChartItem* chartItem); AbstractSeriesChart(ChartItem* chartItem);
protected: protected:
AxisData yAxisData(); AxisData &xAxisData() const;
AxisData xAxisData(); AxisData &yAxisData() const;
qreal maxValue(); qreal maxValue();
qreal minValue(); qreal minValue();
void updateMinAndMaxValues(); void updateMinAndMaxValues();
int valuesCount(); int valuesCount();
int seriesCount(); int seriesCount();
bool verticalLabels(QPainter* painter, QRectF labelsRect); bool verticalLabels(QPainter* painter, QRectF labelsRect);
QSizeF calcChartLegendSize(const QFont &font); QSizeF calcChartLegendSize(const QFont &font, qreal maxWidth);
qreal* designValues(){ return m_designValues;} qreal* designValues(){ return m_designValues;}
virtual qreal hPadding(QRectF chartRect); virtual qreal hPadding(QRectF chartRect);
virtual qreal vPadding(QRectF chartRect); virtual qreal vPadding(QRectF chartRect);
@ -114,7 +122,9 @@ protected:
virtual QString axisLabel(int i, const AxisData &axisData); virtual QString axisLabel(int i, const AxisData &axisData);
private: private:
AxisData m_yAxisData, m_xAxisData; bool calculateLegendColumnWidths(qreal indicatorWidth, qreal maxWidth, const QFontMetrics &fm);
bool calculateLegendSingleColumnWidth(qreal &currentRowWidth, int &currentColumn, int &maxColumnCount,
const qreal itemWidth, const qreal maxRowWidth);
qreal m_designValues [9]; qreal m_designValues [9];
}; };
@ -125,20 +135,30 @@ public:
protected: protected:
QRectF verticalLabelsRect(QPainter* painter, QRectF horizontalLabelsRect); QRectF verticalLabelsRect(QPainter* painter, QRectF horizontalLabelsRect);
virtual QRectF horizontalLabelsRect(QPainter* painter, QRectF horizontalLabelsRect); virtual QRectF horizontalLabelsRect(QPainter* painter, QRectF horizontalLabelsRect);
private:
void drawVerticalLegendItem(QPainter *painter, int i, const QString &text,
int indicatorSize, const QRectF &indicatorsRect, const QColor &indicatorColor);
void drawHorizontalLegendItem(QPainter *painter, int i, const QString &text,
int indicatorSize, const QRectF &indicatorsRect, const QColor &indicatorColor);
}; };
class ChartItem : public LimeReport::ItemDesignIntf class ChartItem : public LimeReport::ItemDesignIntf
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(QObject* xAxisSettings READ xAxisSettings WRITE setXAxisSettings)
Q_PROPERTY(QObject* yAxisSettings READ yAxisSettings WRITE setYAxisSettings)
Q_PROPERTY(ACollectionProperty series READ fakeCollectionReader WRITE setSeries) Q_PROPERTY(ACollectionProperty series READ fakeCollectionReader WRITE setSeries)
Q_PROPERTY(QString datasource READ datasource WRITE setDatasource) Q_PROPERTY(QString datasource READ datasource WRITE setDatasource)
Q_PROPERTY(QString chartTitle READ chartTitle WRITE setChartTitle) Q_PROPERTY(QString chartTitle READ chartTitle WRITE setChartTitle)
Q_PROPERTY(bool drawLegendBorder READ drawLegendBorder WRITE setDrawLegendBorder) Q_PROPERTY(bool drawLegendBorder READ drawLegendBorder WRITE setDrawLegendBorder)
Q_PROPERTY(LegendAlign legendAlign READ legendAlign WRITE setLegendAlign) Q_PROPERTY(LegendAlign legendAlign READ legendAlign WRITE setLegendAlign)
Q_PROPERTY(LegendStyle legendStyle READ legendStyle WRITE setLegendStyle)
Q_PROPERTY(TitleAlign titleAlign READ titleAlign WRITE setTitleAlign) Q_PROPERTY(TitleAlign titleAlign READ titleAlign WRITE setTitleAlign)
Q_PROPERTY(ChartType chartType READ chartType WRITE setChartType) Q_PROPERTY(ChartType chartType READ chartType WRITE setChartType)
Q_PROPERTY(QString labelsField READ labelsField WRITE setLabelsField) Q_PROPERTY(QString labelsField READ labelsField WRITE setLabelsField)
Q_PROPERTY(bool showLegend READ showLegend WRITE setShowLegend) Q_PROPERTY(bool showLegend READ showLegend WRITE setShowLegend)
Q_PROPERTY(QFont titleFont READ titleFont WRITE setTitleFont)
Q_PROPERTY(QFont font READ font WRITE setCharItemFont)
//linesChart //linesChart
Q_PROPERTY(bool drawPoints READ drawPoints WRITE setDrawPoints) Q_PROPERTY(bool drawPoints READ drawPoints WRITE setDrawPoints)
@ -152,7 +172,8 @@ class ChartItem : public LimeReport::ItemDesignIntf
friend class AbstractChart; friend class AbstractChart;
public: public:
enum LegendAlign{LegendAlignTop,LegendAlignCenter,LegendAlignBottom}; enum LegendAlign{LegendAlignRightTop,LegendAlignRightCenter,LegendAlignRightBottom,
LegendAlignBottomLeft,LegendAlignBottomCenter,LegendAlignBottomRight};
enum LegendStyle{LegendPoints, LegendLines}; enum LegendStyle{LegendPoints, LegendLines};
enum TitleAlign{TitleAlignLeft, TitleAlignCenter, TitleAlignRight}; enum TitleAlign{TitleAlignLeft, TitleAlignCenter, TitleAlignRight};
enum ChartType{Pie, VerticalBar, HorizontalBar, Lines, GridLines}; enum ChartType{Pie, VerticalBar, HorizontalBar, Lines, GridLines};
@ -164,11 +185,13 @@ public:
}; };
#if QT_VERSION >= 0x050500 #if QT_VERSION >= 0x050500
Q_ENUM(LegendAlign) Q_ENUM(LegendAlign)
Q_ENUM(LegendStyle)
Q_ENUM(TitleAlign) Q_ENUM(TitleAlign)
Q_ENUM(ChartType) Q_ENUM(ChartType)
Q_ENUM(LineType) Q_ENUM(LineType)
#else #else
Q_ENUMS(LegendAlign) Q_ENUMS(LegendAlign)
Q_ENUMS(LegendStyle)
Q_ENUMS(TitleAlign) Q_ENUMS(TitleAlign)
Q_ENUMS(ChartType) Q_ENUMS(ChartType)
Q_ENUMS(LineType) Q_ENUMS(LineType)
@ -179,6 +202,16 @@ public:
~ChartItem(); ~ChartItem();
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
QObject* xAxisSettings();
void setYAxisSettings(QObject *axis);
QObject* yAxisSettings();
void setXAxisSettings(QObject *axis);
AxisData *xAxisData();
AxisData *yAxisData();
void showAxisEditorDialog(bool isXAxis);
QList<SeriesItem *> &series(); QList<SeriesItem *> &series();
void setSeries(const QList<SeriesItem *> &series); void setSeries(const QList<SeriesItem *> &series);
bool isSeriesExists(const QString& name); bool isSeriesExists(const QString& name);
@ -195,6 +228,9 @@ public:
LegendAlign legendAlign() const; LegendAlign legendAlign() const;
void setLegendAlign(const LegendAlign &legendAlign); void setLegendAlign(const LegendAlign &legendAlign);
LegendStyle legendStyle() const;
void setLegendStyle(const LegendStyle &legendStyle);
TitleAlign titleAlign() const; TitleAlign titleAlign() const;
void setTitleAlign(const TitleAlign &titleAlign); void setTitleAlign(const TitleAlign &titleAlign);
@ -226,6 +262,12 @@ public:
GridChartLines gridChartLines() const; GridChartLines gridChartLines() const;
void setGridChartLines(GridChartLines flags); void setGridChartLines(GridChartLines flags);
QFont titleFont() const;
void setTitleFont(QFont value);
void setCharItemFont(QFont value);
QSettings *settings();
protected: protected:
void paintChartTitle(QPainter* painter, QRectF titleRect); void paintChartTitle(QPainter* painter, QRectF titleRect);
virtual BaseDesignIntf* createSameTypeItem(QObject *owner, QGraphicsItem *parent); virtual BaseDesignIntf* createSameTypeItem(QObject *owner, QGraphicsItem *parent);
@ -257,6 +299,8 @@ private:
QString m_xAxisField; QString m_xAxisField;
bool m_horizontalAxisOnTop; bool m_horizontalAxisOnTop;
GridChartLines m_gridChartLines; GridChartLines m_gridChartLines;
LegendStyle m_legendStyle;
AxisData *m_xAxisData, *m_yAxisData;
}; };
} //namespace LimeReport } //namespace LimeReport
#endif // LRCHARTITEM_H #endif // LRCHARTITEM_H

View File

@ -295,4 +295,15 @@ void ChartItemEditor::on_xAxisFieldComboBox_currentTextChanged(const QString &ar
{ {
if (!m_initing) if (!m_initing)
m_charItem->setXAxisField(arg1); m_charItem->setXAxisField(arg1);
} }
void ChartItemEditor::on_tableWidget_itemChanged(QTableWidgetItem *item)
{
if (ui->seriesNameLineEdit->hasFocus())
return;
const QString dataStr = item->data(Qt::DisplayRole).toString();
if (dataStr == ui->seriesNameLineEdit->text())
return;
ui->seriesNameLineEdit->setText(dataStr);
}

View File

@ -40,8 +40,8 @@ private slots:
void on_labelsFieldComboBox_currentTextChanged(const QString &arg1); void on_labelsFieldComboBox_currentTextChanged(const QString &arg1);
void slotChangeSeriesColor(); void slotChangeSeriesColor();
void on_seriesTypeComboBox_currentIndexChanged(const QString &arg1); void on_seriesTypeComboBox_currentIndexChanged(const QString &arg1);
void on_xAxisFieldComboBox_currentTextChanged(const QString &arg1); void on_xAxisFieldComboBox_currentTextChanged(const QString &arg1);
void on_tableWidget_itemChanged(QTableWidgetItem *item);
private: private:
void readSetting(); void readSetting();

View File

@ -171,9 +171,14 @@ void HorizontalLayout::updateLayoutSize()
void HorizontalLayout::relocateChildren() void HorizontalLayout::relocateChildren()
{ {
int spaceBorder = (borderLines() != 0) ? borderLineSize() : 0; int spaceBorder = (borderLines() != 0) ? borderLineSize() : 0;
QList<BaseDesignIntf*> newChildren;
if (layoutsChildren().count() < childItems().size()-1){ if (layoutsChildren().count() < childItems().size()-1){
auto oldChildren = layoutsChildren();
layoutsChildren().clear(); layoutsChildren().clear();
foreach (BaseDesignIntf* item, childBaseItems()) { foreach (BaseDesignIntf* item, childBaseItems()) {
if (!oldChildren.contains(item)) {
newChildren.append(item);
}
layoutsChildren().append(item); layoutsChildren().append(item);
} }
} }
@ -188,6 +193,10 @@ void HorizontalLayout::relocateChildren()
} }
} }
setIsRelocating(false); setIsRelocating(false);
for (BaseDesignIntf* item : newChildren) {
connectToLayout(item);
}
} }
void HorizontalLayout::divideSpace(){ void HorizontalLayout::divideSpace(){

View File

@ -61,8 +61,13 @@ BaseDesignIntf *ImageItem::createSameTypeItem(QObject *owner, QGraphicsItem *par
} }
void ImageItem::loadPictureFromVariant(QVariant& data){ void ImageItem::loadPictureFromVariant(QVariant& data){
//TODO: Migrate to QMetaType
if (data.isValid()){ if (data.isValid()){
if (data.type()==QVariant::Image){ #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
if (data.typeId() == QMetaType::QImage){
#else
if (data.type() == QVariant::Image){
#endif
m_picture = data.value<QImage>(); m_picture = data.value<QImage>();
} else { } else {
switch (m_format) { switch (m_format) {
@ -178,11 +183,22 @@ void ImageItem::updateItemSize(DataSourceManager* dataManager, RenderPass pass,
m_resourcePath = expandDataFields(m_resourcePath, NoEscapeSymbols, dataManager); m_resourcePath = expandDataFields(m_resourcePath, NoEscapeSymbols, dataManager);
m_picture = QImage(m_resourcePath); m_picture = QImage(m_resourcePath);
} else if (!m_variable.isEmpty()){ } else if (!m_variable.isEmpty()){
//TODO: Migrate to QMetaType
QVariant data = dataManager->variable(m_variable); QVariant data = dataManager->variable(m_variable);
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
if (data.typeId() == QMetaType::QString){
#else
if (data.type() == QVariant::String){ if (data.type() == QVariant::String){
#endif
m_picture = QImage(data.toString()); m_picture = QImage(data.toString());
} else if (data.type() == QVariant::Image){ } else {
loadPictureFromVariant(data); #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
if (data.typeId() == QMetaType::QImage){
#else
if (data.type() == QVariant::Image){
#endif
loadPictureFromVariant(data);
}
} }
} }
} }

View File

@ -107,11 +107,22 @@ void SVGItem::updateItemSize(DataSourceManager *dataManager, RenderPass pass, in
m_resourcePath = expandDataFields(m_resourcePath, NoEscapeSymbols, dataManager); m_resourcePath = expandDataFields(m_resourcePath, NoEscapeSymbols, dataManager);
m_image = imageFromResource(m_resourcePath); m_image = imageFromResource(m_resourcePath);
} else if (!m_variable.isEmpty()){ } else if (!m_variable.isEmpty()){
//TODO: Migrate to QMetaType
QVariant data = dataManager->variable(m_variable); QVariant data = dataManager->variable(m_variable);
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
if (data.typeId() == QMetaType::QString){
#else
if (data.type() == QVariant::String){ if (data.type() == QVariant::String){
#endif
m_image = imageFromResource(data.toString()); m_image = imageFromResource(data.toString());
} else if (data.type() == QVariant::ByteArray) { } else {
m_image = data.value<QByteArray>() ; #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
if (data.typeId() == QMetaType::QByteArray) {
#else
if (data.type() == QVariant::ByteArray) {
#endif
m_image = data.value<QByteArray>() ;
}
} }
} }
} }

View File

@ -276,10 +276,6 @@ void TextItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* style, Q
BaseDesignIntf::paint(painter, style, widget); BaseDesignIntf::paint(painter, style, widget);
} }
QString TextItem::content() const{
return m_strText;
}
void TextItem::Init() void TextItem::Init()
{ {
m_autoWidth = NoneAutoWidth; m_autoWidth = NoneAutoWidth;
@ -299,14 +295,8 @@ void TextItem::setContent(const QString &value)
{ {
if (m_strText.compare(value)!=0){ if (m_strText.compare(value)!=0){
QString oldValue = m_strText; QString oldValue = m_strText;
if (m_trimValue)
m_strText=value.trimmed();
else
m_strText=value;
// if (itemMode() == DesignMode && (autoHeight())){ m_strText = value;
// initTextSizes();
// }
if (!isLoading()){ if (!isLoading()){
if (autoHeight() || autoWidth() || hasFollower()) if (autoHeight() || autoWidth() || hasFollower())
@ -317,6 +307,10 @@ void TextItem::setContent(const QString &value)
} }
} }
QString TextItem::content() const{
return m_strText;
}
void TextItem::updateItemSize(DataSourceManager* dataManager, RenderPass pass, int maxHeight) void TextItem::updateItemSize(DataSourceManager* dataManager, RenderPass pass, int maxHeight)
{ {
@ -493,29 +487,43 @@ QString TextItem::formatFieldValue()
} }
} }
#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
switch (value.type()) { switch (value.type()) {
case QVariant::Date: case QVariant::Date:
case QVariant::DateTime: case QVariant::DateTime:
return formatDateTime(value.toDateTime()); return formatDateTime(value.toDateTime());
case QVariant::Double: case QVariant::Double:
return formatNumber(value.toDouble()); return formatNumber(value.toDouble());
default: default:
return value.toString(); return value.toString();
} }
#else
switch (value.typeId()) {
case QMetaType::QDate:
case QMetaType::QDateTime:
return formatDateTime(value.toDateTime());
case QMetaType::Double:
return formatNumber(value.toDouble());
default:
return value.toString();
}
#endif
} }
TextItem::TextPtr TextItem::textDocument() const TextItem::TextPtr TextItem::textDocument() const
{ {
TextPtr text(new QTextDocument); TextPtr text(new QTextDocument);
QString content = m_trimValue ? m_strText.trimmed() : m_strText;
if (allowHTML()) if (allowHTML())
if (isReplaceCarriageReturns()){ if (isReplaceCarriageReturns()){
text->setHtml(replaceReturns(m_strText)); text->setHtml(replaceReturns(content));
} else { } else {
text->setHtml(m_strText); text->setHtml(content);
} }
else else
text->setPlainText(m_strText); text->setPlainText(content);
QTextOption to; QTextOption to;
to.setAlignment(m_alignment); to.setAlignment(m_alignment);
@ -785,6 +793,7 @@ void TextItem::setTrimValue(bool value)
{ {
bool oldValue = m_trimValue; bool oldValue = m_trimValue;
m_trimValue = value; m_trimValue = value;
update();
notify("trimValue",oldValue,value); notify("trimValue",oldValue,value);
} }
@ -827,7 +836,7 @@ void TextItem::expandContent(DataSourceManager* dataManager, RenderPass pass)
#if (QT_VERSION < QT_VERSION_CHECK(5, 15, 1)) #if (QT_VERSION < QT_VERSION_CHECK(5, 15, 1))
QRegExp rx(QString(Const::NAMED_VARIABLE_RX).arg(variableName)); QRegExp rx(QString(Const::NAMED_VARIABLE_RX).arg(variableName));
#else #else
QRegularExpression rx(QString(Const::NAMED_VARIABLE_RX).arg(variableName)); QRegularExpression rx = getNamedVariableRegEx(variableName);
#endif #endif
if (context.contains(rx) && pass == FirstPass){ if (context.contains(rx) && pass == FirstPass){
backupContent(); backupContent();

View File

@ -57,9 +57,14 @@ void VerticalLayout::updateLayoutSize()
void VerticalLayout::relocateChildren() void VerticalLayout::relocateChildren()
{ {
int spaceBorder = (borderLines() != 0) ? borderLineSize() : 0; int spaceBorder = (borderLines() != 0) ? borderLineSize() : 0;
QList<BaseDesignIntf*> newChildren;
if (layoutsChildren().count() < childItems().size() - 1){ if (layoutsChildren().count() < childItems().size() - 1){
auto oldChildren = layoutsChildren();
layoutsChildren().clear(); layoutsChildren().clear();
foreach (BaseDesignIntf* item, childBaseItems()) { foreach (BaseDesignIntf* item, childBaseItems()) {
if (!oldChildren.contains(item)) {
newChildren.append(item);
}
layoutsChildren().append(item); layoutsChildren().append(item);
} }
} }
@ -74,6 +79,10 @@ void VerticalLayout::relocateChildren()
} }
} }
setIsRelocating(false); setIsRelocating(false);
for (BaseDesignIntf* item : newChildren) {
connectToLayout(item);
}
} }
bool VerticalLayout::canBeSplitted(int height) const bool VerticalLayout::canBeSplitted(int height) const

View File

@ -55,6 +55,7 @@ SOURCES += \
$$REPORT_PATH/items/lrabstractlayout.cpp \ $$REPORT_PATH/items/lrabstractlayout.cpp \
$$REPORT_PATH/items/lrchartitem.cpp \ $$REPORT_PATH/items/lrchartitem.cpp \
$$REPORT_PATH/items/lrchartitemeditor.cpp \ $$REPORT_PATH/items/lrchartitemeditor.cpp \
$$REPORT_PATH/items/lrchartaxiseditor.cpp \
$$REPORT_PATH/items/charts/lrhorizontalbarchart.cpp \ $$REPORT_PATH/items/charts/lrhorizontalbarchart.cpp \
$$REPORT_PATH/items/charts/lrlineschart.cpp \ $$REPORT_PATH/items/charts/lrlineschart.cpp \
$$REPORT_PATH/items/charts/lrgridlineschart.cpp \ $$REPORT_PATH/items/charts/lrgridlineschart.cpp \
@ -148,6 +149,7 @@ HEADERS += \
$$REPORT_PATH/items/lrabstractlayout.h \ $$REPORT_PATH/items/lrabstractlayout.h \
$$REPORT_PATH/items/lrchartitem.h \ $$REPORT_PATH/items/lrchartitem.h \
$$REPORT_PATH/items/lrchartitemeditor.h \ $$REPORT_PATH/items/lrchartitemeditor.h \
$$REPORT_PATH/items/lrchartaxiseditor.h \
$$REPORT_PATH/items/charts/lrhorizontalbarchart.h \ $$REPORT_PATH/items/charts/lrhorizontalbarchart.h \
$$REPORT_PATH/items/charts/lrlineschart.h \ $$REPORT_PATH/items/charts/lrlineschart.h \
$$REPORT_PATH/items/charts/lrgridlineschart.h \ $$REPORT_PATH/items/charts/lrgridlineschart.h \
@ -219,6 +221,7 @@ FORMS += \
$$REPORT_PATH/lraboutdialog.ui \ $$REPORT_PATH/lraboutdialog.ui \
$$REPORT_PATH/lrsettingdialog.ui \ $$REPORT_PATH/lrsettingdialog.ui \
$$REPORT_PATH/items/lrchartitemeditor.ui \ $$REPORT_PATH/items/lrchartitemeditor.ui \
$$REPORT_PATH/items/lrchartaxiseditor.ui \
$$REPORT_PATH/items/lrimageitemeditor.ui \ $$REPORT_PATH/items/lrimageitemeditor.ui \
$$REPORT_PATH/scripteditor/lrscripteditor.ui $$REPORT_PATH/scripteditor/lrscripteditor.ui

View File

@ -1,21 +1,84 @@
#include "lraxisdata.h" #include "lraxisdata.h"
namespace LimeReport { #include <cmath>
AxisData::AxisData() #include <QDebug>
: m_rangeMin(0), m_rangeMax(0),
m_minValue(0), m_maxValue(0), m_step(0),
m_delta(0), m_segmentCount(4)
{
namespace LimeReport {
AxisData::AxisData(AxisType type, QObject *parent)
: QObject(parent), m_rangeMin(0), m_rangeMax(0),
m_minValue(0), m_maxValue(0), m_step(0),
m_delta(0), m_segmentCount(4), m_calculateAxisScale(false),
m_reverseDirection(false), m_manualMaximum(0),
m_manualMinimum(0), m_manualStep(0), m_isMaximumAutomatic(true),
m_isMinimumAutomatic(true), m_isStepAutomatic(true),
m_type(type)
{
} }
AxisData::AxisData(qreal minValue, qreal maxValue) QString AxisData::toString() const
: AxisData() {
// Just for debug purposes
QString str;
QTextStream stream(&str);
stream << "{ "
<< "min: " << m_minValue << ", max: " << m_maxValue << ", step: " << m_step
<< ", range min: " << m_rangeMin << ", range max: " << m_rangeMax << ", segments: " << m_segmentCount
<< ", reverseDiection: " << m_reverseDirection << ", calculateAxisScale: " << m_calculateAxisScale
<< ", manualMaxEnabled: " << !m_isMaximumAutomatic << ", manualMinEnabled: " << !m_isMinimumAutomatic
<< ", manualStepEnabled: " << !m_isStepAutomatic << ", manualMax: " << m_manualMaximum
<< ", manualMin: " << m_manualMinimum << ", manualStep: " << m_manualStep
<< " }";
return str;
}
void AxisData::copy(AxisData *other)
{
m_calculateAxisScale = other->calculateAxisScale();
m_reverseDirection = other->reverseDirection();
m_manualMaximum = other->manualMaximum();
m_manualMinimum = other->manualMinimum();
m_manualStep = other->manualStep();
m_isMaximumAutomatic = other->isMaximumAutomatic();
m_isMinimumAutomatic = other->isMinimumAutomatic();
m_isStepAutomatic = other->isStepAutomatic();
}
void AxisData::update()
{
if (m_calculateAxisScale) {
calculateRoundedAxisScale();
} else {
calculateSimpleAxisScale();
}
m_delta = m_step * m_segmentCount;
// Update manual values if they are automatic
if (m_isStepAutomatic) {
m_manualStep = m_step;
}
if (m_isMinimumAutomatic) {
m_manualMinimum = m_rangeMin;
}
if (m_isMaximumAutomatic) {
m_manualMaximum = m_rangeMax;
}
}
void AxisData::update(qreal minValue, qreal maxValue)
{ {
m_minValue = minValue; m_minValue = minValue;
m_maxValue = maxValue; m_maxValue = maxValue;
calculateValuesAboveMax(minValue, maxValue, 4); update();
m_delta = m_step * m_segmentCount; }
void AxisData::updateForDesignMode()
{
m_minValue = 0;
m_maxValue = 40;
const bool tmp = m_calculateAxisScale;
m_calculateAxisScale = false;
update();
m_calculateAxisScale = tmp;
} }
int AxisData::segmentCount() const int AxisData::segmentCount() const
@ -23,6 +86,11 @@ int AxisData::segmentCount() const
return m_segmentCount; return m_segmentCount;
} }
bool AxisData::calculateAxisScale() const
{
return m_calculateAxisScale;
}
qreal AxisData::rangeMin() const qreal AxisData::rangeMin() const
{ {
return m_rangeMin; return m_rangeMin;
@ -53,16 +121,229 @@ qreal AxisData::delta() const
return m_delta; return m_delta;
} }
void AxisData::calculateValuesAboveMax(qreal minValue, qreal maxValue, int segments) void AxisData::calculateRoundedAxisScale()
{ {
const int delta = maxValue - minValue; const int maximumSegmentCount = 10;
bool calculateStep = isStepAutomatic();
const bool calculateMinimum = isMinimumAutomatic();
const bool calculateMaximum = isMaximumAutomatic();
qreal temporaryMin = 0;
qreal temporaryMax = 0;
if (calculateMinimum) {
temporaryMin = qMin(0.0, minValue());
} else {
temporaryMin = qMin(manualMinimum(), minValue());
}
if (calculateMaximum) {
temporaryMax = maxValue();
} else {
temporaryMax = qMax(manualMaximum(), maxValue());
}
m_step = calculateStep ? 0 : manualStep();
if (temporaryMax == temporaryMin) {
if (temporaryMax == 0) {
temporaryMax = 1;
} else {
temporaryMax *= 2;
}
}
const qreal minAndMaxSpacingOffset = 0.95;
qreal stepMagnitude = 0.0;
qreal normalizedStep = 0.0;
bool isStepNormalized = false;
bool isLoopFinished = false;
// Calculate until segment count is below maximum
while( !isLoopFinished ) {
if (calculateStep) {
if(isStepNormalized) {
if( normalizedStep == 1.0 ) {
normalizedStep = 2.0;
} else if( normalizedStep == 2.0 ) {
normalizedStep = 5.0;
} else {
normalizedStep = 1.0;
stepMagnitude *= 10;
}
} else {
const double startingStep = (temporaryMax - temporaryMin) / maximumSegmentCount;
const int exponent = static_cast< int >( floor( log10( startingStep ) ) );
stepMagnitude = pow(10.0, static_cast<double>(exponent));
normalizedStep = startingStep / stepMagnitude;
if( normalizedStep <= 1.0 ) {
normalizedStep = 1.0;
} else if( normalizedStep <= 2.0 ) {
normalizedStep = 2.0;
} else if( normalizedStep <= 5.0 ) {
normalizedStep = 5.0;
} else {
normalizedStep = 1.0;
stepMagnitude *= 10;
}
isStepNormalized = true;
}
m_step = normalizedStep * stepMagnitude;
}
qreal currentAxisMinimum = temporaryMin;
qreal currentAxisMaximum = temporaryMax;
if (calculateMinimum) {
currentAxisMinimum = calculateNewMinimum(currentAxisMinimum, m_step);
const qreal currentDelta = currentAxisMaximum - currentAxisMinimum;
const qreal actualDelta = currentAxisMaximum - minValue();
if ((currentAxisMinimum != 0.0) && ((actualDelta / currentDelta) > minAndMaxSpacingOffset)) {
currentAxisMinimum -= m_step;
}
}
if (calculateMaximum) {
currentAxisMaximum = calculateNewMaximum(currentAxisMaximum, m_step);
const qreal currentDelta = currentAxisMaximum - currentAxisMinimum;
const qreal actualDelta = maxValue() - currentAxisMinimum;
if ((currentAxisMaximum != 0.0) && ((actualDelta / currentDelta) > minAndMaxSpacingOffset)) {
currentAxisMaximum += m_step;
}
}
m_segmentCount = static_cast<int>(round((currentAxisMaximum - currentAxisMinimum) / m_step));
m_rangeMin = currentAxisMinimum;
m_rangeMax = currentAxisMaximum;
// Check also if step is correctly calucalted. It is possible for float steps that
// there might be a difference. Recalculate the step in that case.
const qreal tmpStep = (m_rangeMax - m_rangeMin) / m_segmentCount;
isLoopFinished = m_segmentCount <= maximumSegmentCount && qFuzzyCompare(tmpStep, m_step);
if (!isLoopFinished) {
// Configured step may be invalid, calculating it automatically
calculateStep = true;
}
}
}
void AxisData::calculateSimpleAxisScale()
{
qreal min = 0;
if (m_minValue < 0) {
min = minValue();
}
m_segmentCount = 4;
const int delta = maxValue() - min;
int max = delta; int max = delta;
while (max % segments != 0){ while (max % m_segmentCount != 0){
max++; max++;
} }
m_rangeMax = max; m_rangeMax = minValue() + max;
m_step = max / segments; m_step = max / m_segmentCount;
m_rangeMin = minValue; m_rangeMin = minValue();
m_segmentCount = segments;
} }
double AxisData::calculateNewMinimum(qreal min, qreal step) const
{
if (step <= 0.0)
return min;
double ret = floor(min / step) * step;
if (ret > min && !qFuzzyCompare(ret, min)) {
ret -= step;
}
return ret;
}
double AxisData::calculateNewMaximum(qreal max, qreal step) const
{
if (step <= 0.0)
return max;
double ret = floor(max / step) * step;
if (ret < max && !qFuzzyCompare(ret, max)) {
ret += step;
}
return ret;
}
void AxisData::setCalculateAxisScale(bool newCalculateAxisScale)
{
m_calculateAxisScale = newCalculateAxisScale;
}
bool AxisData::reverseDirection() const
{
return m_reverseDirection;
}
void AxisData::setReverseDirection(bool reverseDirection)
{
m_reverseDirection = reverseDirection;
}
qreal AxisData::manualMaximum() const
{
return m_manualMaximum;
}
void AxisData::setManualMaximum(qreal newManualMaximum)
{
m_manualMaximum = newManualMaximum;
}
qreal AxisData::manualMinimum() const
{
return m_manualMinimum;
}
void AxisData::setManualMinimum(qreal newManualMinimum)
{
m_manualMinimum = newManualMinimum;
}
qreal AxisData::manualStep() const
{
return m_manualStep;
}
void AxisData::setManualStep(qreal newManualStep)
{
m_manualStep = newManualStep;
}
bool AxisData::isMaximumAutomatic() const
{
return m_isMaximumAutomatic;
}
void AxisData::setIsMaximumAutomatic(bool newIsMaximumAutomatic)
{
m_isMaximumAutomatic = newIsMaximumAutomatic;
}
bool AxisData::isMinimumAutomatic() const
{
return m_isMinimumAutomatic;
}
void AxisData::setIsMinimumAutomatic(bool newIsMinimumAutomatic)
{
m_isMinimumAutomatic = newIsMinimumAutomatic;
}
bool AxisData::isStepAutomatic() const
{
return m_isStepAutomatic;
}
void AxisData::setIsStepAutomatic(bool newIsStepAutomatic)
{
m_isStepAutomatic = newIsStepAutomatic;
}
AxisData::AxisType AxisData::type() const
{
return m_type;
}
} }

View File

@ -1,14 +1,33 @@
#ifndef AXISDATA_H #ifndef AXISDATA_H
#define AXISDATA_H #define AXISDATA_H
#include <QtGlobal> #include <QObject>
namespace LimeReport { namespace LimeReport {
class AxisData class AxisData : public QObject
{ {
Q_OBJECT
Q_PROPERTY(bool reverseDirection READ reverseDirection WRITE setReverseDirection)
Q_PROPERTY(bool calculateAxisScale READ calculateAxisScale WRITE setCalculateAxisScale)
Q_PROPERTY(bool isStepAutomatic READ isStepAutomatic WRITE setIsStepAutomatic)
Q_PROPERTY(bool isMinimumAutomatic READ isMinimumAutomatic WRITE setIsMinimumAutomatic)
Q_PROPERTY(bool isMaximumAutomatic READ isMaximumAutomatic WRITE setIsMaximumAutomatic)
Q_PROPERTY(qreal manualStep READ manualStep WRITE setManualStep)
Q_PROPERTY(qreal manualMinimum READ manualMinimum WRITE setManualMinimum)
Q_PROPERTY(qreal manualMaximum READ manualMaximum WRITE setManualMaximum)
public: public:
AxisData(); enum AxisType {
AxisData(qreal minValue, qreal maxValue); YAxis = 0,
XAxis = 1
};
AxisData(AxisType type, QObject *parent = nullptr);
QString toString() const;
void copy(AxisData *other);
void update();
void update(qreal minValue, qreal maxValue);
void updateForDesignMode();
int segmentCount() const; int segmentCount() const;
@ -21,8 +40,36 @@ public:
qreal delta() const; qreal delta() const;
bool reverseDirection() const;
void setReverseDirection(bool newReverseDirection);
bool calculateAxisScale() const;
void setCalculateAxisScale(bool newCalculateAxisScale);
qreal manualMaximum() const;
void setManualMaximum(qreal newManualMaximum);
qreal manualMinimum() const;
void setManualMinimum(qreal newManualMinimum);
qreal manualStep() const;
void setManualStep(qreal newManualStep);
bool isMaximumAutomatic() const;
void setIsMaximumAutomatic(bool newIsMaximumAutomatic);
bool isMinimumAutomatic() const;
void setIsMinimumAutomatic(bool newIsMinimumAutomatic);
bool isStepAutomatic() const;
void setIsStepAutomatic(bool newIsStepAutomatic);
AxisType type() const;
private: private:
void calculateValuesAboveMax(qreal minValue, qreal maxValue, int segments); void calculateRoundedAxisScale();
void calculateSimpleAxisScale();
qreal calculateNewMinimum(qreal min, qreal step) const;
qreal calculateNewMaximum(qreal max, qreal step) const;
qreal m_rangeMin; qreal m_rangeMin;
qreal m_rangeMax; qreal m_rangeMax;
@ -31,6 +78,15 @@ private:
qreal m_step; qreal m_step;
qreal m_delta; qreal m_delta;
int m_segmentCount; int m_segmentCount;
bool m_calculateAxisScale;
bool m_reverseDirection;
qreal m_manualMaximum;
qreal m_manualMinimum;
qreal m_manualStep;
bool m_isMaximumAutomatic;
bool m_isMinimumAutomatic;
bool m_isStepAutomatic;
const AxisType m_type;
}; };
}; };

View File

@ -261,7 +261,6 @@ public:
void setAlternateBackgroundColor(const QColor &alternateBackgroundColor); void setAlternateBackgroundColor(const QColor &alternateBackgroundColor);
bool useAlternateBackgroundColor() const; bool useAlternateBackgroundColor() const;
void setUseAlternateBackgroundColor(bool useAlternateBackgroundColor); void setUseAlternateBackgroundColor(bool useAlternateBackgroundColor);
void replaceGroupsFunction(BandDesignIntf *band);
qreal bottomSpace() const; qreal bottomSpace() const;
void setBackgroundModeProperty(BGMode value); void setBackgroundModeProperty(BGMode value);
void setBackgroundOpacity(int value); void setBackgroundOpacity(int value);

View File

@ -1290,32 +1290,41 @@ void BaseDesignIntf::setItemPos(const QPointF &newPos)
} }
QWidget* findRootWidget(QWidget* widget){ QWidget* BaseDesignIntf::findRootWidget(QWidget* widget)
{
while (widget->parentWidget()) { while (widget->parentWidget()) {
widget = widget->parentWidget(); widget = widget->parentWidget();
} }
return widget; return widget;
} }
void BaseDesignIntf::showEditorDialog(){ void BaseDesignIntf::showDialog(QWidget *widget)
QWidget *editor = defaultEditor(); {
if (editor) { if (!widget) {
editor->setStyleSheet(findRootWidget(scene()->views().at(0))->styleSheet()); return;
QDialog* dialog = new QDialog(QApplication::activeWindow());
dialog->setAttribute(Qt::WA_DeleteOnClose);
#ifdef Q_OS_MAC
dialog->setWindowModality(Qt::WindowModal);
#else
dialog->setWindowModality(Qt::ApplicationModal);
#endif
dialog->setLayout(new QVBoxLayout());
dialog->resize(editor->size());
dialog->layout()->setContentsMargins(2,2,2,2);
dialog->layout()->addWidget(editor);
connect(editor,SIGNAL(destroyed()),dialog,SLOT(close()));
dialog->setWindowTitle(editor->windowTitle());
dialog->exec();
} }
widget->setStyleSheet(findRootWidget(scene()->views().at(0))->styleSheet());
QDialog *dialog = new QDialog(QApplication::activeWindow());
widget->setParent(dialog);
widget->setAttribute(Qt::WA_DeleteOnClose);
#ifdef Q_OS_MAC
dialog->setWindowModality(Qt::WindowModal);
#else
dialog->setWindowModality(Qt::ApplicationModal);
#endif
dialog->setLayout(new QVBoxLayout());
dialog->resize(widget->size());
dialog->layout()->setContentsMargins(2,2,2,2);
dialog->layout()->addWidget(widget);
connect(widget,SIGNAL(destroyed()),dialog,SLOT(close()));
dialog->setWindowTitle(widget->windowTitle());
dialog->exec();
dialog->deleteLater();
}
void BaseDesignIntf::showEditorDialog()
{
showDialog(defaultEditor());
} }
void BaseDesignIntf::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) void BaseDesignIntf::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
@ -1340,18 +1349,27 @@ void BaseDesignIntf::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
QAction* lockGeometryAction = menu.addAction(tr("Lock item geometry")); QAction* lockGeometryAction = menu.addAction(tr("Lock item geometry"));
lockGeometryAction->setCheckable(true); lockGeometryAction->setCheckable(true);
lockGeometryAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_L));
lockGeometryAction->setChecked(isGeometryLocked()); lockGeometryAction->setChecked(isGeometryLocked());
menu.addSeparator(); menu.addSeparator();
QAction* copyAction = menu.addAction(QIcon(":/report/images/copy"), tr("Copy")); QAction* copyAction = menu.addAction(QIcon(":/report/images/copy"), tr("Copy"));
copyAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_C)); QAction* cutAction = menu.addAction(QIcon(":/report/images/cut"), tr("Cut"));
QAction* cutAction = menu.addAction(QIcon(":/report/images/cut"), tr("Cut"));
cutAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_X));
QAction* pasteAction = menu.addAction(QIcon(":/report/images/paste"), tr("Paste")); QAction* pasteAction = menu.addAction(QIcon(":/report/images/paste"), tr("Paste"));
pasteAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_V));
pasteAction->setEnabled(false); pasteAction->setEnabled(false);
#if QT_VERSION >=QT_VERSION_CHECK(5,0,0)
lockGeometryAction->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_L));
copyAction->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_C));
cutAction->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_X));
pasteAction->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_V));
#else
lockGeometryAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_L));
copyAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_C));
cutAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_X));
pasteAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_V));
#endif
QClipboard *clipboard = QApplication::clipboard(); QClipboard *clipboard = QApplication::clipboard();
ItemsReaderIntf::Ptr reader = StringXMLreader::create(clipboard->text()); ItemsReaderIntf::Ptr reader = StringXMLreader::create(clipboard->text());
if (reader->first() && reader->itemType() == "Object"){ if (reader->first() && reader->itemType() == "Object"){

View File

@ -397,6 +397,9 @@ protected:
qreal calcAbsolutePosY(qreal currentOffset, BaseDesignIntf* item); qreal calcAbsolutePosY(qreal currentOffset, BaseDesignIntf* item);
qreal calcAbsolutePosX(qreal currentOffset, BaseDesignIntf* item); qreal calcAbsolutePosX(qreal currentOffset, BaseDesignIntf* item);
QWidget* findRootWidget(QWidget* widget);
void showDialog(QWidget *widget);
private: private:
int resizeDirectionFlags(QPointF position); int resizeDirectionFlags(QPointF position);
void moveSelectedItems(QPointF delta); void moveSelectedItems(QPointF delta);
@ -480,7 +483,7 @@ signals:
void propertyChanged(const QString& propertName, const QVariant& oldValue,const QVariant& newValue); void propertyChanged(const QString& propertName, const QVariant& oldValue,const QVariant& newValue);
void propertyObjectNameChanged(const QString& oldValue, const QString& newValue); void propertyObjectNameChanged(const QString& oldValue, const QString& newValue);
void propertyesChanged(QVector<QString> propertyNames); void propertyesChanged(QVector<QString> propertyNames);
void itemAlignChanged(BaseDesignIntf* item, const BaseDesignIntf::ItemAlign& oldValue, const BaseDesignIntf::ItemAlign& newValue); void itemAlignChanged(BaseDesignIntf* item, const ItemAlign& oldValue, const ItemAlign& newValue);
void itemVisibleHasChanged(BaseDesignIntf* item); void itemVisibleHasChanged(BaseDesignIntf* item);
void beforeRender(); void beforeRender();
void afterData(); void afterData();

View File

@ -85,7 +85,12 @@ bool QueryHolder::runQuery(IDataSource::DatasourceMode mode)
query.exec(); query.exec();
QSqlQueryModel *model = new QSqlQueryModel; QSqlQueryModel *model = new QSqlQueryModel;
#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
model->setQuery(std::move(query));
#else
model->setQuery(query); model->setQuery(query);
#endif
while (model->canFetchMore()) while (model->canFetchMore())
model->fetchMore(); model->fetchMore();

View File

@ -392,7 +392,13 @@ QSharedPointer<QAbstractItemModel>DataSourceManager::previewSQL(const QString &c
} }
query.exec(); query.exec();
#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
model->setQuery(std::move(query));
#else
model->setQuery(query); model->setQuery(query);
#endif
m_lastError = model->lastError().text(); m_lastError = model->lastError().text();
putError(m_lastError); putError(m_lastError);
if (model->query().isActive()) if (model->query().isActive())
@ -423,8 +429,8 @@ QString DataSourceManager::extractField(QString source)
} }
QString DataSourceManager::replaceVariables(QString value){ QString DataSourceManager::replaceVariables(QString value){
#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 3) #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 1)
QRegularExpression rx(Const::VARIABLE_RX); QRegularExpression rx = getVariableRegEx();
QRegularExpressionMatchIterator iter = rx.globalMatch(value); QRegularExpressionMatchIterator iter = rx.globalMatch(value);
qsizetype pos = 0; qsizetype pos = 0;
QString result; QString result;
@ -443,7 +449,6 @@ QString DataSourceManager::replaceVariables(QString value){
} }
result += value.mid(pos); result += value.mid(pos);
return result; return result;
// TODO: Qt6 port - done
#else #else
QRegExp rx(Const::VARIABLE_RX); QRegExp rx(Const::VARIABLE_RX);
@ -468,8 +473,8 @@ QString DataSourceManager::replaceVariables(QString value){
QString DataSourceManager::replaceVariables(QString query, QMap<QString,QString> &aliasesToParam) QString DataSourceManager::replaceVariables(QString query, QMap<QString,QString> &aliasesToParam)
{ {
#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 3) #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 1)
QRegularExpression rx(Const::VARIABLE_RX); QRegularExpression rx = getVariableRegEx();
int curentAliasIndex = 0; int curentAliasIndex = 0;
if (query.contains(rx)){ if (query.contains(rx)){
int pos = -1; int pos = -1;
@ -508,7 +513,6 @@ QString DataSourceManager::replaceVariables(QString query, QMap<QString,QString>
match = rx.match(query); match = rx.match(query);
} }
} }
// TODO: Qt6 port - done
#else #else
QRegExp rx(Const::VARIABLE_RX); QRegExp rx(Const::VARIABLE_RX);
int curentAliasIndex = 0; int curentAliasIndex = 0;
@ -553,9 +557,8 @@ QString DataSourceManager::replaceVariables(QString query, QMap<QString,QString>
QString DataSourceManager::replaceFields(QString query, QMap<QString,QString> &aliasesToParam, QString masterDatasource) QString DataSourceManager::replaceFields(QString query, QMap<QString,QString> &aliasesToParam, QString masterDatasource)
{ {
#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 3) #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 1)
QRegularExpression rx = getFieldRegEx();
QRegularExpression rx(Const::FIELD_RX);
int curentAliasIndex = 0; int curentAliasIndex = 0;
if (query.contains(rx)){ if (query.contains(rx)){
int pos = -1; int pos = -1;
@ -583,7 +586,6 @@ QString DataSourceManager::replaceFields(QString query, QMap<QString,QString> &a
match = rx.match(query); match = rx.match(query);
} }
} }
// TODO: Qt6 port - done
#else #else
QRegExp rx(Const::FIELD_RX); QRegExp rx(Const::FIELD_RX);
if (query.contains(rx)){ if (query.contains(rx)){
@ -1498,7 +1500,7 @@ void DataSourceManager::invalidateQueriesContainsVariable(const QString& variabl
#if (QT_VERSION < QT_VERSION_CHECK(5, 15, 1)) #if (QT_VERSION < QT_VERSION_CHECK(5, 15, 1))
QRegExp rx(QString(Const::NAMED_VARIABLE_RX).arg(variableName)); QRegExp rx(QString(Const::NAMED_VARIABLE_RX).arg(variableName));
#else #else
QRegularExpression rx(QString(Const::NAMED_VARIABLE_RX).arg(variableName)); QRegularExpression rx = getNamedVariableRegEx(variableName);
#endif #endif
if (holder->queryText().contains(rx)){ if (holder->queryText().contains(rx)){
holder->invalidate(designTime() ? IDataSource::DESIGN_MODE : IDataSource::RENDER_MODE); holder->invalidate(designTime() ? IDataSource::DESIGN_MODE : IDataSource::RENDER_MODE);

View File

@ -169,7 +169,7 @@ void initReportItems(){
#ifdef HAVE_SVG #ifdef HAVE_SVG
DesignElementsFactory::instance().registerCreator( DesignElementsFactory::instance().registerCreator(
"BarcodeItem", "SVGItem",
LimeReport::ItemAttribs(QObject::tr("SVG Item"),"Item"), LimeReport::ItemAttribs(QObject::tr("SVG Item"),"Item"),
createSVGItem createSVGItem
); );

View File

@ -67,7 +67,7 @@ QString replaceHTMLSymbols(const QString &value)
return result; return result;
} }
#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 3) #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 1)
QVector<QString> normalizeCaptures(const QRegularExpressionMatch& reg){ QVector<QString> normalizeCaptures(const QRegularExpressionMatch& reg){
#else #else
QVector<QString> normalizeCaptures(const QRegExp& reg){ QVector<QString> normalizeCaptures(const QRegExp& reg){
@ -93,4 +93,53 @@ ReportError::ReportError(const QString& message):std::runtime_error(message.toSt
IExternalPainter::~IExternalPainter(){} IExternalPainter::~IExternalPainter(){}
IPainterProxy::~IPainterProxy(){} IPainterProxy::~IPainterProxy(){}
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 1)
QRegularExpression getRegEx(QString expression){
return QRegularExpression(expression, QRegularExpression::DotMatchesEverythingOption);
}
QRegularExpression getVariableRegEx(){
return QRegularExpression(
Const::VARIABLE_RX,
QRegularExpression::DotMatchesEverythingOption |
QRegularExpression::CaseInsensitiveOption
);
}
QRegularExpression getFieldRegEx(){
return QRegularExpression(
Const::FIELD_RX,
QRegularExpression::DotMatchesEverythingOption |
QRegularExpression::CaseInsensitiveOption
);
}
QRegularExpression getScriptRegEx(){
return QRegularExpression(
Const::SCRIPT_RX,
QRegularExpression::DotMatchesEverythingOption |
QRegularExpression::CaseInsensitiveOption
);
}
QRegularExpression getGroupFunctionRegEx(QString functionName){
return QRegularExpression(
QString(Const::GROUP_FUNCTION_RX).arg(functionName),
QRegularExpression::DotMatchesEverythingOption |
QRegularExpression::InvertedGreedinessOption
);
}
QRegularExpression getGroupFunctionNameRegEx(QString functionName){
return QRegularExpression(
QString(Const::GROUP_FUNCTION_NAME_RX).arg(functionName),
QRegularExpression::DotMatchesEverythingOption |
QRegularExpression::InvertedGreedinessOption
);
}
QRegularExpression getNamedVariableRegEx(QString variableName){
return QRegularExpression(
QString(Const::NAMED_VARIABLE_RX).arg(variableName),
QRegularExpression::DotMatchesEverythingOption
);
}
#endif
} //namespace LimeReport } //namespace LimeReport

View File

@ -104,7 +104,7 @@ namespace Const{
QString extractClassName(QString className); QString extractClassName(QString className);
QString escapeSimbols(const QString& value); QString escapeSimbols(const QString& value);
QString replaceHTMLSymbols(const QString &value); QString replaceHTMLSymbols(const QString &value);
#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 3) #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 1)
QVector<QString> normalizeCaptures(const QRegularExpressionMatch &reg); QVector<QString> normalizeCaptures(const QRegularExpressionMatch &reg);
#else #else
QVector<QString> normalizeCaptures(const QRegExp &reg); QVector<QString> normalizeCaptures(const QRegExp &reg);
@ -157,6 +157,16 @@ namespace Const{
#else #else
typedef QStyleOptionViewItem StyleOptionViewItem; typedef QStyleOptionViewItem StyleOptionViewItem;
#endif #endif
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 1)
QRegularExpression getRegEx(QString expression);
QRegularExpression getVariableRegEx();
QRegularExpression getFieldRegEx();
QRegularExpression getScriptRegEx();
QRegularExpression getGroupFunctionRegEx(QString functionName);
QRegularExpression getGroupFunctionNameRegEx(QString functionName);
QRegularExpression getNamedVariableRegEx(QString variableName);
#endif
class Enums class Enums
{ {

View File

@ -48,8 +48,8 @@ void GroupFunction::slotBandRendered(BandDesignIntf *band)
QRegExp rxField(Const::FIELD_RX); QRegExp rxField(Const::FIELD_RX);
QRegExp rxVar(Const::VARIABLE_RX); QRegExp rxVar(Const::VARIABLE_RX);
#else #else
QRegularExpression rxField(Const::FIELD_RX); QRegularExpression rxField = getFieldRegEx();
QRegularExpression rxVar(Const::VARIABLE_RX); QRegularExpression rxVar = getVariableRegEx();
#endif #endif
switch (m_dataType){ switch (m_dataType){
@ -154,9 +154,9 @@ GroupFunction::GroupFunction(const QString &expression, const QString &dataBandN
QRegExp rxVariable(Const::VARIABLE_RX,Qt::CaseInsensitive); QRegExp rxVariable(Const::VARIABLE_RX,Qt::CaseInsensitive);
QRegExp rxScript(Const::SCRIPT_RX,Qt::CaseInsensitive); QRegExp rxScript(Const::SCRIPT_RX,Qt::CaseInsensitive);
#else #else
QRegularExpression rxField(Const::FIELD_RX, QRegularExpression::CaseInsensitiveOption); QRegularExpression rxField = getFieldRegEx();
QRegularExpression rxVariable(Const::VARIABLE_RX, QRegularExpression::CaseInsensitiveOption); QRegularExpression rxVariable = getVariableRegEx();
QRegularExpression rxScript(Const::SCRIPT_RX, QRegularExpression::CaseInsensitiveOption); QRegularExpression rxScript = getScriptRegEx();
#endif #endif
#if (QT_VERSION < QT_VERSION_CHECK(5, 15, 1)) #if (QT_VERSION < QT_VERSION_CHECK(5, 15, 1))
if (rxScript.indexIn(expression) != -1){ if (rxScript.indexIn(expression) != -1){

View File

@ -97,6 +97,7 @@ public:
LayoutDesignIntf(const QString& xmlTypeName, QObject* owner = 0,QGraphicsItem* parent = 0): LayoutDesignIntf(const QString& xmlTypeName, QObject* owner = 0,QGraphicsItem* parent = 0):
ItemDesignIntf(xmlTypeName,owner,parent){} ItemDesignIntf(xmlTypeName,owner,parent){}
virtual void addChild(BaseDesignIntf *item,bool updateSize=true) = 0; virtual void addChild(BaseDesignIntf *item,bool updateSize=true) = 0;
virtual void removeChild(BaseDesignIntf *item) = 0;
virtual void restoreChild(BaseDesignIntf *item) = 0; virtual void restoreChild(BaseDesignIntf *item) = 0;
virtual int childrenCount() = 0; virtual int childrenCount() = 0;
friend class BaseDesignIntf; friend class BaseDesignIntf;

View File

@ -554,17 +554,16 @@ CommandIf::Ptr PageDesignIntf::removeReportItemCommand(BaseDesignIntf *item){
CommandIf::Ptr command = createBandDeleteCommand(this,band); CommandIf::Ptr command = createBandDeleteCommand(this,band);
return command; return command;
} else { } else {
LayoutDesignIntf* layout = dynamic_cast<LayoutDesignIntf*>(item->parent()); LayoutDesignIntf* parentLayout = dynamic_cast<LayoutDesignIntf*>(item->parent());
if (layout && (layout->childrenCount()==2)){ LayoutDesignIntf* layout = dynamic_cast<LayoutDesignIntf*>(item);
// When removing layout child all his children will be assigned to parent
if (!layout && parentLayout && (parentLayout->childrenCount() == 2)) {
CommandGroup::Ptr commandGroup = CommandGroup::create(); CommandGroup::Ptr commandGroup = CommandGroup::create();
commandGroup->addCommand(DeleteLayoutCommand::create(this, layout),false); commandGroup->addCommand(DeleteLayoutCommand::create(this, parentLayout),false);
commandGroup->addCommand(DeleteItemCommand::create(this,item),false); commandGroup->addCommand(DeleteItemCommand::create(this,item),false);
return commandGroup; return commandGroup;
} else { } else {
CommandIf::Ptr command = (dynamic_cast<LayoutDesignIntf*>(item))? return layout ? DeleteLayoutCommand::create(this, layout) : DeleteItemCommand::create(this, item) ;
DeleteLayoutCommand::create(this, dynamic_cast<LayoutDesignIntf*>(item)) :
DeleteItemCommand::create(this, item) ;
return command;
} }
} }
} }
@ -727,7 +726,6 @@ ReportEnginePrivate *PageDesignIntf::reportEditor()
void PageDesignIntf::dragEnterEvent(QGraphicsSceneDragDropEvent *event) void PageDesignIntf::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
{ {
if (!event->mimeData()->text().isEmpty()){ if (!event->mimeData()->text().isEmpty()){
event->setDropAction(Qt::CopyAction); event->setDropAction(Qt::CopyAction);
event->accept(); event->accept();
@ -756,7 +754,7 @@ void PageDesignIntf::dropEvent(QGraphicsSceneDragDropEvent* event)
#if (QT_VERSION < QT_VERSION_CHECK(5, 15, 1)) #if (QT_VERSION < QT_VERSION_CHECK(5, 15, 1))
if (isVar) data = data.remove(QRegExp(" \\[.*\\]")); if (isVar) data = data.remove(QRegExp(" \\[.*\\]"));
#else #else
if (isVar) data = data.remove(QRegularExpression(" \\[.*\\]")); if (isVar) data = data.remove(QRegularExpression(" \\[.*\\]", QRegularExpression::DotMatchesEverythingOption));
#endif #endif
ti->setContent(data); ti->setContent(data);
if (!isVar){ if (!isVar){
@ -768,7 +766,7 @@ void PageDesignIntf::dropEvent(QGraphicsSceneDragDropEvent* event)
parentBand->setProperty("datasource",dataSource.cap(1)); parentBand->setProperty("datasource",dataSource.cap(1));
} }
#else #else
QRegularExpression dataSource("(?:\\$D\\{\\s*(.*)\\..*\\})"); QRegularExpression dataSource("(?:\\$D\\{\\s*(.*)\\..*\\})", QRegularExpression::DotMatchesEverythingOption);
QRegularExpressionMatch match = dataSource.match(data); QRegularExpressionMatch match = dataSource.match(data);
if(match.hasMatch()){ if(match.hasMatch()){
parentBand->setProperty("datasource", match.captured(1)); parentBand->setProperty("datasource", match.captured(1));
@ -2008,6 +2006,9 @@ CommandIf::Ptr DeleteLayoutCommand::create(PageDesignIntf *page, LayoutDesignInt
foreach (BaseDesignIntf* childItem, item->childBaseItems()){ foreach (BaseDesignIntf* childItem, item->childBaseItems()){
command->m_childItems.append(childItem->objectName()); command->m_childItems.append(childItem->objectName());
} }
LayoutDesignIntf* layout = dynamic_cast<LayoutDesignIntf*>(item->parent());
if (layout)
command->m_layoutName = layout->objectName();
return CommandIf::Ptr(command); return CommandIf::Ptr(command);
} }
@ -2032,9 +2033,20 @@ void DeleteLayoutCommand::undoIt()
BaseDesignIntf *item = page()->addReportItem(m_itemType); BaseDesignIntf *item = page()->addReportItem(m_itemType);
ItemsReaderIntf::Ptr reader = StringXMLreader::create(m_itemXML); ItemsReaderIntf::Ptr reader = StringXMLreader::create(m_itemXML);
if (reader->first()) reader->readItem(item); if (reader->first()) reader->readItem(item);
if (!m_layoutName.isEmpty()) {
LayoutDesignIntf* layout = dynamic_cast<LayoutDesignIntf*>(page()->reportItemByName(m_layoutName));
if (layout){
layout->restoreChild(item);
}
page()->emitRegisterdItem(item);
}
foreach(QString ci, m_childItems){ foreach(QString ci, m_childItems){
BaseDesignIntf* ri = page()->reportItemByName(ci); BaseDesignIntf* ri = page()->reportItemByName(ci);
if (ri){ if (ri){
LayoutDesignIntf* parentLayout = dynamic_cast<LayoutDesignIntf*>(ri->parent());
if (parentLayout) {
parentLayout->removeChild(ri);
}
dynamic_cast<LayoutDesignIntf*>(item)->addChild(ri); dynamic_cast<LayoutDesignIntf*>(item)->addChild(ri);
} }
page()->emitRegisterdItem(item); page()->emitRegisterdItem(item);

View File

@ -415,6 +415,7 @@ namespace LimeReport {
void setItem(BaseDesignIntf* item); void setItem(BaseDesignIntf* item);
private: private:
QStringList m_childItems; QStringList m_childItems;
QString m_layoutName;
QString m_itemXML; QString m_itemXML;
QString m_itemType; QString m_itemType;
QString m_itemName; QString m_itemName;

View File

@ -492,7 +492,7 @@ bool ReportEnginePrivate::showPreviewWindow(ReportPages pages, PreviewHints hint
Q_UNUSED(printer) Q_UNUSED(printer)
if (pages.count()>0){ if (pages.count()>0){
Q_Q(ReportEngine); Q_Q(ReportEngine);
PreviewReportWindow* w = new PreviewReportWindow(q, 0, settings()); PreviewReportWindow* w = new PreviewReportWindow(q, QApplication::activeWindow(), settings());
w->setWindowFlags(Qt::Dialog|Qt::WindowMaximizeButtonHint|Qt::WindowCloseButtonHint| Qt::WindowMinMaxButtonsHint); w->setWindowFlags(Qt::Dialog|Qt::WindowMaximizeButtonHint|Qt::WindowCloseButtonHint| Qt::WindowMinMaxButtonsHint);
w->setAttribute(Qt::WA_DeleteOnClose,true); w->setAttribute(Qt::WA_DeleteOnClose,true);
w->setWindowModality(Qt::ApplicationModal); w->setWindowModality(Qt::ApplicationModal);

View File

@ -196,13 +196,11 @@ void ReportRender::analizeItem(ContentItemDesignIntf* contentItem, BandDesignInt
QString content = contentItem->content(); QString content = contentItem->content();
QVector<QString> functions; QVector<QString> functions;
foreach(const QString &functionName, m_datasources->groupFunctionNames()){ foreach(const QString &functionName, m_datasources->groupFunctionNames()){
#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 3) #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 1)
QRegularExpression rx(QString(Const::GROUP_FUNCTION_RX).arg(functionName)); QRegularExpression rx = getGroupFunctionRegEx(functionName);
rx.setPatternOptions(rx.InvertedGreedinessOption);
if(content.indexOf(rx)>=0){ if(content.indexOf(rx)>=0){
functions.append(functionName); functions.append(functionName);
} }
// TODO: Qt6 port - done
#else #else
QRegExp rx(QString(Const::GROUP_FUNCTION_RX).arg(functionName)); QRegExp rx(QString(Const::GROUP_FUNCTION_RX).arg(functionName));
rx.setMinimal(true); rx.setMinimal(true);
@ -368,13 +366,11 @@ void ReportRender::clearPageMap()
bool checkContentItem(ContentItemDesignIntf* item, DataSourceManager* datasources){ bool checkContentItem(ContentItemDesignIntf* item, DataSourceManager* datasources){
QString content = item->content(); QString content = item->content();
foreach(QString functionName, datasources->groupFunctionNames()){ foreach(QString functionName, datasources->groupFunctionNames()){
#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 3) #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 1)
QRegularExpression rx(QString(Const::GROUP_FUNCTION_RX).arg(functionName)); QRegularExpression rx = getGroupFunctionRegEx(functionName);
rx.setPatternOptions(rx.InvertedGreedinessOption);
if(content.indexOf(rx)>=0){ if(content.indexOf(rx)>=0){
return true; return true;
} }
// TODO: Qt6 port - done
#else #else
QRegExp rx(QString(Const::GROUP_FUNCTION_RX).arg(functionName)); QRegExp rx(QString(Const::GROUP_FUNCTION_RX).arg(functionName));
if (rx.indexIn(content)>=0){ if (rx.indexIn(content)>=0){
@ -400,16 +396,14 @@ bool ReportRender::containsGroupFunctions(BaseDesignIntf *container){
} }
void ReportRender::extractGroupFuntionsFromItem(ContentItemDesignIntf* contentItem, BandDesignIntf* band){ void ReportRender::extractGroupFuntionsFromItem(ContentItemDesignIntf* contentItem, BandDesignIntf* band){
#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 3) #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 1)
if ( contentItem && contentItem->content().contains(getScriptRegEx())){
if ( contentItem && contentItem->content().contains(QRegularExpression("\\$S\\s*\\{.*\\}"))){
foreach(const QString &functionName, m_datasources->groupFunctionNames()){ foreach(const QString &functionName, m_datasources->groupFunctionNames()){
QRegularExpression rx(QString(Const::GROUP_FUNCTION_RX).arg(functionName));
rx.setPatternOptions(rx.InvertedGreedinessOption);
QRegularExpression rxName(QString(Const::GROUP_FUNCTION_NAME_RX).arg(functionName));
rxName.setPatternOptions(rx.InvertedGreedinessOption);
QRegularExpression rx = getGroupFunctionRegEx(functionName);
QRegularExpression rxName = getGroupFunctionNameRegEx(functionName);
QRegularExpressionMatch match = rx.match(contentItem->content()); QRegularExpressionMatch match = rx.match(contentItem->content());
if (match.hasMatch()){ if (match.hasMatch()){
QRegularExpressionMatchIterator iter = rx.globalMatch(contentItem->content()); QRegularExpressionMatchIterator iter = rx.globalMatch(contentItem->content());
@ -437,31 +431,7 @@ void ReportRender::extractGroupFuntionsFromItem(ContentItemDesignIntf* contentIt
} }
} }
} }
// int pos = 0;
// while ( (pos = match.capturedStart()) != -1){
// QVector<QString> captures = normalizeCaptures(match);
// if (captures.size() >= 3){
// int dsIndex = captures.size() == 3 ? Const::DATASOURCE_INDEX - 1 : Const::DATASOURCE_INDEX;
// BandDesignIntf* dataBand = m_patternPageItem->bandByName(captures.at(dsIndex));
// if (dataBand){
// GroupFunction* gf = datasources()->addGroupFunction(
// functionName, captures.at(Const::VALUE_INDEX), band->objectName(), dataBand->objectName()
// );
// if (gf){
// connect(dataBand, SIGNAL(bandRendered(BandDesignIntf*)),
// gf, SLOT(slotBandRendered(BandDesignIntf*)));
// connect(dataBand, SIGNAL(bandReRendered(BandDesignIntf*, BandDesignIntf*)),
// gf, SLOT(slotBandReRendered(BandDesignIntf*, BandDesignIntf*)));
// }
// } else {
// GroupFunction* gf = datasources()->addGroupFunction(
// functionName, captures.at(Const::VALUE_INDEX), band->objectName(), captures.at(dsIndex)
// );
// gf->setInvalid(tr("Databand \"%1\" not found").arg(captures.at(dsIndex)));
// }
// }
// match = rx.match(contentItem->content(), pos + match.capturedLength());
// }
} else if (contentItem->content().indexOf(rxName)>=0){ } else if (contentItem->content().indexOf(rxName)>=0){
match = rxName.match(contentItem->content()); match = rxName.match(contentItem->content());
GroupFunction* gf = datasources()->addGroupFunction(functionName, match.captured(1), band->objectName(), ""); GroupFunction* gf = datasources()->addGroupFunction(functionName, match.captured(1), band->objectName(), "");
@ -470,7 +440,6 @@ void ReportRender::extractGroupFuntionsFromItem(ContentItemDesignIntf* contentIt
} }
} }
// TODO: Qt6 port - done
#else #else
if ( contentItem && contentItem->content().contains(QRegExp("\\$S\\s*\\{.*\\}"))){ if ( contentItem && contentItem->content().contains(QRegExp("\\$S\\s*\\{.*\\}"))){
foreach(const QString &functionName, m_datasources->groupFunctionNames()){ foreach(const QString &functionName, m_datasources->groupFunctionNames()){
@ -529,10 +498,8 @@ void ReportRender::replaceGroupFunctionsInItem(ContentItemDesignIntf* contentIte
if (m_groupfunctionItems.contains(contentItem->patternName())){ if (m_groupfunctionItems.contains(contentItem->patternName())){
QString content = contentItem->content(); QString content = contentItem->content();
foreach(QString functionName, m_groupfunctionItems.value(contentItem->patternName())){ foreach(QString functionName, m_groupfunctionItems.value(contentItem->patternName())){
#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 3) #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 1)
QRegularExpression rx = getGroupFunctionRegEx(functionName);
QRegularExpression rx(QString(Const::GROUP_FUNCTION_RX).arg(functionName));
rx.setPatternOptions(rx.InvertedGreedinessOption);
QRegularExpressionMatch match = rx.match(content); QRegularExpressionMatch match = rx.match(content);
if (match.capturedStart() != -1){ if (match.capturedStart() != -1){
@ -556,7 +523,6 @@ void ReportRender::replaceGroupFunctionsInItem(ContentItemDesignIntf* contentIte
match = rx.match(content, pos + match.capturedLength()); match = rx.match(content, pos + match.capturedLength());
} }
} }
// TODO: Qt6 port - done
#else #else
QRegExp rx(QString(Const::GROUP_FUNCTION_RX).arg(functionName)); QRegExp rx(QString(Const::GROUP_FUNCTION_RX).arg(functionName));
rx.setMinimal(true); rx.setMinimal(true);

View File

@ -398,7 +398,7 @@ QString ScriptEngineManager::expandUserVariables(QString context, RenderPass /*
} }
return context; return context;
#else #else
QRegularExpression rx(Const::VARIABLE_RX); QRegularExpression rx = getVariableRegEx();
if (context.contains(rx)){ if (context.contains(rx)){
int pos = 0; int pos = 0;
QRegularExpressionMatch match = rx.match(context, pos); QRegularExpressionMatch match = rx.match(context, pos);
@ -504,8 +504,7 @@ QString ScriptEngineManager::expandDataFields(QString context, ExpandType expand
return context; return context;
#else #else
QRegularExpression rx(Const::FIELD_RX); QRegularExpression rx = getFieldRegEx();
if (context.contains(rx)){ if (context.contains(rx)){
QRegularExpressionMatch match = rx.match(context); QRegularExpressionMatch match = rx.match(context);
while (match.hasMatch()){ while (match.hasMatch()){
@ -520,17 +519,32 @@ QString ScriptEngineManager::expandDataFields(QString context, ExpandType expand
fieldValue="\"\""; fieldValue="\"\"";
} else { } else {
fieldValue = escapeSimbols(varValue.toString()); fieldValue = escapeSimbols(varValue.toString());
switch (dataManager()->fieldData(field).type()) { //TODO: Migrate to QMetaType
case QVariant::Char: #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
case QVariant::String: switch (dataManager()->fieldData(field).typeId()) {
case QVariant::StringList: case QMetaType::QChar:
case QVariant::Date: case QMetaType::QString:
case QVariant::DateTime: case QMetaType::QStringList:
fieldValue = "\""+fieldValue+"\""; case QMetaType::QDate:
break; case QMetaType::QDateTime:
default: fieldValue = "\""+fieldValue+"\"";
break; break;
default:
break;
} }
#else
switch (dataManager()->fieldData(field).type()) {
case QVariant::Char:
case QVariant::String:
case QVariant::StringList:
case QVariant::Date:
case QVariant::DateTime:
fieldValue = "\""+fieldValue+"\"";
break;
default:
break;
}
#endif
} }
} else { } else {
if (expandType == ReplaceHTMLSymbols) if (expandType == ReplaceHTMLSymbols)
@ -567,8 +581,7 @@ QString ScriptEngineManager::expandScripts(QString context, QVariant& varValue,
if (context.contains(rx)){ if (context.contains(rx)){
#else #else
QRegularExpression rx(Const::SCRIPT_RX, QRegularExpression::DotMatchesEverythingOption); QRegularExpression rx = getScriptRegEx();
if(context.contains(rx)){ if(context.contains(rx)){
#endif #endif
@ -636,8 +649,8 @@ QVariant ScriptEngineManager::evaluateScript(const QString& script){
QVariant varValue; QVariant varValue;
if (script.contains(rx)){ if (script.contains(rx)){
#else #else
QRegularExpression rx(Const::SCRIPT_RX); QRegularExpression rx = getScriptRegEx();
QVariant varValue; QVariant varValue;
if (script.contains(rx)){ if (script.contains(rx)){
@ -1110,7 +1123,7 @@ bool ScriptExtractor::parse()
bool ScriptExtractor::parse(int &curPos, const State& state, ScriptNode::Ptr scriptNode) bool ScriptExtractor::parse(int &curPos, const State& state, ScriptNode::Ptr scriptNode)
{ {
while (curPos<m_context.length()){ while (curPos < m_context.length()){
switch (state) { switch (state) {
case OpenBracketFound: case OpenBracketFound:
if (m_context[curPos]=='}'){ if (m_context[curPos]=='}'){
@ -1680,11 +1693,10 @@ QVariant ScriptFunctionsManager::calcGroupFunction(const QString &name, const QS
if (gf){ if (gf){
if (gf->isValid()){ if (gf->isValid()){
return gf->calculate(pageItem); return gf->calculate(pageItem);
}else{ } else{
return gf->error(); return gf->error();
} }
} } else {
else {
return QString(QObject::tr("Function %1 not found or have wrong arguments").arg(name)); return QString(QObject::tr("Function %1 not found or have wrong arguments").arg(name));
} }
} else { } else {

View File

@ -401,7 +401,11 @@ private:
class ScriptNode{ class ScriptNode{
public: public:
typedef QSharedPointer<ScriptNode> Ptr; typedef QSharedPointer<ScriptNode> Ptr;
QString body(){return m_body;} QString body(){
if (m_body.isEmpty() && m_children.count() > 0)
return m_children.at(0)->body();
return m_body;
}
void setBody(const QString& body){ m_body = body;} void setBody(const QString& body){ m_body = body;}
void setStartLex(const QString startLex){ m_startLex = startLex;} void setStartLex(const QString startLex){ m_startLex = startLex;}
QString script(){return m_startLex + m_body + '}';} QString script(){return m_startLex + m_body + '}';}

View File

@ -56,7 +56,12 @@ ComboBoxEditor::ComboBoxEditor(QWidget *parent, bool clearable) :
connect(m_buttonClear,SIGNAL(clicked()),this,SLOT(slotClearButtonClicked())); connect(m_buttonClear,SIGNAL(clicked()),this,SLOT(slotClearButtonClicked()));
} }
connect(m_comboBox,SIGNAL(currentIndexChanged(QString)),this,SLOT(slotCurrentIndexChanged(QString))); #if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
connect(m_comboBox, SIGNAL(currentTextChanged(QString)), this, SLOT(slotCurrentIndexChanged(QString)));
#else
connect(m_comboBox, SIGNAL(currentIndexChanged(QString)), this, SLOT(slotCurrentIndexChanged(QString)));
#endif
m_comboBox->installEventFilter(this); m_comboBox->installEventFilter(this);
QHBoxLayout *layout = new QHBoxLayout(this); QHBoxLayout *layout = new QHBoxLayout(this);
layout->addWidget(m_comboBox); layout->addWidget(m_comboBox);

View File

@ -222,6 +222,10 @@ void QObjectPropertyModel::setMultiObjects(QList<QObject *>* list)
m_objects.clear(); m_objects.clear();
submit(); submit();
if (list->isEmpty()) {
return;
}
if (!list->contains(m_object)){ if (!list->contains(m_object)){
m_object=list->at(0); m_object=list->at(0);
list->removeAt(0); list->removeAt(0);

View File

@ -0,0 +1,57 @@
#include "lraxispropitem.h"
#include <QToolButton>
#include <lrchartitemeditor.h>
#include <lrpagedesignintf.h>
#include <lrreportengine_p.h>
namespace {
LimeReport::ObjectPropItem * createYAxisPropItem(
QObject *object, LimeReport::ObjectPropItem::ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& data, LimeReport::ObjectPropItem* parent, bool readonly)
{
return new LimeReport::AxisPropItem(object, objects, name, displayName, data, parent, readonly, false);
}
LimeReport::ObjectPropItem * createXAxisPropItem(
QObject *object, LimeReport::ObjectPropItem::ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& data, LimeReport::ObjectPropItem* parent, bool readonly)
{
return new LimeReport::AxisPropItem(object, objects, name, displayName, data, parent, readonly, true);
}
bool VARIABLE_IS_NOT_USED registredXAxisProp = LimeReport::ObjectPropFactory::instance().registerCreator(LimeReport::APropIdent("xAxisSettings", "LimeReport::ChartItem"), QObject::tr("X axis"), createXAxisPropItem);
bool VARIABLE_IS_NOT_USED registredYAxisProp = LimeReport::ObjectPropFactory::instance().registerCreator(LimeReport::APropIdent("yAxisSettings", "LimeReport::ChartItem"), QObject::tr("Y axis"), createYAxisPropItem);
}
namespace LimeReport {
QWidget *AxisPropItem::createProperyEditor(QWidget *parent) const
{
return new AxisPropEditor(qobject_cast<ChartItem*>(object()), m_isXAxis, parent);
}
QString AxisPropItem::displayValue() const
{
return QObject::tr("Axis");
}
AxisPropEditor::AxisPropEditor(ChartItem *chart, bool isXAxis, QWidget *parent)
: QWidget(parent), m_button(new QPushButton(this)), m_chart(chart), m_isXAxis(isXAxis)
{
m_button->setText("...");
QHBoxLayout* layout = new QHBoxLayout(this);
layout->addWidget(m_button);
layout->setSpacing(1);
layout->setContentsMargins(1,0,1,1);
setLayout(layout);
setFocusProxy(m_button);
setAutoFillBackground(true);
connect(m_button,SIGNAL(clicked()),this,SLOT(slotButtonClicked()));
}
void AxisPropEditor::slotButtonClicked()
{
m_chart->showAxisEditorDialog(m_isXAxis);
emit editingFinished();
}
}

View File

@ -0,0 +1,43 @@
#ifndef AXISPROPITEM_H
#define AXISPROPITEM_H
#include <QPushButton>
#include <QHBoxLayout>
#include <lrobjectpropitem.h>
#include <lrchartitem.h>
namespace LimeReport {
class AxisPropEditor : public QWidget
{
Q_OBJECT
public:
AxisPropEditor(ChartItem* chart, bool isXAxis, QWidget *parent = 0);
signals:
void editingFinished();
private slots:
void slotButtonClicked();
private:
QPushButton* m_button;
ChartItem* m_chart;
bool m_isXAxis;
};
class AxisPropItem: public LimeReport::ObjectPropItem
{
Q_OBJECT
public:
AxisPropItem():ObjectPropItem(){}
AxisPropItem(QObject* object, ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& value, ObjectPropItem* parent, bool readonly, bool isXAxis)
:ObjectPropItem(object, objects, name, displayName, value, parent, readonly), m_isXAxis(isXAxis){}
QWidget* createProperyEditor(QWidget *parent) const;
QString displayValue() const;
private:
bool m_isXAxis = false;
};
} // namespace LimeReport
#endif // AXISPROPITEM_H

View File

@ -85,6 +85,17 @@ LimeReport::RectPropItem::RectPropItem(QObject *object, ObjectsList* objects, co
QString LimeReport::RectPropItem::displayValue() const QString LimeReport::RectPropItem::displayValue() const
{ {
//TODO: Migrate to QMetaType
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
switch(propertyValue().typeId()){
case QMetaType::QRect:
return rectToString(propertyValue().toRect());
case QMetaType::QRectF:
return rectToString(propertyValue().toRect());
default :
return ObjectPropItem::displayValue();
}
#else
switch(propertyValue().type()){ switch(propertyValue().type()){
case QVariant::Rect: case QVariant::Rect:
return rectToString(propertyValue().toRect()); return rectToString(propertyValue().toRect());
@ -93,6 +104,7 @@ QString LimeReport::RectPropItem::displayValue() const
default : default :
return ObjectPropItem::displayValue(); return ObjectPropItem::displayValue();
} }
#endif
} }
LimeReport::RectUnitPropItem::RectUnitPropItem(QObject *object, ObjectsList* objects, const QString &name, const QString &displayName, const QVariant &value, ObjectPropItem *parent, bool /*readonly*/): LimeReport::RectUnitPropItem::RectUnitPropItem(QObject *object, ObjectsList* objects, const QString &name, const QString &displayName, const QVariant &value, ObjectPropItem *parent, bool /*readonly*/):

View File

@ -193,13 +193,23 @@ bool XMLWriter::enumOrFlag(QString name, QObject *item)
bool XMLWriter::isCollection(QString propertyName, QObject* item) bool XMLWriter::isCollection(QString propertyName, QObject* item)
{ {
QMetaProperty prop=item->metaObject()->property(item->metaObject()->indexOfProperty(propertyName.toLatin1())); QMetaProperty prop=item->metaObject()->property(item->metaObject()->indexOfProperty(propertyName.toLatin1()));
return QMetaType::type(prop.typeName())==COLLECTION_TYPE_ID; //TODO: Migrate to QMetaType
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
return QMetaType::fromName(prop.typeName()).id() == COLLECTION_TYPE_ID;
#else
return QMetaType::type(prop.typeName()) == COLLECTION_TYPE_ID;
#endif
} }
bool XMLWriter::isTranslation(QString propertyName, QObject* item) bool XMLWriter::isTranslation(QString propertyName, QObject* item)
{ {
QMetaProperty prop=item->metaObject()->property(item->metaObject()->indexOfProperty(propertyName.toLatin1())); QMetaProperty prop=item->metaObject()->property(item->metaObject()->indexOfProperty(propertyName.toLatin1()));
return QMetaType::type(prop.typeName())==TRANSLATION_TYPE_ID; //TODO: Migrate to QMetaType
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
return QMetaType::fromName(prop.typeName()).id() == TRANSLATION_TYPE_ID;
#else
return QMetaType::type(prop.typeName()) == TRANSLATION_TYPE_ID;
#endif
} }
void XMLWriter::saveCollection(QString propertyName, QObject *item, QDomElement *node) void XMLWriter::saveCollection(QString propertyName, QObject *item, QDomElement *node)
@ -254,7 +264,13 @@ void XMLWriter::saveTranslation(QString propertyName, QObject* item, QDomElement
bool XMLWriter::isQObject(QString propertyName, QObject *item) bool XMLWriter::isQObject(QString propertyName, QObject *item)
{ {
QMetaProperty prop=item->metaObject()->property(item->metaObject()->indexOfProperty(propertyName.toLatin1())); QMetaProperty prop=item->metaObject()->property(item->metaObject()->indexOfProperty(propertyName.toLatin1()));
return QMetaType::type(prop.typeName())==QMetaType::QObjectStar; //TODO: Migrate to QMetaType
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
return QMetaType::fromName(prop.typeName()).id() == QMetaType::QObjectStar;
#else
return QMetaType::type(prop.typeName()) == QMetaType::QObjectStar;
#endif
} }
bool XMLWriter::replaceNode(QDomElement node, QObject* item) bool XMLWriter::replaceNode(QDomElement node, QObject* item)

View File

@ -8,18 +8,20 @@ namespace Ui {
class LanguageSelectDialog; class LanguageSelectDialog;
} }
class LanguageSelectDialog : public QDialog class LanguageSelectDialog : public QDialog {
{
Q_OBJECT Q_OBJECT
public: public:
explicit LanguageSelectDialog(QWidget *parent = 0); explicit LanguageSelectDialog(QWidget *parent = 0);
~LanguageSelectDialog(); ~LanguageSelectDialog();
QLocale::Language getSelectedLanguage(); QLocale::Language getSelectedLanguage();
private:
private:
Ui::LanguageSelectDialog *ui; Ui::LanguageSelectDialog *ui;
}; };
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
Q_DECLARE_METATYPE(QLocale::Language) Q_DECLARE_METATYPE(QLocale::Language)
#endif
#endif // LANGUAGESELECTDIALOG_H #endif // LANGUAGESELECTDIALOG_H

View File

@ -29,7 +29,11 @@ TranslationEditor::TranslationEditor(QWidget *parent) :
ui->tbStrings->setHorizontalHeaderItem(1,new QTableWidgetItem(tr("Report Item"))); ui->tbStrings->setHorizontalHeaderItem(1,new QTableWidgetItem(tr("Report Item")));
ui->tbStrings->setHorizontalHeaderItem(2,new QTableWidgetItem(tr("Property"))); ui->tbStrings->setHorizontalHeaderItem(2,new QTableWidgetItem(tr("Property")));
ui->tbStrings->setHorizontalHeaderItem(3,new QTableWidgetItem(tr("Source text"))); ui->tbStrings->setHorizontalHeaderItem(3,new QTableWidgetItem(tr("Source text")));
new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Return), this, SLOT(slotItemChecked())); #if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
m_clrReturn = new QShortcut(QKeySequence(Qt::CTRL | Qt::Key_Return), this, SLOT(slotItemChecked()));
#else
m_clrReturn = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Return), this, SLOT(slotItemChecked()));
#endif
//ui->tbStrings->setSortingEnabled(true); //ui->tbStrings->setSortingEnabled(true);
} }
@ -50,6 +54,7 @@ void TranslationEditor::setReportEngine(ITranslationContainer* translationContai
TranslationEditor::~TranslationEditor() TranslationEditor::~TranslationEditor()
{ {
delete ui; delete ui;
delete m_clrReturn;
} }
QLocale::Language TranslationEditor::getLanguageByName(const QString& languageName){ QLocale::Language TranslationEditor::getLanguageByName(const QString& languageName){

View File

@ -4,6 +4,7 @@
#include <QWidget> #include <QWidget>
#include <QLocale> #include <QLocale>
#include <QTreeWidgetItem> #include <QTreeWidgetItem>
#include <QShortcut>
#include "lrreporttranslation.h" #include "lrreporttranslation.h"
namespace LimeReport { namespace LimeReport {
@ -46,6 +47,7 @@ private:
PageTranslation* m_currentPageTranslation; PageTranslation* m_currentPageTranslation;
PropertyTranslation* m_currentPropertyTranslation; PropertyTranslation* m_currentPropertyTranslation;
bool m_translationChanging; bool m_translationChanging;
QShortcut* m_clrReturn;
}; };
} //namespace LimeReport } //namespace LimeReport