0
0
mirror of https://github.com/fralx/LimeReport.git synced 2025-03-28 13:13:44 +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_MINOR 6)
set(LIMEREPORT_VERSION_RELEASE 6)
set(LIMEREPORT_VERSION_RELEASE 8)
option(ENABLE_ZINT "Enable libzint build for barcode support" OFF)
option(LIMEREPORT_STATIC "Build LimeReport as static library" OFF)
option(USE_QT6 "Use Qt6" OFF)
find_package(
QT NAMES Qt6 Qt5
COMPONENTS Core Widgets Sql Network Xml Svg Qml PrintSupport REQUIRED
)
if(USE_QT6)
find_package(QT NAMES Qt6)
else()
find_package(QT NAMES Qt5)
endif(USE_QT6)
find_package(
Qt${QT_VERSION_MAJOR}
COMPONENTS Core Widgets Sql Network Xml Svg Qml PrintSupport REQUIRED
@ -36,7 +38,7 @@ endif()
add_subdirectory(3rdparty)
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_AUTOUIC ON)
@ -78,6 +80,7 @@ ${PROJECT_NAME}/items/editors/lrtextalignmenteditorwidget.cpp
${PROJECT_NAME}/items/lrabstractlayout.cpp
${PROJECT_NAME}/items/lralignpropitem.cpp
${PROJECT_NAME}/items/lrchartitem.cpp
${PROJECT_NAME}/items/lrchartaxiseditor.cpp
${PROJECT_NAME}/items/lrchartitemeditor.cpp
${PROJECT_NAME}/items/lrhorizontallayout.cpp
${PROJECT_NAME}/items/lrimageitem.cpp
@ -189,6 +192,7 @@ ${PROJECT_NAME}/items/editors/lrtextalignmenteditorwidget.h
${PROJECT_NAME}/items/lrabstractlayout.h
${PROJECT_NAME}/items/lralignpropitem.h
${PROJECT_NAME}/items/lrchartitem.h
${PROJECT_NAME}/items/lrchartaxiseditor.h
${PROJECT_NAME}/items/lrchartitemeditor.h
${PROJECT_NAME}/items/lreditableimageitemintf.h
${PROJECT_NAME}/items/lrhorizontallayout.h
@ -285,6 +289,7 @@ ${PROJECT_NAME}/databrowser/lrsqleditdialog.ui
${PROJECT_NAME}/databrowser/lrvariabledialog.ui
${PROJECT_NAME}/dialogdesigner/templates/Dialog.ui
${PROJECT_NAME}/items/lrchartitemeditor.ui
${PROJECT_NAME}/items/lrchartaxiseditor.ui
${PROJECT_NAME}/items/lrimageitemeditor.ui
${PROJECT_NAME}/items/lrtextitemeditor.ui
${PROJECT_NAME}/lraboutdialog.ui
@ -340,6 +345,8 @@ set(GLOBAL_HEADERS
${CMAKE_CURRENT_BINARY_DIR}/config.h
)
set(PROJECT_NAME ${PROJECT_NAME}-qt${QT_VERSION_MAJOR})
if (LIMEREPORT_STATIC)
message(STATUS "STATIC LIBRARY")
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)
## Donation [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.me/arinalex)
## Features
* Multi-platform support

View File

@ -141,7 +141,7 @@ RCC_DIR = $${ARCH_DIR}/$${BUILD_TYPE}/rcc
LIMEREPORT_VERSION_MAJOR = 1
LIMEREPORT_VERSION_MINOR = 6
LIMEREPORT_VERSION_RELEASE = 0
LIMEREPORT_VERSION_RELEASE = 8
LIMEREPORT_VERSION = '$${LIMEREPORT_VERSION_MAJOR}.$${LIMEREPORT_VERSION_MINOR}.$${LIMEREPORT_VERSION_RELEASE}'
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}::Qml
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
Qt${QT_VERSION_MAJOR}::Core
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 escapeSimbols(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);
#else
QVector<QString> normalizeCaptures(const QRegExp &reg);
@ -157,6 +157,16 @@ namespace Const{
#else
typedef QStyleOptionViewItem StyleOptionViewItem;
#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
{

View File

@ -36,7 +36,11 @@ namespace LimeReport {
DataBrowserTree::DataBrowserTree(QWidget *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
#endif
{
QMimeData* result = QTreeWidget::mimeData(items);
if (items.at(0)->type()==Row){

View File

@ -42,7 +42,11 @@ public:
enum NodeType{Connection, Table, Row, Category, Variable, ExternalVariable};
explicit DataBrowserTree(QWidget *parent = 0);
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:

View File

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

View File

@ -30,6 +30,7 @@ SOURCES += \
$$REPORT_PATH/objectinspector/propertyItems/lrcontentpropitem.cpp \
$$REPORT_PATH/objectinspector/propertyItems/lrmarginpropitem.cpp \
$$REPORT_PATH/objectinspector/propertyItems/lrseriespropitem.cpp \
$$REPORT_PATH/objectinspector/propertyItems/lraxispropitem.cpp \
$$REPORT_PATH/objectinspector/editors/lrtextitempropertyeditor.cpp \
$$REPORT_PATH/objectinspector/editors/lrcomboboxeditor.cpp \
$$REPORT_PATH/objectinspector/editors/lrcheckboxeditor.cpp \
@ -80,6 +81,7 @@ HEADERS += \
$$REPORT_PATH/objectinspector/propertyItems/lrcolorpropitem.h \
$$REPORT_PATH/objectinspector/propertyItems/lrmarginpropitem.h \
$$REPORT_PATH/objectinspector/propertyItems/lrseriespropitem.h \
$$REPORT_PATH/objectinspector/propertyItems/lraxispropitem.h \
$$REPORT_PATH/objectinspector/editors/lrtextitempropertyeditor.h \
$$REPORT_PATH/objectinspector/editors/lrcomboboxeditor.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
{
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)

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);

View File

@ -8,7 +8,7 @@ namespace LimeReport{
class PieChart : public AbstractChart{
public:
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 paintChartLegend(QPainter *painter, QRectF legendRect);
protected:

View File

@ -71,8 +71,6 @@ void VerticalBarChart::paintVerticalBars(QPainter *painter, QRectF barsRect)
qreal hStep = (barsRect.width() / valuesCount()) / (barSeriesCount == 0 ? 1 : barSeriesCount);
qreal topShift = (delta - (maxValue() - minValue())) * vStep + barsRect.top();
qDebug() << "vStep" << vStep << "hStep" << hStep;
if (!m_chartItem->series().isEmpty() && (m_chartItem->itemMode() != DesignMode)){
int curSeries = 0;
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)
{
placeItemInLayout(item);
m_children.append(item);
@ -57,22 +56,7 @@ void AbstractLayout::addChild(BaseDesignIntf* item, bool updateSize)
item->setFixedPos(true);
item->setPossibleResizeDirectionFlags(ResizeRight | ResizeBottom);
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))
);
connectToLayout(item);
if (updateSize){
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)
{
if (m_children.contains(item)) return;
m_isRelocating=true;
insertItemInLayout(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(itemAlignChanged(BaseDesignIntf*,ItemAlign,ItemAlign)),
this, SLOT(slotOnChildItemAlignChanged(BaseDesignIntf*,ItemAlign,ItemAlign)));
connectToLayout(item);
item->setFixedPos(true);
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)
{
rebuildChildrenIfNeeded();
@ -288,7 +324,7 @@ BaseDesignIntf *AbstractLayout::findPrior(BaseDesignIntf *item)
void AbstractLayout::slotOnChildDestroy(QObject* child)
{
m_children.removeAll(static_cast<BaseDesignIntf*>(child));
if (m_children.count()<2){
if (m_children.count() < 2 && !static_cast<LayoutDesignIntf*>(child)){
beforeDelete();
} else {
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);
}

View File

@ -28,6 +28,7 @@ public:
void setLayoutType(const LayoutType& layoutType);
void addChild(BaseDesignIntf *item,bool updateSize=true);
void removeChild(BaseDesignIntf *item);
void restoreChild(BaseDesignIntf *item);
bool isEmpty() const;
void paintChild(BaseDesignIntf* child, QPointF parentPos, QPainter* painter);
@ -52,6 +53,8 @@ protected:
QVariant itemChange(GraphicsItemChange change, const QVariant &value);
void updateItemSize(DataSourceManager* dataManager, RenderPass pass, int maxHeight);
void rebuildChildrenIfNeeded();
void connectToLayout(BaseDesignIntf* item);
void disconnectFromLayout(BaseDesignIntf* item);
private:
virtual void sortChildren() = 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 "lrreportengine_p.h"
#include "lrdatadesignintf.h"
#include "lrchartaxiseditor.h"
#include "charts/lrpiechart.h"
#include "charts/lrverticalbarchart.h"
@ -141,13 +142,18 @@ void SeriesItem::setPreferredType(const SeriesItemPreferredType& type)
ChartItem::ChartItem(QObject *owner, QGraphicsItem *parent)
: 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_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_chart = new PieChart(this);
m_chart->setTitleFont(font());
}
ChartItem::~ChartItem()
@ -182,20 +188,36 @@ void ChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
painter->setRenderHint(QPainter::Antialiasing,true);
painter->setRenderHint(QPainter::TextAntialiasing,true);
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();
qreal titleOffset = !m_title.isEmpty()?(((painter->fontMetrics().height()+borderMargin*2)<maxTitleHeight)?
(painter->fontMetrics().height()+borderMargin*2):
(maxTitleHeight)):0;
qreal titleOffset = 0;
if (!m_title.isEmpty()) {
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);
QRectF legendRect = QRectF(0,0,0,0);
if (m_showLegend)
const QRectF titleRect = QRectF(borderMargin,borderMargin,rect().width()-borderMargin*2,titleOffset);
QRectF legendRect = QRectF(0, 0, 0, 0);
QRectF diagramRect = rect().adjusted(borderMargin, titleOffset + borderMargin,
-(borderMargin * 2), -borderMargin);
if (m_showLegend) {
legendRect = m_chart->calcChartLegendRect(painter->font(), rect(), false, borderMargin, titleOffset);
QRectF diagramRect = rect().adjusted(borderMargin,titleOffset+borderMargin,
-(legendRect.width()+borderMargin*2),-borderMargin);
switch(legendAlign()) {
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);
if (m_showLegend)
@ -206,6 +228,47 @@ void ChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
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)
{
ChartItem* result = new ChartItem(owner,parent);
@ -271,10 +334,7 @@ void ChartItem::fillLabels(IDataSource *dataSource)
QWidget *ChartItem::defaultEditor()
{
QSettings* l_settings = (page()->settings() != 0) ?
page()->settings() :
(page()->reportEditor()!=0) ? page()->reportEditor()->settings() : 0;
QWidget* editor = new ChartItemEditor(this, page(), l_settings);
QWidget* editor = new ChartItemEditor(this, page(), settings());
editor->setAttribute(Qt::WA_DeleteOnClose);
return editor;
}
@ -284,6 +344,18 @@ bool ChartItem::isNeedUpdateSize(RenderPass pass) const
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
{
return m_showLegend;
@ -329,6 +401,7 @@ void ChartItem::setChartType(const ChartType &chartType)
if (m_chartType != chartType){
ChartType oldValue = m_chartType;
m_chartType = chartType;
QFont oldTitleFont = m_chart->titleFont();
delete m_chart;
switch (m_chartType) {
case Pie:
@ -347,6 +420,7 @@ void ChartItem::setChartType(const ChartType &chartType)
m_chart = new GridLinesChart(this);
break;
}
m_chart->setTitleFont(oldTitleFont);
notify("chartType",oldValue,m_chartType);
update();
}
@ -365,13 +439,16 @@ void ChartItem::setDatasource(const QString &datasource)
void ChartItem::paintChartTitle(QPainter *painter, QRectF titleRect)
{
painter->save();
QFont tmpFont = painter->font();
QFontMetrics fm(tmpFont);
while ((fm.height()>titleRect.height() || fm.boundingRect(m_title).width()>titleRect.width())
&& tmpFont.pixelSize()>1) {
QFont tmpFont = transformToSceneFont(titleFont());
QRect titleBoundingRect = QFontMetrics(tmpFont).boundingRect(rect().toRect(), Qt::TextWordWrap, chartTitle());
while ((titleBoundingRect.height() > titleRect.height() || titleBoundingRect.width() > titleRect.width())
&& tmpFont.pixelSize() > 1)
{
tmpFont.setPixelSize(tmpFont.pixelSize()-1);
fm = QFontMetrics(tmpFont);
titleBoundingRect = QFontMetrics(tmpFont).boundingRect(rect().toRect(), Qt::TextWordWrap, chartTitle());
}
painter->setFont(tmpFont);
Qt::AlignmentFlag align = Qt::AlignCenter;
switch (m_titleAlign) {
@ -385,7 +462,7 @@ void ChartItem::paintChartTitle(QPainter *painter, QRectF titleRect)
align = Qt::AlignRight;
break;
}
painter->drawText(titleRect, align, m_title);
painter->drawText(titleRect, align | Qt::TextWordWrap, m_title);
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
{
return m_legendBorder;
@ -527,6 +620,33 @@ void ChartItem::setGridChartLines(GridChartLines 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)
: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)
{
QSizeF legendSize = calcChartLegendSize(font);
const QSizeF legendSize = calcChartLegendSize(font, parentRect.width() * 0.9);
qreal legendTopMargin = 0;
qreal legendBottomMargin = 0;
qreal legendLeftMargin = 0;
bool isVertical = true;
switch (m_chartItem->legendAlign()) {
case ChartItem::LegendAlignTop:
legendTopMargin = titleOffset+borderMargin;
legendBottomMargin = parentRect.height()-(legendSize.height()+titleOffset);
case ChartItem::LegendAlignRightTop:
legendTopMargin = titleOffset + borderMargin;
legendBottomMargin = parentRect.height() - (legendSize.height() + titleOffset);
isVertical = true;
break;
case ChartItem::LegendAlignCenter:
legendTopMargin = titleOffset+(parentRect.height()-titleOffset-legendSize.height())/2;
legendBottomMargin = (parentRect.height()-titleOffset-legendSize.height())/2;
case ChartItem::LegendAlignRightCenter:
legendTopMargin = titleOffset + (parentRect.height() - titleOffset - legendSize.height()) / 2;
legendBottomMargin = (parentRect.height() - titleOffset - legendSize.height()) / 2;
isVertical = true;
break;
case ChartItem::LegendAlignBottom:
legendTopMargin = parentRect.height()-(legendSize.height()+titleOffset);
legendBottomMargin = borderMargin;
case ChartItem::LegendAlignRightBottom:
legendTopMargin = parentRect.height() - (legendSize.height() + titleOffset);
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;
}
qreal rightOffset = !takeAllRect?((legendSize.width()>parentRect.width()/2-borderMargin)?
(parentRect.width()/2):
(parentRect.width()-legendSize.width())):0;
if (isVertical) {
qreal rightOffset = !takeAllRect ? ((legendSize.width() > parentRect.width() / 2 - borderMargin) ?
(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)
{
QFont tmpFont = painter->font();
QSizeF legendSize = calcChartLegendSize(tmpFont);
if ((legendSize.height()>legendRect.height() || legendSize.width()>legendRect.width())){
while ( (legendSize.height()>legendRect.height() || legendSize.width()>legendRect.width())
&& tmpFont.pixelSize()>1)
switch(m_chartItem->legendAlign()) {
case ChartItem::LegendAlignBottomLeft:
case ChartItem::LegendAlignBottomCenter:
case ChartItem::LegendAlignBottomRight: {
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);
painter->setFont(tmpFont);
legendSize = calcChartLegendSize(tmpFont);
tmpFont.setPixelSize(tmpFont.pixelSize() - 1);
legendSize = calcChartLegendSize(tmpFont, legendRect.width());
}
painter->setFont(tmpFont);
legendRect = calcChartLegendRect(tmpFont, legendRect, true, 0, 0);
break;
}
}
@ -602,56 +778,58 @@ AbstractSeriesChart::AbstractSeriesChart(ChartItem *chartItem)
qreal AbstractSeriesChart::maxValue()
{
return m_yAxisData.maxValue();
return m_chartItem->yAxisData()->maxValue();
}
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()
{
qreal maxYValue = 0;
qreal minYValue = 0;
qreal maxXValue = 0;
qreal minXValue = 0;
if (m_chartItem->itemMode() == DesignMode) {
maxYValue = 40;
maxXValue = 40;
} else {
for (SeriesItem* series : m_chartItem->series()){
for (qreal value : series->data()->values()){
minYValue = std::min(minYValue, value);
maxYValue = std::max(maxYValue, value);
}
if (series->data()->xAxisValues().isEmpty()) {
// Grid plot starts from 0 on x axis so x range must be decresed by 1
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_chartItem->xAxisData()->updateForDesignMode();
m_chartItem->yAxisData()->updateForDesignMode();
return;
}
qreal maxYValue = 0;
qreal minYValue = std::numeric_limits<qreal>::max();
qreal maxXValue = 0;
qreal minXValue = std::numeric_limits<qreal>::max();
for (SeriesItem* series : m_chartItem->series()){
for (qreal value : series->data()->values()){
minYValue = std::min(minYValue, value);
maxYValue = std::max(maxYValue, value);
}
if (series->data()->xAxisValues().isEmpty()) {
// Grid plot starts from 0 on x axis so x range must be decresed by 1
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_xAxisData = AxisData(minXValue, maxXValue);
m_chartItem->xAxisData()->update(minXValue, maxXValue);
m_chartItem->yAxisData()->update(minYValue, maxYValue);
}
qreal AbstractSeriesChart::hPadding(QRectF chartRect)
@ -676,28 +854,54 @@ int AbstractSeriesChart::seriesCount()
return m_chartItem->series().count();
}
QSizeF AbstractSeriesChart::calcChartLegendSize(const QFont &font)
QSizeF AbstractSeriesChart::calcChartLegendSize(const QFont &font, const qreal maxWidth)
{
QFontMetrics fm(font);
qreal cw = 0;
qreal maxWidth = 0;
if (!m_chartItem->series().isEmpty()){
foreach(SeriesItem* series, m_chartItem->series()){
cw += fm.height();
if (maxWidth<fm.boundingRect(series->name()).width())
maxWidth = fm.boundingRect(series->name()).width()+10;
switch(m_chartItem->legendAlign()) {
case ChartItem::LegendAlignBottomLeft:
case ChartItem::LegendAlignBottomCenter:
case ChartItem::LegendAlignBottomRight: {
const qreal seriesCount = m_chartItem->series().isEmpty() ? m_designLabels.size() : m_chartItem->series().size();
const qreal indicatorWidth = fm.height() * 1.5;
m_legendColumnWidths.clear();
while (!calculateLegendColumnWidths(indicatorWidth, maxWidth, fm)) {
// Nothing to do here
}
} else {
foreach(QString label, m_designLabels){
cw += fm.height();
if (maxWidth<fm.boundingRect(label).width())
maxWidth = fm.boundingRect(label).width()+10;
if (m_legendColumnWidths.isEmpty()) {
m_legendColumnWidths.append(0);
}
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();
return QSizeF(maxWidth+fm.height()*2,cw);
default: {
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)
@ -829,7 +1033,7 @@ void AbstractSeriesChart::paintGrid(QPainter *painter, QRectF gridRect)
painter->save();
const AxisData &yAxisData = this->yAxisData();
const AxisData &xAxisData = this->xAxisData();
AxisData &xAxisData = this->xAxisData();
painter->setRenderHint(QPainter::Antialiasing,false);
@ -874,20 +1078,19 @@ void AbstractSeriesChart::paintGrid(QPainter *painter, QRectF gridRect)
if (m_chartItem->horizontalAxisOnTop()) {
painter->drawLine(x, gridRect.top() - gridOffset.height(),
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()),
hStep, fontHeight),
text);
} else {
painter->drawLine(x, gridRect.bottom() + gridOffset.height(),
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(),
hStep, fontHeight),
text);
}
}
painter->restore();
}
@ -973,7 +1176,12 @@ QString AbstractSeriesChart::axisLabel(int i, const AxisData &axisData)
{
const qreal min = axisData.rangeMin();
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) {
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);
}
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)
{
prepareLegendToPaint(legendRect, painter);
int indicatorSize = painter->fontMetrics().height()/2;
painter->setPen(Qt::black);
painter->setRenderHint(QPainter::Antialiasing,false);
if (m_chartItem->drawLegendBorder())
painter->drawRect(legendRect);
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()){
qreal cw = 0;
foreach(SeriesItem* series, m_chartItem->series()){
QString label = series->name();
painter->drawText(indicatorsRect.adjusted(indicatorSize+indicatorSize/2,cw,0,0),label);
painter->setBrush(series->color());
painter->drawEllipse(
indicatorsRect.adjusted(
0,
cw+indicatorSize/2,
-(indicatorsRect.width()-indicatorSize),
-(indicatorsRect.height()-(cw+indicatorSize+indicatorSize/2))
)
);
cw += painter->fontMetrics().height();
for (int i = 0 ; i < m_chartItem->series().size() ; ++i) {
SeriesItem* series = m_chartItem->series().at(i);
if (isHorizontal) {
drawHorizontalLegendItem(painter, i, series->name(), indicatorSize, indicatorsRect, series->color());
} else {
drawVerticalLegendItem(painter, i, series->name(), indicatorSize, indicatorsRect, series->color());
}
}
} else if (m_chartItem->itemMode() == DesignMode){
qreal cw = 0;
for (int i=0;i<m_designLabels.size();++i){
QString label = m_designLabels.at(i);
painter->drawText(indicatorsRect.adjusted(indicatorSize+indicatorSize/2,cw,0,0),label);
painter->setBrush(color_map[i]);
painter->drawEllipse(
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) {
for (int i = 0 ; i < m_designLabels.size() ; ++i){
if (isHorizontal) {
drawHorizontalLegendItem(painter, i, m_designLabels.at(i), indicatorSize, indicatorsRect, color_map[i]);
} else {
drawVerticalLegendItem(painter, i, m_designLabels.at(i), indicatorSize, indicatorsRect, color_map[i]);
}
}
}
@ -1058,4 +1346,66 @@ QRectF AbstractBarChart::horizontalLabelsRect(QPainter *painter, QRectF labelsRe
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

View File

@ -76,28 +76,36 @@ public:
virtual ~AbstractChart(){}
virtual void paintChart(QPainter *painter, QRectF rect) = 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);
QFont titleFont();
void setTitleFont(const QFont &value);
protected:
QVector<qreal> legendColumnWidths() const;
virtual void prepareLegendToPaint(QRectF& legendRect, QPainter *painter);
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;
QList<QString> m_designLabels;
QVector<qreal> m_legendColumnWidths;
};
class AbstractSeriesChart: public AbstractChart{
public:
AbstractSeriesChart(ChartItem* chartItem);
protected:
AxisData yAxisData();
AxisData xAxisData();
AxisData &xAxisData() const;
AxisData &yAxisData() const;
qreal maxValue();
qreal minValue();
void updateMinAndMaxValues();
int valuesCount();
int seriesCount();
bool verticalLabels(QPainter* painter, QRectF labelsRect);
QSizeF calcChartLegendSize(const QFont &font);
QSizeF calcChartLegendSize(const QFont &font, qreal maxWidth);
qreal* designValues(){ return m_designValues;}
virtual qreal hPadding(QRectF chartRect);
virtual qreal vPadding(QRectF chartRect);
@ -114,7 +122,9 @@ protected:
virtual QString axisLabel(int i, const AxisData &axisData);
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];
};
@ -125,20 +135,30 @@ public:
protected:
QRectF verticalLabelsRect(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
{
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(QString datasource READ datasource WRITE setDatasource)
Q_PROPERTY(QString chartTitle READ chartTitle WRITE setChartTitle)
Q_PROPERTY(bool drawLegendBorder READ drawLegendBorder WRITE setDrawLegendBorder)
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(ChartType chartType READ chartType WRITE setChartType)
Q_PROPERTY(QString labelsField READ labelsField WRITE setLabelsField)
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
Q_PROPERTY(bool drawPoints READ drawPoints WRITE setDrawPoints)
@ -152,7 +172,8 @@ class ChartItem : public LimeReport::ItemDesignIntf
friend class AbstractChart;
public:
enum LegendAlign{LegendAlignTop,LegendAlignCenter,LegendAlignBottom};
enum LegendAlign{LegendAlignRightTop,LegendAlignRightCenter,LegendAlignRightBottom,
LegendAlignBottomLeft,LegendAlignBottomCenter,LegendAlignBottomRight};
enum LegendStyle{LegendPoints, LegendLines};
enum TitleAlign{TitleAlignLeft, TitleAlignCenter, TitleAlignRight};
enum ChartType{Pie, VerticalBar, HorizontalBar, Lines, GridLines};
@ -164,11 +185,13 @@ public:
};
#if QT_VERSION >= 0x050500
Q_ENUM(LegendAlign)
Q_ENUM(LegendStyle)
Q_ENUM(TitleAlign)
Q_ENUM(ChartType)
Q_ENUM(LineType)
#else
Q_ENUMS(LegendAlign)
Q_ENUMS(LegendStyle)
Q_ENUMS(TitleAlign)
Q_ENUMS(ChartType)
Q_ENUMS(LineType)
@ -179,6 +202,16 @@ public:
~ChartItem();
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();
void setSeries(const QList<SeriesItem *> &series);
bool isSeriesExists(const QString& name);
@ -195,6 +228,9 @@ public:
LegendAlign legendAlign() const;
void setLegendAlign(const LegendAlign &legendAlign);
LegendStyle legendStyle() const;
void setLegendStyle(const LegendStyle &legendStyle);
TitleAlign titleAlign() const;
void setTitleAlign(const TitleAlign &titleAlign);
@ -226,6 +262,12 @@ public:
GridChartLines gridChartLines() const;
void setGridChartLines(GridChartLines flags);
QFont titleFont() const;
void setTitleFont(QFont value);
void setCharItemFont(QFont value);
QSettings *settings();
protected:
void paintChartTitle(QPainter* painter, QRectF titleRect);
virtual BaseDesignIntf* createSameTypeItem(QObject *owner, QGraphicsItem *parent);
@ -257,6 +299,8 @@ private:
QString m_xAxisField;
bool m_horizontalAxisOnTop;
GridChartLines m_gridChartLines;
LegendStyle m_legendStyle;
AxisData *m_xAxisData, *m_yAxisData;
};
} //namespace LimeReport
#endif // LRCHARTITEM_H

View File

@ -295,4 +295,15 @@ void ChartItemEditor::on_xAxisFieldComboBox_currentTextChanged(const QString &ar
{
if (!m_initing)
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 slotChangeSeriesColor();
void on_seriesTypeComboBox_currentIndexChanged(const QString &arg1);
void on_xAxisFieldComboBox_currentTextChanged(const QString &arg1);
void on_tableWidget_itemChanged(QTableWidgetItem *item);
private:
void readSetting();

View File

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

View File

@ -61,8 +61,13 @@ BaseDesignIntf *ImageItem::createSameTypeItem(QObject *owner, QGraphicsItem *par
}
void ImageItem::loadPictureFromVariant(QVariant& data){
//TODO: Migrate to QMetaType
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>();
} else {
switch (m_format) {
@ -178,11 +183,22 @@ void ImageItem::updateItemSize(DataSourceManager* dataManager, RenderPass pass,
m_resourcePath = expandDataFields(m_resourcePath, NoEscapeSymbols, dataManager);
m_picture = QImage(m_resourcePath);
} else if (!m_variable.isEmpty()){
//TODO: Migrate to QMetaType
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){
#endif
m_picture = QImage(data.toString());
} else if (data.type() == QVariant::Image){
loadPictureFromVariant(data);
} else {
#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_image = imageFromResource(m_resourcePath);
} else if (!m_variable.isEmpty()){
//TODO: Migrate to QMetaType
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){
#endif
m_image = imageFromResource(data.toString());
} else if (data.type() == QVariant::ByteArray) {
m_image = data.value<QByteArray>() ;
} else {
#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);
}
QString TextItem::content() const{
return m_strText;
}
void TextItem::Init()
{
m_autoWidth = NoneAutoWidth;
@ -299,14 +295,8 @@ void TextItem::setContent(const QString &value)
{
if (m_strText.compare(value)!=0){
QString oldValue = m_strText;
if (m_trimValue)
m_strText=value.trimmed();
else
m_strText=value;
// if (itemMode() == DesignMode && (autoHeight())){
// initTextSizes();
// }
m_strText = value;
if (!isLoading()){
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)
{
@ -493,29 +487,43 @@ QString TextItem::formatFieldValue()
}
}
#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
switch (value.type()) {
case QVariant::Date:
case QVariant::DateTime:
return formatDateTime(value.toDateTime());
case QVariant::Double:
return formatNumber(value.toDouble());
default:
return value.toString();
case QVariant::Date:
case QVariant::DateTime:
return formatDateTime(value.toDateTime());
case QVariant::Double:
return formatNumber(value.toDouble());
default:
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
{
TextPtr text(new QTextDocument);
QString content = m_trimValue ? m_strText.trimmed() : m_strText;
if (allowHTML())
if (isReplaceCarriageReturns()){
text->setHtml(replaceReturns(m_strText));
text->setHtml(replaceReturns(content));
} else {
text->setHtml(m_strText);
text->setHtml(content);
}
else
text->setPlainText(m_strText);
text->setPlainText(content);
QTextOption to;
to.setAlignment(m_alignment);
@ -785,6 +793,7 @@ void TextItem::setTrimValue(bool value)
{
bool oldValue = m_trimValue;
m_trimValue = value;
update();
notify("trimValue",oldValue,value);
}
@ -827,7 +836,7 @@ void TextItem::expandContent(DataSourceManager* dataManager, RenderPass pass)
#if (QT_VERSION < QT_VERSION_CHECK(5, 15, 1))
QRegExp rx(QString(Const::NAMED_VARIABLE_RX).arg(variableName));
#else
QRegularExpression rx(QString(Const::NAMED_VARIABLE_RX).arg(variableName));
QRegularExpression rx = getNamedVariableRegEx(variableName);
#endif
if (context.contains(rx) && pass == FirstPass){
backupContent();

View File

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

View File

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

View File

@ -1,21 +1,84 @@
#include "lraxisdata.h"
namespace LimeReport {
AxisData::AxisData()
: m_rangeMin(0), m_rangeMax(0),
m_minValue(0), m_maxValue(0), m_step(0),
m_delta(0), m_segmentCount(4)
{
#include <cmath>
#include <QDebug>
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)
: AxisData()
QString AxisData::toString() const
{
// 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_maxValue = maxValue;
calculateValuesAboveMax(minValue, maxValue, 4);
m_delta = m_step * m_segmentCount;
update();
}
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
@ -23,6 +86,11 @@ int AxisData::segmentCount() const
return m_segmentCount;
}
bool AxisData::calculateAxisScale() const
{
return m_calculateAxisScale;
}
qreal AxisData::rangeMin() const
{
return m_rangeMin;
@ -53,16 +121,229 @@ qreal AxisData::delta() const
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;
while (max % segments != 0){
while (max % m_segmentCount != 0){
max++;
}
m_rangeMax = max;
m_step = max / segments;
m_rangeMin = minValue;
m_segmentCount = segments;
m_rangeMax = minValue() + max;
m_step = max / m_segmentCount;
m_rangeMin = minValue();
}
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
#define AXISDATA_H
#include <QtGlobal>
#include <QObject>
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:
AxisData();
AxisData(qreal minValue, qreal maxValue);
enum AxisType {
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;
@ -21,8 +40,36 @@ public:
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:
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_rangeMax;
@ -31,6 +78,15 @@ private:
qreal m_step;
qreal m_delta;
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);
bool useAlternateBackgroundColor() const;
void setUseAlternateBackgroundColor(bool useAlternateBackgroundColor);
void replaceGroupsFunction(BandDesignIntf *band);
qreal bottomSpace() const;
void setBackgroundModeProperty(BGMode 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()) {
widget = widget->parentWidget();
}
return widget;
}
void BaseDesignIntf::showEditorDialog(){
QWidget *editor = defaultEditor();
if (editor) {
editor->setStyleSheet(findRootWidget(scene()->views().at(0))->styleSheet());
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();
void BaseDesignIntf::showDialog(QWidget *widget)
{
if (!widget) {
return;
}
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)
@ -1340,18 +1349,27 @@ void BaseDesignIntf::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
QAction* lockGeometryAction = menu.addAction(tr("Lock item geometry"));
lockGeometryAction->setCheckable(true);
lockGeometryAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_L));
lockGeometryAction->setChecked(isGeometryLocked());
menu.addSeparator();
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"));
cutAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_X));
QAction* cutAction = menu.addAction(QIcon(":/report/images/cut"), tr("Cut"));
QAction* pasteAction = menu.addAction(QIcon(":/report/images/paste"), tr("Paste"));
pasteAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_V));
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();
ItemsReaderIntf::Ptr reader = StringXMLreader::create(clipboard->text());
if (reader->first() && reader->itemType() == "Object"){

View File

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

View File

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

View File

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

View File

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

View File

@ -67,7 +67,7 @@ QString replaceHTMLSymbols(const QString &value)
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){
#else
QVector<QString> normalizeCaptures(const QRegExp& reg){
@ -93,4 +93,53 @@ ReportError::ReportError(const QString& message):std::runtime_error(message.toSt
IExternalPainter::~IExternalPainter(){}
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

View File

@ -104,7 +104,7 @@ namespace Const{
QString extractClassName(QString className);
QString escapeSimbols(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);
#else
QVector<QString> normalizeCaptures(const QRegExp &reg);
@ -157,6 +157,16 @@ namespace Const{
#else
typedef QStyleOptionViewItem StyleOptionViewItem;
#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
{

View File

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

View File

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

View File

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

View File

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

View File

@ -492,7 +492,7 @@ bool ReportEnginePrivate::showPreviewWindow(ReportPages pages, PreviewHints hint
Q_UNUSED(printer)
if (pages.count()>0){
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->setAttribute(Qt::WA_DeleteOnClose,true);
w->setWindowModality(Qt::ApplicationModal);

View File

@ -196,13 +196,11 @@ void ReportRender::analizeItem(ContentItemDesignIntf* contentItem, BandDesignInt
QString content = contentItem->content();
QVector<QString> functions;
foreach(const QString &functionName, m_datasources->groupFunctionNames()){
#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 3)
QRegularExpression rx(QString(Const::GROUP_FUNCTION_RX).arg(functionName));
rx.setPatternOptions(rx.InvertedGreedinessOption);
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 1)
QRegularExpression rx = getGroupFunctionRegEx(functionName);
if(content.indexOf(rx)>=0){
functions.append(functionName);
}
// TODO: Qt6 port - done
#else
QRegExp rx(QString(Const::GROUP_FUNCTION_RX).arg(functionName));
rx.setMinimal(true);
@ -368,13 +366,11 @@ void ReportRender::clearPageMap()
bool checkContentItem(ContentItemDesignIntf* item, DataSourceManager* datasources){
QString content = item->content();
foreach(QString functionName, datasources->groupFunctionNames()){
#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 3)
QRegularExpression rx(QString(Const::GROUP_FUNCTION_RX).arg(functionName));
rx.setPatternOptions(rx.InvertedGreedinessOption);
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 1)
QRegularExpression rx = getGroupFunctionRegEx(functionName);
if(content.indexOf(rx)>=0){
return true;
}
// TODO: Qt6 port - done
#else
QRegExp rx(QString(Const::GROUP_FUNCTION_RX).arg(functionName));
if (rx.indexIn(content)>=0){
@ -400,16 +396,14 @@ bool ReportRender::containsGroupFunctions(BaseDesignIntf *container){
}
void ReportRender::extractGroupFuntionsFromItem(ContentItemDesignIntf* contentItem, BandDesignIntf* band){
#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 3)
if ( contentItem && contentItem->content().contains(QRegularExpression("\\$S\\s*\\{.*\\}"))){
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 1)
if ( contentItem && contentItem->content().contains(getScriptRegEx())){
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());
if (match.hasMatch()){
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){
match = rxName.match(contentItem->content());
GroupFunction* gf = datasources()->addGroupFunction(functionName, match.captured(1), band->objectName(), "");
@ -470,7 +440,6 @@ void ReportRender::extractGroupFuntionsFromItem(ContentItemDesignIntf* contentIt
}
}
// TODO: Qt6 port - done
#else
if ( contentItem && contentItem->content().contains(QRegExp("\\$S\\s*\\{.*\\}"))){
foreach(const QString &functionName, m_datasources->groupFunctionNames()){
@ -529,10 +498,8 @@ void ReportRender::replaceGroupFunctionsInItem(ContentItemDesignIntf* contentIte
if (m_groupfunctionItems.contains(contentItem->patternName())){
QString content = contentItem->content();
foreach(QString functionName, m_groupfunctionItems.value(contentItem->patternName())){
#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 3)
QRegularExpression rx(QString(Const::GROUP_FUNCTION_RX).arg(functionName));
rx.setPatternOptions(rx.InvertedGreedinessOption);
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 1)
QRegularExpression rx = getGroupFunctionRegEx(functionName);
QRegularExpressionMatch match = rx.match(content);
if (match.capturedStart() != -1){
@ -556,7 +523,6 @@ void ReportRender::replaceGroupFunctionsInItem(ContentItemDesignIntf* contentIte
match = rx.match(content, pos + match.capturedLength());
}
}
// TODO: Qt6 port - done
#else
QRegExp rx(QString(Const::GROUP_FUNCTION_RX).arg(functionName));
rx.setMinimal(true);

View File

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

View File

@ -401,7 +401,11 @@ private:
class ScriptNode{
public:
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 setStartLex(const QString startLex){ m_startLex = startLex;}
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_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);
QHBoxLayout *layout = new QHBoxLayout(this);
layout->addWidget(m_comboBox);

View File

@ -222,6 +222,10 @@ void QObjectPropertyModel::setMultiObjects(QList<QObject *>* list)
m_objects.clear();
submit();
if (list->isEmpty()) {
return;
}
if (!list->contains(m_object)){
m_object=list->at(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
{
//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()){
case QVariant::Rect:
return rectToString(propertyValue().toRect());
@ -93,6 +104,7 @@ QString LimeReport::RectPropItem::displayValue() const
default :
return ObjectPropItem::displayValue();
}
#endif
}
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)
{
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)
{
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)
@ -254,7 +264,13 @@ void XMLWriter::saveTranslation(QString propertyName, QObject* item, QDomElement
bool XMLWriter::isQObject(QString propertyName, QObject *item)
{
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)

View File

@ -8,18 +8,20 @@ namespace Ui {
class LanguageSelectDialog;
}
class LanguageSelectDialog : public QDialog
{
class LanguageSelectDialog : public QDialog {
Q_OBJECT
public:
public:
explicit LanguageSelectDialog(QWidget *parent = 0);
~LanguageSelectDialog();
QLocale::Language getSelectedLanguage();
private:
private:
Ui::LanguageSelectDialog *ui;
};
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
Q_DECLARE_METATYPE(QLocale::Language)
#endif
#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(2,new QTableWidgetItem(tr("Property")));
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);
}
@ -50,6 +54,7 @@ void TranslationEditor::setReportEngine(ITranslationContainer* translationContai
TranslationEditor::~TranslationEditor()
{
delete ui;
delete m_clrReturn;
}
QLocale::Language TranslationEditor::getLanguageByName(const QString& languageName){

View File

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