diff --git a/autotests/format/FormatTest.cpp b/autotests/format/FormatTest.cpp index bf42cf6f..566b472a 100644 --- a/autotests/format/FormatTest.cpp +++ b/autotests/format/FormatTest.cpp @@ -1,219 +1,218 @@ /* This file is part of the KDE project * Copyright (C) 2012 Dag Andersen * Copyright (C) 2015 Jarosław Staniek * * QFUZZYCOMPARE() from marble/tests/TestUtils.h: * Copyright (C) 2013 Dennis Nienhüser * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include "FormatTest.h" #include "KReportTestUtils.h" #include "KReportPreRenderer.h" #include "KReportDesigner.h" #include "KReportLabelElement.h" #include "KReportDocument.h" #include "KReportDesignerSectionDetail.h" #include "KReportSection.h" #include "KReportDesignerItemLine.h" #include "KReportItemLine.h" #include "KReportDesignerItemRectBase.h" #include "KReportUnit.h" -#include #include #include #include #include #include #include #include #include QTEST_MAIN(FormatTest) static bool openDesignFile(KReportDesign *design, QString *errorMessage) { const QString dir(QFile::decodeName(FILES_DATA_DIR)); const QString fname(QLatin1String(QTest::currentTestFunction()) + QLatin1String(".kreport")); QFile file(dir + QDir::separator() + fname); bool ok = file.open(QFile::ReadOnly | QFile::Text); if (!ok) { *errorMessage = QString::fromLatin1("Could not open file %1: ").arg(file.fileName()) + file.errorString(); return false; } QString content = file.readAll(); if (file.error() != QFileDevice::NoError) { *errorMessage = QString::fromLatin1("Error reading file %1: ").arg(file.fileName()) + file.errorString(); return false; } KReportDesignReadingStatus status; if (!design->setContent(content, &status)) { QString message; QDebug(&message) << status; *errorMessage = QLatin1String("Failed to load content. ") + message; return false; } errorMessage->clear(); return true; } void FormatTest::testPageLayout() { KReportDesign design; QString errorMessage; if (!openDesignFile(&design, &errorMessage)) { QFAIL(qPrintable(errorMessage)); } const QPageLayout pageLayout = design.pageLayout(); QVERIFY(pageLayout.isValid()); QCOMPARE(pageLayout.pageSize().id(), QPageSize::A5); QCOMPARE(pageLayout.pageSize().sizePoints(), QPageSize(QPageSize::A5).sizePoints()); QCOMPARE(pageLayout.orientation(), QPageLayout::Portrait); QCOMPARE(pageLayout.margins(QPageLayout::Millimeter), QMarginsF(30.0, 20.0, 40.0, 15.0)); //! @todo move this renderer test to a separate place #if 0 KReportDesigner designer; QCOMPARE(designer.propertySet()->property("page-size").value().toString(), QLatin1String("A5")); QCOMPARE(designer.propertySet()->property("margin-bottom").value().toDouble(), KReportUnit::parseValue("1.5cm")); QCOMPARE(designer.propertySet()->property("margin-top").value().toDouble(), KReportUnit::parseValue("2.0cm")); QCOMPARE(designer.propertySet()->property("margin-left").value().toDouble(), KReportUnit::parseValue("3.0cm")); QCOMPARE(designer.propertySet()->property("margin-right").value().toDouble(), KReportUnit::parseValue("4.0cm")); KReportPreRenderer renderer( designer.document() ); renderer.generate(); ReportPageOptions opt = renderer.reportData()->pageOptions(); QCOMPARE(opt.getPageSize(), QString("A5")); QScreen *srn = QApplication::screens().at(0); const qreal dpiY = srn->logicalDotsPerInchY(); - qDebug() << opt.getMarginBottom() << INCH_TO_POINT(opt.getMarginBottom()) << KReportDpi::dpiY() << dpiY << KReportUnit::parseValue("1.5cm"); - QFUZZYCOMPARE(INCH_TO_POINT(opt.getMarginBottom()) / KReportDpi::dpiY(), KReportUnit::parseValue("1.5cm"), 0.2); - QFUZZYCOMPARE(INCH_TO_POINT(opt.getMarginTop()) / KReportDpi::dpiY(), KReportUnit::parseValue("2.0cm"), 0.2); - QFUZZYCOMPARE(INCH_TO_POINT(opt.getMarginLeft()) / KReportDpi::dpiX(), KReportUnit::parseValue("3.0cm"), 0.2); - QFUZZYCOMPARE(INCH_TO_POINT(opt.getMarginRight()) / KReportDpi::dpiX(), KReportUnit::parseValue("4.0cm"), 0.3); + qDebug() << opt.getMarginBottom() << INCH_TO_POINT(opt.getMarginBottom()) << KReportPrivate::dpiY() << dpiY << KReportUnit::parseValue("1.5cm"); + QFUZZYCOMPARE(INCH_TO_POINT(opt.getMarginBottom()) / KReportPrivate::dpiY(), KReportUnit::parseValue("1.5cm"), 0.2); + QFUZZYCOMPARE(INCH_TO_POINT(opt.getMarginTop()) / KReportPrivate::dpiY(), KReportUnit::parseValue("2.0cm"), 0.2); + QFUZZYCOMPARE(INCH_TO_POINT(opt.getMarginLeft()) / KReportPrivate::dpiX(), KReportUnit::parseValue("3.0cm"), 0.2); + QFUZZYCOMPARE(INCH_TO_POINT(opt.getMarginRight()) / KReportPrivate::dpiX(), KReportUnit::parseValue("4.0cm"), 0.3); #endif } void FormatTest::testLineElement() { #if 0 // todo KReportDesign design; QString errorMessage; if (!openDesignFile(&design, &errorMessage)) { QFAIL(qPrintable(errorMessage)); } #endif //! @todo move this renderer test to a separate place #if 0 KReportDesigner designer; ReportSectionDetail *ds = designer.detailSection(); ReportSection *sec = ds->detailSection(); KReportItemLine *l = dynamic_cast(sec->items().first()); QVERIFY(l != 0); QCOMPARE(l->Z, 1.5); KReportPosition start = l->startPosition(); KReportPosition end = l->endPosition(); QCOMPARE(start.toPoint(), QPointF(KReportUnit::parseValue("1.5cm"), KReportUnit::parseValue("0.5cm"))); QCOMPARE(end.toPoint(), QPointF(KReportUnit::parseValue("4.5cm"), KReportUnit::parseValue("2.5cm"))); KReportPreRenderer renderer( designer.document() ); renderer.generate(); l = dynamic_cast(renderer.reportData()->object("line1")); QVERIFY(l != 0); QCOMPARE(l->Z, 1.5); start = l->startPosition(); end = l->endPosition(); QCOMPARE(start.toPoint(), QPointF(KReportUnit::parseValue("1.5cm"), KReportUnit::parseValue("0.5cm"))); QCOMPARE(end.toPoint(), QPointF(KReportUnit::parseValue("4.5cm"), KReportUnit::parseValue("2.5cm"))); #endif } void FormatTest::testLabelElement() { KReportDesign design; QString errorMessage; if (!openDesignFile(&design, &errorMessage)) { QFAIL(qPrintable(errorMessage)); } QCOMPARE(design.title(), QLatin1String("Label Element Test Report")); QVERIFY(design.hasSection(KReportSection::Detail)); KReportSection detailSection = design.section(KReportSection::Detail); QCOMPARE(detailSection.type(), KReportSection::Detail); QCOMPARE(detailSection.height(), CM_TO_POINT(5.0)); QCOMPARE(detailSection.backgroundColor(), QColor("#eeeeee")); QList elements = detailSection.elements(); QCOMPARE(elements.count(), 1); KReportElement element = elements.first(); QCOMPARE(element.name(), QLatin1String("label1")); KReportLabelElement label1(elements.first()); QCOMPARE(label1.text(), "Label"); QCOMPARE(label1.z(), 2.5); const QRectF rect(CM_TO_POINT(1.5), CM_TO_POINT(0.5), CM_TO_POINT(4.5), CM_TO_POINT(0.75)); QCOMPARE(label1.rect(), rect); QCOMPARE(label1.backgroundColor(), QColor("#dddddd")); QCOMPARE(label1.foregroundColor(), QColor("#101010")); QCOMPARE(label1.backgroundOpacity(), 0.9); QCOMPARE(label1.alignment(), Qt::AlignRight | Qt::AlignBottom); QCOMPARE(label1.font().capitalization(), QFont::AllLowercase); QCOMPARE(label1.font().bold(), true); QCOMPARE(label1.font().weight(), 99); QCOMPARE(label1.font().italic(), true); QCOMPARE(label1.font().fixedPitch(), true); QCOMPARE(label1.font().family(), "Ubuntu"); QCOMPARE(label1.font().kerning(), true); QCOMPARE(label1.font().underline(), true); QCOMPARE(label1.font().strikeOut(), true); QCOMPARE(label1.font().pointSizeF(), 9.0); QCOMPARE(label1.font().letterSpacing(), 110.0); QCOMPARE(label1.font().letterSpacingType(), QFont::PercentageSpacing); QCOMPARE(label1.borderStyle().width(), 1.0); QCOMPARE(label1.borderStyle().color(), QColor("#400000")); QCOMPARE(label1.borderStyle().penStyle(), Qt::DashLine); //! @todo move this renderer test to a separate place #if 0 KReportDesigner designer;//, doc.documentElement()); ReportSectionDetail *ds = designer.detailSection(); ReportSection *sec = ds->detailSection(); QVERIFY(sec->items().count() == 1); KReportDesignerItemRectBase *rect = dynamic_cast(sec->items().first()); QVERIFY(rect != 0); QRectF expected( QPointF(KReportUnit::parseValue("1.5cm"), KReportUnit::parseValue("0.5cm")), QSizeF(KReportUnit::parseValue("4.5cm"), KReportUnit::parseValue("0.75cm"))); QCOMPARE(rect->pointRect(), expected); KReportPreRenderer renderer( designer.document() ); renderer.generate(); KReportItemBase *item = dynamic_cast(renderer.reportData()->object("label1")); QVERIFY(item != 0); KReportPosition pos = item->position(); KReportSize size = item->size(); QCOMPARE(pos.toPoint().x(), KReportUnit::parseValue("1.5cm")); QCOMPARE(pos.toPoint().y(), KReportUnit::parseValue("0.5cm")); QCOMPARE(size.toPoint(), QSizeF(KReportUnit::parseValue("4.5cm"), KReportUnit::parseValue("0.75cm"))); QCOMPARE(size.toPoint(), QSizeF(KReportUnit::parseValue("4.5cm"), KReportUnit::parseValue("0.75cm"))); #endif } diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index f8ac5184..296fd234 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,19 +1,19 @@ find_package(Qt5Widgets REQUIRED) find_package(KF5WidgetsAddons) find_package(KF5GuiAddons) remove_definitions( -DQT_NO_KEYWORDS -DQT_NO_SIGNALS_SLOTS_KEYWORDS -DQT_NO_CAST_FROM_ASCII ) add_definitions(-DKREPORTEXAMPLE_DATA_DIR="\\"${CMAKE_CURRENT_SOURCE_DIR}\\"") set(kreportexample_SRCS main.cpp window.cpp DesignerWidget.cpp KReportExampleData.cpp ) add_executable(kreportexample ${kreportexample_SRCS}) -target_link_libraries(kreportexample KF5::ConfigGui KReport) +target_link_libraries(kreportexample KF5::ConfigGui KReport KReportUtilsPrivate) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 81335721..2affb80f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,369 +1,374 @@ # Options simple_option(KREPORT_SCRIPTING "Scripting support using JavaScript language" ON) if(KREPORT_SCRIPTING) find_package(Qt5Qml REQUIRED) set(SCRIPTING_LIBS Qt5::Qml) endif() set(kreport_LIB_SRCS common/kreport_debug.cpp common/kreportplugin_debug.cpp common/KReportItemBase.cpp common/KReportAsyncItemBase.cpp common/KReportSectionData.cpp common/KReportLabelSizeInfo.cpp common/KReportDocument.cpp common/KReportDetailSectionData.cpp common/KReportPluginInterface.cpp common/KReportItemLine.cpp common/KReportRenderObjects.cpp common/KReportPluginManager.cpp common/KReportJsonTrader_p.cpp common/KReportPluginMetaData.cpp common/KReportData.cpp common/KReportUtils.cpp common/KReportPageSize.cpp common/KReportUnit.cpp common/KReportDesign.cpp common/KReportDesign_p.cpp common/KReportLineStyle.cpp common/KReportElement.cpp ${PROJECT_BINARY_DIR}/src/KReportElement_sdc.cpp common/KReportSection.cpp renderer/KReportPrintRenderer_p.cpp renderer/KReportPreRenderer.cpp renderer/KReportAsyncItemManager_p.cpp renderer/KReportScreenRenderer_p.cpp renderer/KReportHTMLTableRenderer_p.cpp renderer/KReportHTMLCSSRenderer_p.cpp #TODO renderer/KReportKSpreadRenderer.cpp #TODO renderer/KReportODTRenderer.cpp #TODO renderer/KOdtFrameReportRenderer.cpp renderer/KReportRendererBase.cpp renderer/KReportPage.cpp renderer/KReportView.cpp renderer/KReportOneRecordData_p.cpp wrtembed/KReportDetailGroupSectionDialog.cpp wrtembed/KReportDesignerItemBase.cpp wrtembed/KReportDesignerItemRectBase.cpp wrtembed/KReportDesignerItemLine.cpp wrtembed/KReportDesignerSection.cpp wrtembed/KReportDesignerSectionDetailGroup.cpp wrtembed/KReportDesignerSectionDetail.cpp wrtembed/KReportDesignerSectionScene.cpp wrtembed/KReportDesignerSectionView.cpp wrtembed/KReportDesigner.cpp wrtembed/KReportPropertiesButton.cpp wrtembed/KReportSectionEditor.cpp - wrtembed/KReportDpi.cpp wrtembed/KReportRuler.cpp wrtembed/KReportZoomHandler.cpp wrtembed/KReportZoomMode.cpp items/label/KReportItemLabel.cpp items/label/KReportDesignerItemLabel.cpp items/label/KReportLabelPlugin.cpp items/label/KReportBoundedTextItem.cpp items/label/KReportLabelElement.cpp items/label/label.json items/check/KReportItemCheck.cpp items/check/KReportDesignerItemCheckBox.cpp items/check/KReportCheckBoxPlugin.cpp items/check/check.json items/field/KReportItemField.cpp items/field/KReportDesignerItemField.cpp items/field/KReportFieldPlugin.cpp items/field/field.json items/image/KReportItemImage.cpp items/image/KReportDesignerItemImage.cpp items/image/KReportImagePlugin.cpp items/image/image.json items/text/KReportItemText.cpp items/text/KReportDesignerItemText.cpp items/text/KReportTextPlugin.cpp items/text/text.json # non-source: Mainpage.dox Messages.sh ) - + set(kreport_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/common ${CMAKE_CURRENT_SOURCE_DIR}/wrtembed ${CMAKE_CURRENT_SOURCE_DIR}/renderer ) set(kreport_TARGET_INCLUDE_DIRS common renderer wrtembed ) if(KREPORT_SCRIPTING) list(APPEND kreport_LIB_SRCS renderer/scripting/KReportScriptHandler.cpp renderer/scripting/KReportScriptConstants.cpp renderer/scripting/KReportScriptDebug.cpp renderer/scripting/KReportScriptDraw.cpp renderer/scripting/KReportScriptReport.cpp renderer/scripting/KReportScriptSection.cpp renderer/scripting/KReportScriptLine.cpp #renderer/odtframe/KoOdtFrameReportDocument.cpp #renderer/odtframe/KoOdtFrameReportCheckBox.cpp #renderer/odtframe/KoOdtFrameReportImage.cpp #renderer/odtframe/KoOdtFrameReportTextBox.cpp #renderer/odtframe/KoOdtFrameReportLine.cpp #renderer/odtframe/KoOdtFrameReportPicture.cpp #renderer/odtframe/KoOdtFrameReportPrimitive.cpp #renderer/ods/KoSimpleOdsDocument.cpp #renderer/ods/KoSimpleOdsSheet.cpp #renderer/ods/KoSimpleOdsCell.cpp items/label/KReportScriptLabel.cpp items/check/KReportScriptCheck.cpp items/field/KReportScriptField.cpp items/image/KReportScriptImage.cpp items/text/KReportScriptText.cpp ) qt_wrap_cpp(KReport kreport_LIB_SRCS renderer/scripting/KReportGroupTracker.h ) list(APPEND kreport_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/renderer/scripting ) list(APPEND kreport_TARGET_INCLUDE_DIRS renderer/scripting ) endif() qt5_wrap_ui(kreport_LIB_SRCS wrtembed/KReportDetailGroupSectionDialog.ui wrtembed/KReportSectionEditor.ui ) ecm_create_qm_loader(kreport_LIB_SRCS kreport_qt) add_library(KReport SHARED ${kreport_LIB_SRCS}) set_coinstallable_lib_version(KReport) +add_library(KReportUtilsPrivate STATIC + common/KReportUtils_p.cpp +) + kdb_create_shared_data_classes( kreport_GENERATED_SHARED_DATA_CLASS_HEADERS # output variable with list of headers NO_PREFIX # subdirectory in which the headers should be generated common/KReportLineStyle.shared.h common/KReportElement.shared.h common/KReportSection.shared.h items/label/KReportLabelElement.shared.h ) kdb_remove_extensions( kreport_GENERATED_SHARED_DATA_CLASS_BASENAMES ${kreport_GENERATED_SHARED_DATA_CLASS_HEADERS} ) generate_export_header(KReport) #qt5_use_modules(KReport Widgets Xml PrintSupport) target_include_directories(KReport PUBLIC "$" INTERFACE "$" PRIVATE ${kreport_TARGET_INCLUDE_DIRS} ) target_link_libraries(KReport PUBLIC Qt5::PrintSupport Qt5::Xml KF5::CoreAddons KPropertyWidgets PRIVATE - KF5::WidgetsAddons - KF5::ConfigGui # KStandardShortcut ${SCRIPTING_LIBS} - #KF5::KIOCore - #KF5::KIOFileWidgets - #KF5::KIOWidgets - #KF5::KIONTLM + KReportUtilsPrivate ) +target_link_libraries(KReportUtilsPrivate + PUBLIC + Qt5::Widgets + PRIVATE + KF5::WidgetsAddons + KF5::ConfigGui + ) + ecm_setup_version(${PROJECT_VERSION} VARIABLE_PREFIX KREPORT VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/kreport_version.h" PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/KReportConfigVersion.cmake" ) install(TARGETS KReport EXPORT KReportTargets ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) # Create a Config.cmake and a ConfigVersion.cmake file and install them set(CMAKECONFIG_INSTALL_DIR "${CMAKECONFIG_INSTALL_PREFIX}/${KREPORT_BASE_NAME}") # A place for KReport plugins set(KREPORT_PLUGIN_INSTALL_DIR ${PLUGIN_INSTALL_DIR}/kreport${PROJECT_STABLE_VERSION_MAJOR}) ecm_configure_package_config_file( "${CMAKE_CURRENT_SOURCE_DIR}/KReportConfig.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/KReportConfig.cmake" INSTALL_DESTINATION "${CMAKECONFIG_INSTALL_DIR}" ) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/KReportConfig.cmake" "${CMAKE_CURRENT_BINARY_DIR}/KReportConfigVersion.cmake" DESTINATION "${CMAKECONFIG_INSTALL_DIR}" COMPONENT Devel) install(EXPORT KReportTargets DESTINATION "${CMAKECONFIG_INSTALL_DIR}" FILE KReportTargets.cmake) ecm_generate_pri_file( BASE_NAME ${KREPORT_BASE_NAME} LIB_NAME ${KREPORT_BASE_NAME} DEPS "widgets" FILENAME_VAR PRI_FILENAME INCLUDE_INSTALL_DIR ${KREPORT_INCLUDE_INSTALL_DIR} ) install(FILES ${PRI_FILENAME} DESTINATION ${ECM_MKSPECS_INSTALL_DIR}) install(FILES kreport_elementplugin.desktop DESTINATION ${SERVICETYPES_INSTALL_DIR}) ecm_generate_headers(kreport_FORWARDING_HEADERS REQUIRED_HEADERS kreport_HEADERS ORIGINAL CAMELCASE RELATIVE common HEADER_NAMES KReportPageSize KReportData KReportItemBase KReportItemLine KReportPluginMetaData KReportPluginManager KReportPluginInterface KReportUnit KReportUtils KReportDesign KReportDocument KReportSectionData KReportRenderObjects KReportAsyncItemBase ) ecm_generate_headers(kreport_FORWARDING_HEADERS REQUIRED_HEADERS kreport_HEADERS ORIGINAL CAMELCASE RELATIVE renderer HEADER_NAMES KReportPage KReportRendererBase KReportPreRenderer KReportView ) if(KREPORT_SCRIPTING) ecm_generate_headers(kreport_FORWARDING_HEADERS REQUIRED_HEADERS kreport_HEADERS ORIGINAL CAMELCASE RELATIVE renderer/scripting HEADER_NAMES KReportScriptHandler KReportScriptDraw KReportScriptConstants KReportGroupTracker ) endif() ecm_generate_headers(kreport_FORWARDING_HEADERS REQUIRED_HEADERS kreport_HEADERS ORIGINAL CAMELCASE RELATIVE wrtembed HEADER_NAMES KReportZoomMode KReportDesignerSectionDetail KReportDesignerSection - KReportDpi KReportZoomHandler KReportDesignerItemBase KReportDesignerSectionDetailGroup KReportDesignerItemRectBase KReportDesigner ) ecm_generate_headers(kreport_FORWARDING_HEADERS_FROM_BUILDDIR REQUIRED_HEADERS kreport_HEADERS_FROM_BUILDDIR ORIGINAL CAMELCASE SOURCE_DIR ${PROJECT_BINARY_DIR}/src HEADER_NAMES ${kreport_GENERATED_SHARED_DATA_CLASS_BASENAMES} ) list(APPEND kreport_HEADERS ${CMAKE_CURRENT_BINARY_DIR}/kreport_version.h) install( FILES ${kreport_HEADERS} ${kreport_HEADERS_FROM_BUILDDIR} ${kreport_FORWARDING_HEADERS} ${kreport_FORWARDING_HEADERS_FROM_BUILDDIR} ${PROJECT_BINARY_DIR}/src/kreport_export.h ${PROJECT_BINARY_DIR}/src/config-kreport.h DESTINATION ${KREPORT_INCLUDE_INSTALL_DIR} COMPONENT Devel ) if(BUILD_QCH) kreport_add_qch( KReport_QCH NAME KReport BASE_NAME ${KREPORT_BASE_NAME} VERSION ${PROJECT_VERSION} NAMESPACE org.kde.${KREPORT_BASE_NAME} SOURCES Mainpage.dox ${kreport_HEADERS} ${kreport_HEADERS_FROM_BUILDDIR} LINK_QCHS Qt5Core_QCH Qt5Xml_QCH Qt5Gui_QCH Qt5Widgets_QCH Qt5PrintSupport_QCH KF5CoreAddons_QCH KPropertyCore_QCH KPropertyWidgets_QCH BLANK_MACROS KREPORT_EXPORT KREPORT_DEPRECATED TAGFILE_INSTALL_DESTINATION ${KREPORT_QTQCH_FULL_INSTALL_DIR} QCH_INSTALL_DESTINATION ${KREPORT_QTQCH_FULL_INSTALL_DIR} ) set(kreport_qch_targets KReport_QCH) endif() kreport_install_qch_export( TARGETS ${kreport_qch_targets} FILE KReportQCHTargets.cmake DESTINATION "${CMAKECONFIG_INSTALL_DIR}" COMPONENT Devel ) add_subdirectory(plugins) add_subdirectory(pics) enable_testing() configure_file(config-kreport.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-kreport.h) diff --git a/src/common/KReportDocument.cpp b/src/common/KReportDocument.cpp index d8fc3dd7..968e1a07 100644 --- a/src/common/KReportDocument.cpp +++ b/src/common/KReportDocument.cpp @@ -1,388 +1,388 @@ /* This file is part of the KDE project * Copyright (C) 2007-2008 by Adam Pigg (adam@piggz.co.uk) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include "KReportDocument.h" #include "KReportUnit.h" #include "KReportDetailSectionData.h" #include "KReportItemBase.h" -#include "KReportDpi.h" +#include "KReportUtils_p.h" #include "KReportPageSize.h" #include #include #include "kreport_debug.h" class Q_DECL_HIDDEN KReportDocument::Private { public: bool valid; QString title; QString name; QString query; #ifdef KREPORT_SCRIPTING QString script; QString interpreter; #endif bool externalData; QPageLayout page; QString pageSize; QString labelType; }; void KReportDocument::init() { m_pageHeaderFirst = m_pageHeaderOdd = m_pageHeaderEven = m_pageHeaderLast = m_pageHeaderAny = 0; m_pageFooterFirst = m_pageFooterOdd = m_pageFooterEven = m_pageFooterLast = m_pageFooterAny = 0; m_reportHeader = m_reportFooter = 0; } KReportDocument::KReportDocument(QObject *parent) : QObject(parent), m_detailSection(0), d(new Private()) { init(); d->valid = true; } KReportDocument::KReportDocument(const QDomElement & elemSource, QObject *parent) : QObject(parent), m_detailSection(0), d(new Private()) { d->valid = false; init(); //kreportDebug(); if (elemSource.tagName() != QLatin1String("report:content")) { kreportWarning() << "QDomElement is not tag" << elemSource.text(); return; } - const qreal dpiX = KReportDpi::dpiX(); - const qreal dpiY = KReportDpi::dpiY(); + const qreal dpiX = KReportPrivate::dpiX(); + const qreal dpiY = KReportPrivate::dpiY(); QDomNodeList sections = elemSource.childNodes(); for (int nodeCounter = 0; nodeCounter < sections.count(); nodeCounter++) { QDomElement elemThis = sections.item(nodeCounter).toElement(); if (elemThis.tagName() == QLatin1String("report:title")) { d->title = elemThis.text(); #ifdef KREPORT_SCRIPTING } else if (elemThis.tagName() == QLatin1String("report:script")) { d->script = elemThis.text(); d->interpreter = elemThis.attribute(QLatin1String("report:script-interpreter")); #endif } else if (elemThis.tagName() == QLatin1String("report:page-style")) { QString pagetype = elemThis.firstChild().nodeValue(); //Full page mode is required to allow margins to be set to whatever the user has specified d->page.setMode(QPageLayout::FullPageMode); if (pagetype == QLatin1String("predefined")) { setPageSize(elemThis.attribute(QLatin1String("report:page-size"), QLatin1String("A4"))); d->page.setPageSize(QPageSize(KReportPageSize::pageSize(pageSize()))); } else if (pagetype == QLatin1String("custom")) { QPageSize custom(QSize(elemThis.attribute(QLatin1String("report:custom-page-width"), QString()).toFloat() , elemThis.attribute(QLatin1String("report:custom-page-height"), QString()).toFloat()), QLatin1String("Custom")); d->page.setPageSize(custom); } else if (pagetype == QLatin1String("label")) { setLabelType(elemThis.firstChild().nodeValue()); } //! @todo add config for default margins or add within templates support d->page.setUnits(QPageLayout::Point); d->page.setLeftMargin(KReportUnit::parseValue(elemThis.attribute(QLatin1String("fo:margin-left"), QLatin1String("1.0cm")))); d->page.setRightMargin(KReportUnit::parseValue(elemThis.attribute(QLatin1String("fo:margin-right"), QLatin1String("1.0cm")))); d->page.setTopMargin(KReportUnit::parseValue(elemThis.attribute(QLatin1String("fo:margin-top"), QLatin1String("1.0cm")))); d->page.setBottomMargin(KReportUnit::parseValue(elemThis.attribute(QLatin1String("fo:margin-bottom"), QLatin1String("1.0cm")))); d->page.setOrientation(elemThis.attribute(QLatin1String("report:print-orientation"), QLatin1String("portrait")) == QLatin1String("portrait") ? QPageLayout::Portrait : QPageLayout::Landscape); } else if (elemThis.tagName() == QLatin1String("report:body")) { QDomNodeList sectionlist = elemThis.childNodes(); QDomNode sec; for (int s = 0; s < sectionlist.count(); ++s) { sec = sectionlist.item(s); if (sec.isElement()) { QString sn = sec.nodeName().toLower(); //kreportDebug() << sn; if (sn == QLatin1String("report:section")) { KReportSectionData * sd = new KReportSectionData(sec.toElement(), this); if (!sd->isValid()) { kreportDebug() << "Invalid section"; delete sd; } else { //kreportDebug() << "Adding section of type " << sd->type(); switch (sd->type()) { case KReportSectionData::PageHeaderFirst: m_pageHeaderFirst = sd; break; case KReportSectionData::PageHeaderOdd: m_pageHeaderOdd = sd; break; case KReportSectionData::PageHeaderEven: m_pageHeaderEven = sd; break; case KReportSectionData::PageHeaderLast: m_pageHeaderLast = sd; break; case KReportSectionData::PageHeaderAny: m_pageHeaderAny = sd; break; case KReportSectionData::ReportHeader: m_reportHeader = sd; break; case KReportSectionData::ReportFooter: m_reportFooter = sd; break; case KReportSectionData::PageFooterFirst: m_pageFooterFirst = sd; break; case KReportSectionData::PageFooterOdd: m_pageFooterOdd = sd; break; case KReportSectionData::PageFooterEven: m_pageFooterEven = sd; break; case KReportSectionData::PageFooterLast: m_pageFooterLast = sd; break; case KReportSectionData::PageFooterAny: m_pageFooterAny = sd; break; default: ; } } } else if (sn == QLatin1String("report:detail")) { KReportDetailSectionData * dsd = new KReportDetailSectionData(sec.toElement(), this); if (dsd->isValid()) { m_detailSection = dsd; } else { kreportDebug() << "Invalid detail section"; delete dsd; } } } else { kreportWarning() << "Encountered an unknown Element: " << elemThis.tagName(); } } } d->valid = true; } } KReportDocument::~KReportDocument() { delete d; } QList KReportDocument::objects() const { QList obs; for (int i = 1; i <= KReportSectionData::PageFooterAny; i++) { KReportSectionData *sec = section((KReportSectionData::Section)i); if (sec) { obs << sec->objects(); } } if (m_detailSection) { //kreportDebug() << "Number of groups: " << m_detailSection->m_groupList.count(); foreach(KReportDetailGroupSectionData* g, m_detailSection->m_groupList) { if (g->m_groupHeader) { obs << g->m_groupHeader->objects(); } if (g->m_groupFooter) { obs << g->m_groupFooter->objects(); } } if (m_detailSection->m_detailSection) obs << m_detailSection->m_detailSection->objects(); } /*kreportDebug() << "Object List:"; foreach(KReportItemBase* o, obs) { kreportDebug() << o->entityName(); }*/ return obs; } KReportItemBase* KReportDocument::object(const QString& n) const { QList obs = objects(); foreach(KReportItemBase* o, obs) { if (o->entityName() == n) { return o; } } return 0; } QList KReportDocument::sections() const { QList secs; for (int i = 0; i < 12 ; ++i) { KReportSectionData *sec = section((KReportSectionData::Section)(i + 1)); if (sec) { secs << sec; } } if (m_detailSection) { //kreportDebug() << "Number of groups: " << m_detailSection->m_groupList.count(); foreach(KReportDetailGroupSectionData* g, m_detailSection->m_groupList) { if (g->m_groupHeader) { secs << g->m_groupHeader; } if (g->m_groupFooter) { secs << g->m_groupFooter; } } if (m_detailSection->m_detailSection) secs << m_detailSection->m_detailSection; } return secs; } KReportSectionData* KReportDocument::section(const QString& sn) const { QList secs = sections(); foreach(KReportSectionData *sec, secs) { if (sec->name() == sn) { return sec; } } return 0; } KReportSectionData* KReportDocument::section(KReportSectionData::Section s) const { KReportSectionData *sec; switch (s) { case KReportSectionData::PageHeaderAny: sec = m_pageHeaderAny; break; case KReportSectionData::PageHeaderEven: sec = m_pageHeaderEven; break; case KReportSectionData::PageHeaderOdd: sec = m_pageHeaderOdd; break; case KReportSectionData::PageHeaderFirst: sec = m_pageHeaderFirst; break; case KReportSectionData::PageHeaderLast: sec = m_pageHeaderLast; break; case KReportSectionData::PageFooterAny: sec = m_pageFooterAny; break; case KReportSectionData::PageFooterEven: sec = m_pageFooterEven; break; case KReportSectionData::PageFooterOdd: sec = m_pageFooterOdd; break; case KReportSectionData::PageFooterFirst: sec = m_pageFooterFirst; break; case KReportSectionData::PageFooterLast: sec = m_pageFooterLast; break; case KReportSectionData::ReportHeader: sec = m_reportHeader; break; case KReportSectionData::ReportFooter: sec = m_reportFooter; break; default: sec = 0; } return sec; } QPageLayout KReportDocument::pageLayout() const { return d->page; } bool KReportDocument::isValid() const { return d->valid; } QString KReportDocument::title() const { return d->title; } bool KReportDocument::externalData() const { return d->externalData; } QString KReportDocument::interpreter() const { return d->interpreter; } QString KReportDocument::name() const { return d->name; } void KReportDocument::setName(const QString& n) { d->name = n; } QString KReportDocument::query() const { return d->query; } QString KReportDocument::script() const { return d->script; } QString KReportDocument::pageSize() { return d->pageSize; } void KReportDocument::setPageSize(const QString& size) { d->pageSize = size; } QString KReportDocument::labelType() const { return d->labelType; } void KReportDocument::setLabelType(const QString& label) { d->labelType = label; } diff --git a/src/common/KReportItemBase.cpp b/src/common/KReportItemBase.cpp index 0f04d550..212af5c2 100644 --- a/src/common/KReportItemBase.cpp +++ b/src/common/KReportItemBase.cpp @@ -1,237 +1,239 @@ /* This file is part of the KDE project * Copyright (C) 2007-2008 by Adam Pigg (adam@piggz.co.uk) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include "KReportItemBase.h" #include "KReportUtils.h" +#include "KReportUtils_p.h" + #include #include #include class Q_DECL_HIDDEN KReportItemBase::Private { public: Private(); ~Private(); KPropertySet *set; KProperty *nameProperty; KProperty *sizeProperty; KProperty *positionProperty; QString oldName; qreal z; }; KReportItemBase::Private::Private() { set = new KPropertySet(); nameProperty = new KProperty("name", QString(), tr("Name"), tr("Object Name")); nameProperty->setAutoSync(0); positionProperty = new KProperty("position", QPointF(), QCoreApplication::translate("ItemPosition", "Position")); sizeProperty = new KProperty("size", QSizeF(), QCoreApplication::translate("ItemSize", "Size")); set->addProperty(nameProperty); set->addProperty(positionProperty); set->addProperty(sizeProperty); } KReportItemBase::Private::~Private() { delete set; } KReportItemBase::KReportItemBase() : d(new Private()) { d->z = 0; connect(propertySet(), &KPropertySet::propertyChanged, this, &KReportItemBase::propertyChanged); } KReportItemBase::~KReportItemBase() { delete d; } bool KReportItemBase::parseReportTextStyleData(const QDomElement & elemSource, KRTextStyleData *ts) { return KReportUtils::parseReportTextStyleData(elemSource, ts); } bool KReportItemBase::parseReportLineStyleData(const QDomElement & elemSource, KReportLineStyle *ls) { return KReportUtils::parseReportLineStyleData(elemSource, ls); } bool KReportItemBase::parseReportRect(const QDomElement & elemSource) { QPointF pos; QSizeF size; pos.setX(KReportUnit::parseValue(elemSource.attribute(QLatin1String("svg:x"), QLatin1String("1cm")))); pos.setY(KReportUnit::parseValue(elemSource.attribute(QLatin1String("svg:y"), QLatin1String("1cm")))); size.setWidth(KReportUnit::parseValue(elemSource.attribute(QLatin1String("svg:width"), QLatin1String("1cm")))); size.setHeight(KReportUnit::parseValue(elemSource.attribute(QLatin1String("svg:height"), QLatin1String("1cm")))); setPosition(pos); setSize(size); return true; } void KReportItemBase::setUnit(const KReportUnit& u) { qDebug() << "Setting page unit to: " << u.symbol(); d->positionProperty->setOption("unit", u.symbol()); d->sizeProperty->setOption("unit", u.symbol()); } int KReportItemBase::renderSimpleData(OROPage *page, OROSection *section, const QPointF &offset, const QVariant &data, KReportScriptHandler* script) { Q_UNUSED(page) Q_UNUSED(section) Q_UNUSED(offset) Q_UNUSED(data) Q_UNUSED(script) return 0; } int KReportItemBase::renderReportData(OROPage *page, OROSection *section, const QPointF &offset, KReportData *data, KReportScriptHandler* script) { Q_UNUSED(page) Q_UNUSED(section) Q_UNUSED(offset) Q_UNUSED(data) Q_UNUSED(script) return 0; } QString KReportItemBase::itemDataSource() const { return QString(); } KPropertySet* KReportItemBase::propertySet() { return d->set; } bool KReportItemBase::supportsSubQuery() const { return false; } QString KReportItemBase::entityName() const { return d->nameProperty->value().toString(); } void KReportItemBase::setEntityName(const QString& n) { d->nameProperty->setValue(n); } KProperty* KReportItemBase::nameProperty() { return d->nameProperty; } QString KReportItemBase::oldName() const { return d->oldName; } void KReportItemBase::setOldName(const QString& old) { d->oldName = old; } QPointF KReportItemBase::position() const { return d->positionProperty->value().toPointF(); } QSizeF KReportItemBase::size() const { return d->sizeProperty->value().toSizeF(); } const KPropertySet * KReportItemBase::propertySet() const { return d->set; } QPointF KReportItemBase::scenePosition(const QPointF &pos) { - const qreal x = POINT_TO_INCH(pos.x()) * KReportDpi::dpiX(); - const qreal y = POINT_TO_INCH(pos.y()) * KReportDpi::dpiY(); + const qreal x = POINT_TO_INCH(pos.x()) * KReportPrivate::dpiX(); + const qreal y = POINT_TO_INCH(pos.y()) * KReportPrivate::dpiY(); return QPointF(x, y); } QSizeF KReportItemBase::sceneSize(const QSizeF &size) { - const qreal w = POINT_TO_INCH(size.width()) * KReportDpi::dpiX(); - const qreal h = POINT_TO_INCH(size.height()) * KReportDpi::dpiY(); + const qreal w = POINT_TO_INCH(size.width()) * KReportPrivate::dpiX(); + const qreal h = POINT_TO_INCH(size.height()) * KReportPrivate::dpiY(); return QSizeF(w, h); } qreal KReportItemBase::z() const { return d->z; } void KReportItemBase::setZ(qreal z) { d->z = z; } void KReportItemBase::setPosition(const QPointF& pos) { d->positionProperty->setValue(pos); } void KReportItemBase::setSize(const QSizeF& size) { d->sizeProperty->setValue(size); } QPointF KReportItemBase::positionFromScene(const QPointF& pos) { - const qreal x = INCH_TO_POINT(pos.x() / KReportDpi::dpiX()); - const qreal y = INCH_TO_POINT(pos.y() / KReportDpi::dpiY()); + const qreal x = INCH_TO_POINT(pos.x() / KReportPrivate::dpiX()); + const qreal y = INCH_TO_POINT(pos.y() / KReportPrivate::dpiY()); return QPointF(x, y); } QSizeF KReportItemBase::sizeFromScene(const QSizeF& size) { - qreal w = INCH_TO_POINT(size.width() / KReportDpi::dpiX()); - qreal h = INCH_TO_POINT(size.height() / KReportDpi::dpiY()); + qreal w = INCH_TO_POINT(size.width() / KReportPrivate::dpiX()); + qreal h = INCH_TO_POINT(size.height() / KReportPrivate::dpiY()); return QSizeF(w, h); } void KReportItemBase::propertyChanged(KPropertySet& s, KProperty& p) { } diff --git a/src/common/KReportItemBase.h b/src/common/KReportItemBase.h index 3a4dddf1..7fac4e86 100644 --- a/src/common/KReportItemBase.h +++ b/src/common/KReportItemBase.h @@ -1,156 +1,155 @@ /* This file is part of the KDE project * Copyright (C) 2007-2010 by Adam Pigg (adam@piggz.co.uk) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #ifndef KREPORTITEMBASE_H #define KREPORTITEMBASE_H #include "config-kreport.h" #include "kreport_export.h" -#include "KReportDpi.h" #include "KReportUnit.h" #include #include #include class OROPage; class OROSection; class KReportSize; class KReportData; class KReportLineStyle; #ifdef KREPORT_SCRIPTING class KReportScriptHandler; #else #define KReportScriptHandler void #endif class KProperty; class KPropertySet; class QDomElement; class KRTextStyleData { public: QFont font; Qt::Alignment alignment; QColor backgroundColor; QColor foregroundColor; int backgroundOpacity; }; /* class KReportLineStyle { public: int weight; QColor lineColor; Qt::PenStyle style; }; */ /** */ class KREPORT_EXPORT KReportItemBase : public QObject { Q_OBJECT public: KReportItemBase(); virtual ~KReportItemBase(); /** @brief Return the item type as a string. Required by all items @return Item type */ virtual QString typeName() const = 0; /** @brief Render the item into a primitive which is used by the second stage renderer @return the height required by the object */ virtual int renderSimpleData(OROPage *page, OROSection *section, const QPointF &offset, const QVariant &data, KReportScriptHandler *script); /** @brief Render a complex item that uses a sub query as a data source @return the height required by the object */ virtual int renderReportData(OROPage *page, OROSection *section, const QPointF &offset, KReportData *data, KReportScriptHandler *script); /** @brief Override if the item supports a simple data source, such as a field @return The field name or expression for the data source */ virtual QString itemDataSource() const; /** @brief Override if the item uses a sub query and linked fields, such as a chart or sub-report @return True if uses a sub query */ virtual bool supportsSubQuery() const; KPropertySet* propertySet(); const KPropertySet* propertySet() const; void setEntityName(const QString& n); QString entityName() const; virtual void setUnit(const KReportUnit& u); /** * @brief Return the size in points */ QSizeF size() const; /** * @brief Return the position in points */ QPointF position() const; void setPosition(const QPointF &pos); void setSize(const QSizeF &siz); qreal z() const; void setZ(qreal z); //Helper function to map between size/position units static QPointF scenePosition(const QPointF &pos); static QSizeF sceneSize(const QSizeF &size); static QPointF positionFromScene(const QPointF &pos); static QSizeF sizeFromScene(const QSizeF &size); protected: virtual void createProperties() = 0; bool parseReportRect(const QDomElement &elem); static bool parseReportTextStyleData(const QDomElement &, KRTextStyleData*); static bool parseReportLineStyleData(const QDomElement &, KReportLineStyle*); KProperty *nameProperty(); QString oldName() const; void setOldName(const QString &old); Q_SLOT virtual void propertyChanged(KPropertySet &s, KProperty &p); private: Q_DISABLE_COPY(KReportItemBase) class Private; Private * const d; }; #endif diff --git a/src/common/KReportUtils_p.h b/src/common/KReportUtils_p.cpp similarity index 68% copy from src/common/KReportUtils_p.h copy to src/common/KReportUtils_p.cpp index 6db95a41..c70c8393 100644 --- a/src/common/KReportUtils_p.h +++ b/src/common/KReportUtils_p.cpp @@ -1,360 +1,312 @@ /* This file is part of the KDE project - Copyright (C) 2015-2016 Jarosław Staniek + Copyright (C) 2016 Adam Pigg This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#ifndef KREPORTUTILS_P_H -#define KREPORTUTILS_P_H +#include "KReportUtils_p.h" +#include "config-kreport.h" -#include +#ifdef Q_OS_WIN +#define KPATH_SEPARATOR ';' +#else +#define KPATH_SEPARATOR ':' +#endif -#include -#include -#include +class KReportDpiSingleton +{ +public: + KReportDpiSingleton(); -#include -#include -#include -#include -#include -#include -#include + int m_dpiX; + int m_dpiY; +}; -// This is a private code made inline for use in the lib and examples. -//! @todo Move to a shared lib to use in other Kexi libraries as well. +KReportDpiSingleton::KReportDpiSingleton() +{ + // Another way to get the DPI of the display would be QPaintDeviceMetrics, + // but we have no widget here (and moving this to KoView wouldn't allow + // using this from the document easily). +#ifdef Q_WS_X11 + m_dpiX = QX11Info::appDpiX(); + m_dpiY = QX11Info::appDpiY(); +#else + QDesktopWidget *w = QApplication::desktop(); + if (w) { + m_dpiX = w->logicalDpiX(); + m_dpiY = w->logicalDpiY(); + } else { + m_dpiX = 75; + m_dpiY = 75; + } +#endif +} + +Q_GLOBAL_STATIC(KReportDpiSingleton, s_instance) -namespace KReportPrivate { -//! @todo Support other themes -const QString supportedIconTheme = QLatin1String("breeze"); -//! @brief @return true if @a path is readable +namespace KReportPrivate +{ + bool fileReadable(const QString &path) { return !path.isEmpty() && QFileInfo(path).isReadable(); } -//! @brief Used for a workaround: locations for QStandardPaths::AppDataLocation end with app name. -//! If this is not an expected app but for example a test app, replace -//! the subdir name with app name so we can find resource file(s). QStringList correctStandardLocations(const QString &privateName, QStandardPaths::StandardLocation location, const QString &extraLocation) -{ + { QStringList result; if (!privateName.isEmpty()) { QRegularExpression re(QLatin1Char('/') + QCoreApplication::applicationName() + QLatin1Char('$')); QStringList standardLocations(QStandardPaths::standardLocations(location)); if (!extraLocation.isEmpty()) { standardLocations.append(extraLocation); } for(const QString &dir : standardLocations) { if (dir.indexOf(re) != -1) { QString realDir(dir); realDir.replace(re, QLatin1Char('/') + privateName); result.append(realDir); } } } return result; } -#ifdef Q_OS_WIN -#define KPATH_SEPARATOR ';' -#else -#define KPATH_SEPARATOR ':' -#endif - -/*! @brief Locates a file path for specified parameters - * @param privateName Name to be used instead of application name for resource lookup - * @param path Relative path to the resource file - * @param location Standard file location to use for file lookup - * @param extraLocation Extra directory path for file lookup - * @return Empty string on failure - */ QString locateFile(const QString &privateName, const QString& path, QStandardPaths::StandardLocation location, const QString &extraLocation) { // let QStandardPaths handle this, it will look for app local stuff QString fullPath = QFileInfo( QStandardPaths::locate(location, path)).canonicalFilePath(); if (fileReadable(fullPath)) { return fullPath; } // Try extra location fullPath = QFileInfo(extraLocation + QLatin1Char('/') + path).canonicalFilePath(); if (fileReadable(fullPath)) { return fullPath; } // Try in PATH subdirs, useful for running apps from the build dir, without installing for(const QByteArray &pathDir : qgetenv("PATH").split(KPATH_SEPARATOR)) { const QString dataDirFromPath = QFileInfo(QFile::decodeName(pathDir) + QStringLiteral("/data/") + path).canonicalFilePath(); if (fileReadable(dataDirFromPath)) { return dataDirFromPath; } } const QStringList correctedStandardLocations(correctStandardLocations(privateName, location, extraLocation)); for(const QString &dir : correctedStandardLocations) { fullPath = QFileInfo(dir + QLatin1Char('/') + path).canonicalFilePath(); if (fileReadable(fullPath)) { return fullPath; } } return QString(); } -/*! @brief Registers icons resource file - * @param privateName Name to be used instead of application name for resource lookup - * @param path Relative path to the resource file - * @param location Standard file location to use for file lookup - * @param resourceRoot A resource root for QResource::registerResource() - * @param errorMessage On failure it is set to a brief error message. - * @param errorDescription On failure it is set to a detailed error message. - * other for warning - */ bool registerIconsResource(const QString &privateName, const QString& path, QStandardPaths::StandardLocation location, const QString &resourceRoot, const QString &extraLocation, QString *errorMessage, QString *detailedErrorMessage) { const QString fullPath = locateFile(privateName, path, location, extraLocation); if (fullPath.isEmpty() || !QFileInfo(fullPath).isReadable() || !QResource::registerResource(fullPath, resourceRoot)) { QStringList triedLocations(QStandardPaths::standardLocations(location)); if (!extraLocation.isEmpty()) { triedLocations.append(extraLocation); } triedLocations.append(correctStandardLocations(privateName, location, extraLocation)); const QString triedLocationsString = QLocale().createSeparatedList(triedLocations); #ifdef QT_ONLY *errorMessage = QString("Could not open icon resource file %1.").arg(path); *detailedErrorMessage = QString("Tried to find in %1.").arg(triedLocationsString); #else //! @todo 3.1 Re-add translation *errorMessage = /*QObject::tr*/ QString::fromLatin1( "Could not open icon resource file \"%1\". " "Application will not start. " "Please check if it is properly installed.") .arg(QFileInfo(path).fileName()); //! @todo 3.1 Re-add translation *detailedErrorMessage = QString::fromLatin1("Tried to find in %1.").arg(triedLocationsString); #endif return false; } *errorMessage = QString(); *detailedErrorMessage = QString(); return true; } -/*! @brief Registers a global icon resource file - * @param themeName A name of icon theme to use. - * @param errorMessage On failure it is set to a brief error message. - * @param errorDescription On failure it is set to a detailed error message. - * other for warning - */ bool registerGlobalIconsResource(const QString &themeName, QString *errorMessage, QString *detailedErrorMessage) { QString extraLocation; #ifdef CMAKE_INSTALL_FULL_ICONDIR extraLocation = QDir::fromNativeSeparators(QFile::decodeName(CMAKE_INSTALL_FULL_ICONDIR)); if (extraLocation.endsWith("/icons")) { extraLocation.chop(QLatin1String("/icons").size()); } #elif defined(Q_OS_WIN) extraLocation = QCoreApplication::applicationDirPath() + QStringLiteral("/data"); #endif return registerIconsResource(QString(), QString::fromLatin1("icons/%1/%1-icons.rcc").arg(themeName), QStandardPaths::GenericDataLocation, QStringLiteral("/icons/") + themeName, extraLocation, errorMessage, detailedErrorMessage); } -/*! @brief Registers a global icon resource file - * @param themeName A name of icon theme to use. - */ bool registerGlobalIconsResource(const QString &themeName) { QString errorMessage; QString detailedErrorMessage; if (!registerGlobalIconsResource(themeName, &errorMessage, &detailedErrorMessage)) { if (detailedErrorMessage.isEmpty()) { KMessageBox::error(nullptr, errorMessage); } else { KMessageBox::detailedError(nullptr, errorMessage, detailedErrorMessage); } qWarning() << qPrintable(errorMessage); return false; } return true; } -/*! @brief Registers a global icon resource file for default theme name. - */ bool registerGlobalIconsResource() { return registerGlobalIconsResource(supportedIconTheme); } -/*! @brief Sets up a private icon resource file - * @return @c false on failure and sets error message. Does not warn or exit on failure. - * @param privateName Name to be used instead of application name for resource lookup - * @param path Relative path to the resource file - * @param themeName Icon theme to use. It affects filename. - * @param errorMessage On failure it is set to a brief error message - * @param errorDescription On failure it is set to a detailed error message - * other for warning - * @param prefix Resource path prefix. The default is useful for library-global resource, - * other values is useful for plugins. - */ bool setupPrivateIconsResource(const QString &privateName, const QString& path, const QString &themeName, QString *errorMessage, QString *detailedErrorMessage, - const QString &prefix = QLatin1String(":/icons")) + const QString &prefix) { // Register application's resource first to have priority over the theme. // Some icons may exists in both resources. if (!registerIconsResource(privateName, path, QStandardPaths::AppDataLocation, QString(), QString(), errorMessage, detailedErrorMessage)) { return false; } bool changeTheme = false; #ifdef QT_GUI_LIB QIcon::setThemeSearchPaths(QStringList() << prefix << QIcon::themeSearchPaths()); changeTheme = 0 != QIcon::themeName().compare(themeName, Qt::CaseInsensitive); if (changeTheme) { QIcon::setThemeName(themeName); } #endif KConfigGroup cg(KSharedConfig::openConfig(), "Icons"); changeTheme = changeTheme || 0 != cg.readEntry("Theme", QString()).compare(themeName, Qt::CaseInsensitive); // tell KIconLoader an co. about the theme if (changeTheme) { cg.writeEntry("Theme", themeName); cg.sync(); } return true; } -/*! @brief Sets up a private icon resource file - * @return @c false on failure and sets error message. - * @param privateName Name to be used instead of application name for resource lookup - * @param path Relative path to the resource file - * @param themeName Icon theme to use. It affects filename. - * @param errorMessage On failure it is set to a brief error message. - * @param errorDescription On failure it is set to a detailed error message. - * other for warning - * @param prefix Resource path prefix. The default is useful for library-global resource, - * other values is useful for plugins. - */ bool setupPrivateIconsResourceWithMessage(const QString &privateName, const QString& path, const QString &themeName, QString *errorMessage, QString *detailedErrorMessage, - const QString &prefix = QLatin1String(":/icons")) + const QString &prefix) { if (!setupPrivateIconsResource(privateName, path, themeName, errorMessage, detailedErrorMessage, prefix)) { if (detailedErrorMessage->isEmpty()) { KMessageBox::error(nullptr, *errorMessage); } else { KMessageBox::detailedError(nullptr, *errorMessage, *detailedErrorMessage); } return false; } return true; } -/*! @overload setupPrivateIconsResourceWithMessage(QString &privateName, const QString& path, - const QString &themeName, - QString *errorMessage, QString *detailedErrorMessage, - const QString &prefix = QLatin1String(":/icons")) - Uses default theme name. - */ bool setupPrivateIconsResourceWithMessage(const QString &privateName, const QString& path, QString *errorMessage, QString *detailedErrorMessage, - const QString &prefix = QLatin1String(":/icons")) + const QString &prefix) { return setupPrivateIconsResourceWithMessage(privateName, path, supportedIconTheme, errorMessage, detailedErrorMessage, prefix); } -/*! @brief Sets up a private icon resource file - * Warns on failure and returns @c false. - * @param privateName Name to be used instead of application name for resource lookup - * @param path Relative path to the resource file - * @param messageType Type of message to use on error, QtFatalMsg for fatal exit and any - * other for warning - * @param prefix Resource path prefix. The default is useful for library-global resource, - * other values is useful for plugins. - */ bool setupPrivateIconsResourceWithMessage(const QString &privateName, const QString& path, QtMsgType messageType, - const QString &prefix = QLatin1String(":/icons")) + const QString &prefix) { QString errorMessage; QString detailedErrorMessage; if (!setupPrivateIconsResourceWithMessage(privateName, path, &errorMessage, &detailedErrorMessage, prefix)) { if (messageType == QtFatalMsg) { qFatal("%s %s", qPrintable(errorMessage), qPrintable(detailedErrorMessage)); } else { qWarning() << qPrintable(errorMessage) << qPrintable(detailedErrorMessage); } return false; } return true; } -//! Sets up a global icon theme if it is different from supported. -//! Warns on failure and returns @c false. bool setupGlobalIconTheme() { if (0 != QIcon::themeName().compare(supportedIconTheme, Qt::CaseInsensitive)) { const QString message = QString::fromLatin1( "\"%1\" supports only \"%2\" icon theme but current system theme is \"%3\". " "Application's icon theme will be changed to \"%2\". " "Please consider adding support for other themes to %4.") .arg(QLatin1String(KREPORT_BASE_NAME)).arg(supportedIconTheme).arg(QIcon::themeName()) .arg(QCoreApplication::applicationName()); qDebug() << qPrintable(message); if (!registerGlobalIconsResource()) { // don't fail, just warn const QString message = QString::fromLatin1( "Failed to set icon theme to \"%1\". Icons in the application will be inconsistent. " "Please install .rcc file(s) for the system theme.") .arg(supportedIconTheme); qDebug() << qPrintable(message); return false; } } return true; } -} // KReportPrivate +int dpiX() +{ + return s_instance->m_dpiX; +} -#endif +int dpiY() +{ + return s_instance->m_dpiY; +} + +} diff --git a/src/common/KReportUtils_p.h b/src/common/KReportUtils_p.h index 6db95a41..5d4351b1 100644 --- a/src/common/KReportUtils_p.h +++ b/src/common/KReportUtils_p.h @@ -1,360 +1,173 @@ /* This file is part of the KDE project Copyright (C) 2015-2016 Jarosław Staniek This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KREPORTUTILS_P_H #define KREPORTUTILS_P_H - #include #include #include #include #include #include #include #include #include #include #include +#include + +#ifdef Q_WS_X11 +#include +#else +#include +#endif + // This is a private code made inline for use in the lib and examples. //! @todo Move to a shared lib to use in other Kexi libraries as well. namespace KReportPrivate { //! @todo Support other themes const QString supportedIconTheme = QLatin1String("breeze"); //! @brief @return true if @a path is readable -bool fileReadable(const QString &path) -{ - return !path.isEmpty() && QFileInfo(path).isReadable(); -} +bool fileReadable(const QString &path); //! @brief Used for a workaround: locations for QStandardPaths::AppDataLocation end with app name. //! If this is not an expected app but for example a test app, replace //! the subdir name with app name so we can find resource file(s). QStringList correctStandardLocations(const QString &privateName, QStandardPaths::StandardLocation location, - const QString &extraLocation) -{ - QStringList result; - if (!privateName.isEmpty()) { - QRegularExpression re(QLatin1Char('/') + QCoreApplication::applicationName() + QLatin1Char('$')); - QStringList standardLocations(QStandardPaths::standardLocations(location)); - if (!extraLocation.isEmpty()) { - standardLocations.append(extraLocation); - } - for(const QString &dir : standardLocations) { - if (dir.indexOf(re) != -1) { - QString realDir(dir); - realDir.replace(re, QLatin1Char('/') + privateName); - result.append(realDir); - } - } - } - return result; -} + const QString &extraLocation); + -#ifdef Q_OS_WIN -#define KPATH_SEPARATOR ';' -#else -#define KPATH_SEPARATOR ':' -#endif /*! @brief Locates a file path for specified parameters * @param privateName Name to be used instead of application name for resource lookup * @param path Relative path to the resource file * @param location Standard file location to use for file lookup * @param extraLocation Extra directory path for file lookup * @return Empty string on failure */ QString locateFile(const QString &privateName, const QString& path, QStandardPaths::StandardLocation location, - const QString &extraLocation) -{ - // let QStandardPaths handle this, it will look for app local stuff - QString fullPath = QFileInfo( - QStandardPaths::locate(location, path)).canonicalFilePath(); - if (fileReadable(fullPath)) { - return fullPath; - } - - // Try extra location - fullPath = QFileInfo(extraLocation + QLatin1Char('/') + path).canonicalFilePath(); - if (fileReadable(fullPath)) { - return fullPath; - } - // Try in PATH subdirs, useful for running apps from the build dir, without installing - for(const QByteArray &pathDir : qgetenv("PATH").split(KPATH_SEPARATOR)) { - const QString dataDirFromPath = QFileInfo(QFile::decodeName(pathDir) + QStringLiteral("/data/") - + path).canonicalFilePath(); - if (fileReadable(dataDirFromPath)) { - return dataDirFromPath; - } - } - - const QStringList correctedStandardLocations(correctStandardLocations(privateName, location, extraLocation)); - for(const QString &dir : correctedStandardLocations) { - fullPath = QFileInfo(dir + QLatin1Char('/') + path).canonicalFilePath(); - if (fileReadable(fullPath)) { - return fullPath; - } - } - return QString(); -} + const QString &extraLocation); /*! @brief Registers icons resource file * @param privateName Name to be used instead of application name for resource lookup * @param path Relative path to the resource file * @param location Standard file location to use for file lookup * @param resourceRoot A resource root for QResource::registerResource() * @param errorMessage On failure it is set to a brief error message. * @param errorDescription On failure it is set to a detailed error message. * other for warning */ bool registerIconsResource(const QString &privateName, const QString& path, QStandardPaths::StandardLocation location, const QString &resourceRoot, const QString &extraLocation, - QString *errorMessage, QString *detailedErrorMessage) -{ - const QString fullPath = locateFile(privateName, path, location, extraLocation); - if (fullPath.isEmpty() || !QFileInfo(fullPath).isReadable() - || !QResource::registerResource(fullPath, resourceRoot)) - { - QStringList triedLocations(QStandardPaths::standardLocations(location)); - if (!extraLocation.isEmpty()) { - triedLocations.append(extraLocation); - } - triedLocations.append(correctStandardLocations(privateName, location, extraLocation)); - const QString triedLocationsString = QLocale().createSeparatedList(triedLocations); -#ifdef QT_ONLY - *errorMessage = QString("Could not open icon resource file %1.").arg(path); - *detailedErrorMessage = QString("Tried to find in %1.").arg(triedLocationsString); -#else - //! @todo 3.1 Re-add translation - *errorMessage = /*QObject::tr*/ QString::fromLatin1( - "Could not open icon resource file \"%1\". " - "Application will not start. " - "Please check if it is properly installed.") - .arg(QFileInfo(path).fileName()); - //! @todo 3.1 Re-add translation - *detailedErrorMessage = QString::fromLatin1("Tried to find in %1.").arg(triedLocationsString); -#endif - return false; - } - *errorMessage = QString(); - *detailedErrorMessage = QString(); - return true; -} + QString *errorMessage, QString *detailedErrorMessage); /*! @brief Registers a global icon resource file * @param themeName A name of icon theme to use. * @param errorMessage On failure it is set to a brief error message. * @param errorDescription On failure it is set to a detailed error message. * other for warning */ bool registerGlobalIconsResource(const QString &themeName, QString *errorMessage, - QString *detailedErrorMessage) -{ - QString extraLocation; -#ifdef CMAKE_INSTALL_FULL_ICONDIR - extraLocation = QDir::fromNativeSeparators(QFile::decodeName(CMAKE_INSTALL_FULL_ICONDIR)); - if (extraLocation.endsWith("/icons")) { - extraLocation.chop(QLatin1String("/icons").size()); - } -#elif defined(Q_OS_WIN) - extraLocation = QCoreApplication::applicationDirPath() + QStringLiteral("/data"); -#endif - return registerIconsResource(QString(), QString::fromLatin1("icons/%1/%1-icons.rcc").arg(themeName), - QStandardPaths::GenericDataLocation, - QStringLiteral("/icons/") + themeName, - extraLocation, errorMessage, - detailedErrorMessage); -} + QString *detailedErrorMessage); /*! @brief Registers a global icon resource file * @param themeName A name of icon theme to use. */ -bool registerGlobalIconsResource(const QString &themeName) -{ - QString errorMessage; - QString detailedErrorMessage; - if (!registerGlobalIconsResource(themeName, &errorMessage, &detailedErrorMessage)) { - if (detailedErrorMessage.isEmpty()) { - KMessageBox::error(nullptr, errorMessage); - } else { - KMessageBox::detailedError(nullptr, errorMessage, detailedErrorMessage); - } - qWarning() << qPrintable(errorMessage); - return false; - } - return true; -} +bool registerGlobalIconsResource(const QString &themeName); /*! @brief Registers a global icon resource file for default theme name. */ -bool registerGlobalIconsResource() -{ - return registerGlobalIconsResource(supportedIconTheme); -} +bool registerGlobalIconsResource(); /*! @brief Sets up a private icon resource file * @return @c false on failure and sets error message. Does not warn or exit on failure. * @param privateName Name to be used instead of application name for resource lookup * @param path Relative path to the resource file * @param themeName Icon theme to use. It affects filename. * @param errorMessage On failure it is set to a brief error message * @param errorDescription On failure it is set to a detailed error message * other for warning * @param prefix Resource path prefix. The default is useful for library-global resource, * other values is useful for plugins. */ bool setupPrivateIconsResource(const QString &privateName, const QString& path, const QString &themeName, QString *errorMessage, QString *detailedErrorMessage, - const QString &prefix = QLatin1String(":/icons")) -{ - // Register application's resource first to have priority over the theme. - // Some icons may exists in both resources. - if (!registerIconsResource(privateName, path, - QStandardPaths::AppDataLocation, - QString(), QString(), errorMessage, detailedErrorMessage)) - { - return false; - } - bool changeTheme = false; -#ifdef QT_GUI_LIB - QIcon::setThemeSearchPaths(QStringList() << prefix << QIcon::themeSearchPaths()); - changeTheme = 0 != QIcon::themeName().compare(themeName, Qt::CaseInsensitive); - if (changeTheme) { - QIcon::setThemeName(themeName); - } -#endif - - KConfigGroup cg(KSharedConfig::openConfig(), "Icons"); - changeTheme = changeTheme || 0 != cg.readEntry("Theme", QString()).compare(themeName, Qt::CaseInsensitive); - // tell KIconLoader an co. about the theme - if (changeTheme) { - cg.writeEntry("Theme", themeName); - cg.sync(); - } - return true; -} + const QString &prefix = QLatin1String(":/icons")); /*! @brief Sets up a private icon resource file * @return @c false on failure and sets error message. * @param privateName Name to be used instead of application name for resource lookup * @param path Relative path to the resource file * @param themeName Icon theme to use. It affects filename. * @param errorMessage On failure it is set to a brief error message. * @param errorDescription On failure it is set to a detailed error message. * other for warning * @param prefix Resource path prefix. The default is useful for library-global resource, * other values is useful for plugins. */ bool setupPrivateIconsResourceWithMessage(const QString &privateName, const QString& path, const QString &themeName, QString *errorMessage, QString *detailedErrorMessage, - const QString &prefix = QLatin1String(":/icons")) -{ - if (!setupPrivateIconsResource(privateName, path, themeName, - errorMessage, detailedErrorMessage, prefix)) - { - if (detailedErrorMessage->isEmpty()) { - KMessageBox::error(nullptr, *errorMessage); - } else { - KMessageBox::detailedError(nullptr, *errorMessage, *detailedErrorMessage); - } - return false; - } - return true; -} + const QString &prefix = QLatin1String(":/icons")); /*! @overload setupPrivateIconsResourceWithMessage(QString &privateName, const QString& path, const QString &themeName, QString *errorMessage, QString *detailedErrorMessage, const QString &prefix = QLatin1String(":/icons")) Uses default theme name. */ bool setupPrivateIconsResourceWithMessage(const QString &privateName, const QString& path, QString *errorMessage, QString *detailedErrorMessage, - const QString &prefix = QLatin1String(":/icons")) -{ - return setupPrivateIconsResourceWithMessage(privateName, path, supportedIconTheme, - errorMessage, detailedErrorMessage, prefix); -} + const QString &prefix = QLatin1String(":/icons")); /*! @brief Sets up a private icon resource file * Warns on failure and returns @c false. * @param privateName Name to be used instead of application name for resource lookup * @param path Relative path to the resource file * @param messageType Type of message to use on error, QtFatalMsg for fatal exit and any * other for warning * @param prefix Resource path prefix. The default is useful for library-global resource, * other values is useful for plugins. */ bool setupPrivateIconsResourceWithMessage(const QString &privateName, const QString& path, QtMsgType messageType, - const QString &prefix = QLatin1String(":/icons")) -{ - QString errorMessage; - QString detailedErrorMessage; - if (!setupPrivateIconsResourceWithMessage(privateName, path, - &errorMessage, &detailedErrorMessage, prefix)) { - if (messageType == QtFatalMsg) { - qFatal("%s %s", qPrintable(errorMessage), qPrintable(detailedErrorMessage)); - } else { - qWarning() << qPrintable(errorMessage) << qPrintable(detailedErrorMessage); - } - return false; - } - return true; -} + const QString &prefix = QLatin1String(":/icons")); //! Sets up a global icon theme if it is different from supported. //! Warns on failure and returns @c false. -bool setupGlobalIconTheme() -{ - if (0 != QIcon::themeName().compare(supportedIconTheme, Qt::CaseInsensitive)) { - const QString message = QString::fromLatin1( - "\"%1\" supports only \"%2\" icon theme but current system theme is \"%3\". " - "Application's icon theme will be changed to \"%2\". " - "Please consider adding support for other themes to %4.") - .arg(QLatin1String(KREPORT_BASE_NAME)).arg(supportedIconTheme).arg(QIcon::themeName()) - .arg(QCoreApplication::applicationName()); - qDebug() << qPrintable(message); - if (!registerGlobalIconsResource()) { - // don't fail, just warn - const QString message = QString::fromLatin1( - "Failed to set icon theme to \"%1\". Icons in the application will be inconsistent. " - "Please install .rcc file(s) for the system theme.") - .arg(supportedIconTheme); - qDebug() << qPrintable(message); - return false; - } - } - return true; -} +bool setupGlobalIconTheme(); + +int dpiX(); + +int dpiY(); } // KReportPrivate #endif diff --git a/src/renderer/KReportPage.cpp b/src/renderer/KReportPage.cpp index cd3b2230..1cec5aba 100644 --- a/src/renderer/KReportPage.cpp +++ b/src/renderer/KReportPage.cpp @@ -1,131 +1,131 @@ /* This file is part of the KDE project * Copyright (C) 2007-2008 by Adam Pigg (adam@piggz.co.uk) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include "KReportPage.h" #include "KReportRendererBase.h" #include "KReportUnit.h" #include "KReportRenderObjects.h" -#include "KReportDpi.h" +#include "KReportUtils_p.h" #include "kreport_debug.h" #include #include #include #include //! @internal class Q_DECL_HIDDEN KReportPage::Private { public: explicit Private(ORODocument *document) : reportDocument(document) , page(0) {} ~Private() { delete renderer; } ORODocument *reportDocument; int page; QPixmap pixmap; KReportRendererFactory factory; KReportRendererBase *renderer; QTimer renderTimer; }; KReportPage::KReportPage(QWidget *parent, ORODocument *document) : QObject(parent), QGraphicsRectItem() , d(new Private(document)) { Q_ASSERT(document); int pageWidth; int pageHeight; QString pageSize = d->reportDocument->pageLayout().pageSize().name(); - pageWidth = d->reportDocument->pageLayout().fullRectPixels(KReportDpi::dpiX()).width(); - pageHeight = d->reportDocument->pageLayout().fullRectPixels(KReportDpi::dpiX()).height(); + pageWidth = d->reportDocument->pageLayout().fullRectPixels(KReportPrivate::dpiX()).width(); + pageHeight = d->reportDocument->pageLayout().fullRectPixels(KReportPrivate::dpiX()).height(); //TODO remove after check #if 0 if (pageSize == QLatin1String("Custom")) { // if this is custom sized sheet of paper we will just use those values } else { // lookup the correct size information for the specified size paper pageWidth = d->reportDocument->pageOptions().pixelSize().width(); pageHeight = d->reportDocument->pageOptions().pixelSize().height(); } #endif setRect(0, 0, pageWidth, pageHeight); //kreportDebug() << "PAGE IS " << pageWidth << "x" << pageHeight; d->pixmap = QPixmap(pageWidth, pageHeight); d->renderer = d->factory.createInstance(QLatin1String("screen")); connect(d->reportDocument, SIGNAL(updated(int)), this, SLOT(pageUpdated(int))); d->renderTimer.setSingleShot(true); connect(&d->renderTimer, SIGNAL(timeout()), this, SLOT(renderCurrentPage())); renderPage(1); } KReportPage::~KReportPage() { delete d; } void KReportPage::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) { Q_UNUSED(option); Q_UNUSED(widget); painter->drawPixmap(QPoint(0, 0), d->pixmap); } void KReportPage::renderPage(int page) { d->page = page - 1; d->pixmap.fill(); QPainter qp(&d->pixmap); if (d->reportDocument) { KReportRendererContext cxt; cxt.setPainter(&qp); d->renderer->render(cxt, d->reportDocument, d->page); } update(); } void KReportPage::pageUpdated(int pageNo) { //kreportDebug() << pageNo << d->page; //Refresh this page if it changes if (pageNo == d->page) { //kreportDebug() << "Current page updated"; d->renderTimer.start(100); } } void KReportPage::renderCurrentPage() { renderPage(d->page + 1); } diff --git a/src/renderer/KReportPreRenderer.cpp b/src/renderer/KReportPreRenderer.cpp index ca565063..c645777e 100644 --- a/src/renderer/KReportPreRenderer.cpp +++ b/src/renderer/KReportPreRenderer.cpp @@ -1,698 +1,698 @@ /* This file is part of the KDE project * Copyright (C) 2001-2007 by OpenMFG, LLC (info@openmfg.com) * Copyright (C) 2007-2008 by Adam Pigg (adam@piggz.co.uk) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include "KReportPreRenderer.h" #include "KReportPreRenderer_p.h" #include "KReportAsyncItemManager_p.h" #include "KReportOneRecordData_p.h" #include "KReportRenderObjects.h" #include "KReportData.h" #include "KReportItemBase.h" #include "KReportDocument.h" #include "KReportDetailSectionData.h" #include "KReportLabelSizeInfo.h" #include "KReportPageSize.h" -#include "KReportDpi.h" +#include "KReportUtils_p.h" #ifdef KREPORT_SCRIPTING #include "scripting/KReportScriptHandler.h" #include "scripting/KReportGroupTracker.h" #endif #include #include #include "kreport_debug.h" KReportPreRendererPrivate::KReportPreRendererPrivate(KReportPreRenderer *preRenderer) : m_preRenderer(preRenderer) { m_valid = false; m_document = 0; m_reportDocument = 0; m_page = 0; m_yOffset = 0.0; m_topMargin = m_bottomMargin = 0.0; m_leftMargin = m_rightMargin = 0.0; m_pageCounter = 0; m_maxHeight = m_maxWidth = 0.0; m_oneRecord = new KReportPrivate::OneRecordData(); m_kodata = 0; #ifdef KREPORT_SCRIPTING m_scriptHandler = 0; #endif asyncManager = new KReportPrivate::AsyncItemManager(this); connect(asyncManager, SIGNAL(finished()), this, SLOT(asyncItemsFinished())); } KReportPreRendererPrivate::~KReportPreRendererPrivate() { delete m_reportDocument; delete m_document; delete m_oneRecord; m_postProcText.clear(); } void KReportPreRendererPrivate::createNewPage() { //kreportDebug(); if (m_pageCounter > 0) finishCurPage(); m_pageCounter++; #ifdef KREPORT_SCRIPTING //Update the page count script value m_scriptHandler->setPageNumber(m_pageCounter); m_scriptHandler->newPage(); #endif m_page = new OROPage(0); m_document->addPage(m_page); //! @todo calculate past page bool lastPage = false; m_yOffset = m_topMargin; if (m_pageCounter == 1 && m_reportDocument->m_pageHeaderFirst) renderSection(*(m_reportDocument->m_pageHeaderFirst)); else if (lastPage == true && m_reportDocument->m_pageHeaderLast) renderSection(*(m_reportDocument->m_pageHeaderLast)); else if ((m_pageCounter % 2) == 1 && m_reportDocument->m_pageHeaderOdd) renderSection(*(m_reportDocument->m_pageHeaderOdd)); else if ((m_pageCounter % 2) == 0 && m_reportDocument->m_pageHeaderAny) renderSection(*(m_reportDocument->m_pageHeaderAny)); else if (m_reportDocument->m_pageHeaderAny) renderSection(*(m_reportDocument->m_pageHeaderAny)); } qreal KReportPreRendererPrivate::finishCurPageSize(bool lastPage) { qreal retval = 0.0; if (lastPage && m_reportDocument->m_pageFooterLast) retval = renderSectionSize(* (m_reportDocument->m_pageFooterLast)); else if (m_pageCounter == 1 && m_reportDocument->m_pageFooterFirst) retval = renderSectionSize(* (m_reportDocument->m_pageFooterFirst)); else if ((m_pageCounter % 2) == 1 && m_reportDocument->m_pageFooterOdd) retval = renderSectionSize(* (m_reportDocument->m_pageFooterOdd)); else if ((m_pageCounter % 2) == 0 && m_reportDocument->m_pageFooterEven) retval = renderSectionSize(* (m_reportDocument->m_pageFooterEven)); else if (m_reportDocument->m_pageFooterAny) retval = renderSectionSize(* (m_reportDocument->m_pageFooterAny)); //kreportDebug() << retval; return retval; } qreal KReportPreRendererPrivate::finishCurPage(bool lastPage) { qreal offset = m_maxHeight - m_bottomMargin; qreal retval = 0.0; //kreportDebug() << offset; if (lastPage && m_reportDocument->m_pageFooterLast) { //kreportDebug() << "Last Footer"; m_yOffset = offset - renderSectionSize(* (m_reportDocument->m_pageFooterLast)); retval = renderSection(* (m_reportDocument->m_pageFooterLast)); } else if (m_pageCounter == 1 && m_reportDocument->m_pageFooterFirst) { //kreportDebug() << "First Footer"; m_yOffset = offset - renderSectionSize(* (m_reportDocument->m_pageFooterFirst)); retval = renderSection(* (m_reportDocument->m_pageFooterFirst)); } else if ((m_pageCounter % 2) == 1 && m_reportDocument->m_pageFooterOdd) { //kreportDebug() << "Odd Footer"; m_yOffset = offset - renderSectionSize(* (m_reportDocument->m_pageFooterOdd)); retval = renderSection(* (m_reportDocument->m_pageFooterOdd)); } else if ((m_pageCounter % 2) == 0 && m_reportDocument->m_pageFooterEven) { //kreportDebug() << "Even Footer"; m_yOffset = offset - renderSectionSize(* (m_reportDocument->m_pageFooterEven)); retval = renderSection(* (m_reportDocument->m_pageFooterEven)); } else if (m_reportDocument->m_pageFooterAny) { //kreportDebug() << "Any Footer"; m_yOffset = offset - renderSectionSize(* (m_reportDocument->m_pageFooterAny)); retval = renderSection(* (m_reportDocument->m_pageFooterAny)); } return retval; } void KReportPreRendererPrivate::renderDetailSection(KReportDetailSectionData *detailData) { if (detailData->m_detailSection) { if (m_kodata/* && !curs->eof()*/) { QStringList keys; QStringList keyValues; QList shownGroups; KReportDetailGroupSectionData * grp = 0; bool status = m_kodata->moveFirst(); int recordCount = m_kodata->recordCount(); //kreportDebug() << "Record Count:" << recordCount; for (int i = 0; i < (int) detailData->m_groupList.count(); ++i) { grp = detailData->m_groupList[i]; //If the group has a header or footer, then emit a change of group value if(grp->m_groupFooter || grp->m_groupHeader) { // we get here only if group is *shown* shownGroups << i; keys.append(grp->m_column); if (!keys.last().isEmpty()) keyValues.append(m_kodata->value(m_kodata->fieldNumber(keys.last())).toString()); else keyValues.append(QString()); //Tell interested parties we're about to render a header emit(enteredGroup(keys.last(), keyValues.last())); } if (grp->m_groupHeader) renderSection(*(grp->m_groupHeader)); } while (status) { const qint64 pos = m_kodata->at(); //kreportDebug() << "At:" << l << "Y:" << m_yOffset << "Max Height:" << m_maxHeight; if ((renderSectionSize(*detailData->m_detailSection) + finishCurPageSize((pos + 1 == recordCount)) + m_bottomMargin + m_yOffset) >= m_maxHeight) { //kreportDebug() << "Next section is too big for this page"; if (pos > 0) { m_kodata->movePrevious(); createNewPage(); m_kodata->moveNext(); } } renderSection(*(detailData->m_detailSection)); if (m_kodata) status = m_kodata->moveNext(); if (status == true && keys.count() > 0) { // check to see where it is we need to start int pos = -1; // if it's still -1 by the time we are done then no keyValues changed for (int i = 0; i < keys.count(); ++i) { if (keyValues[i] != m_kodata->value(m_kodata->fieldNumber(keys[i])).toString()) { pos = i; break; } } // don't bother if nothing has changed if (pos != -1) { // roll back the query and go ahead if all is good status = m_kodata->movePrevious(); if (status == true) { // print the footers as needed // any changes made in this for loop need to be duplicated // below where the footers are finished. bool do_break = false; for (int i = shownGroups.count() - 1; i >= 0; i--) { if (do_break) createNewPage(); do_break = false; grp = detailData->m_groupList[shownGroups.at(i)]; if (grp->m_groupFooter) { if (renderSectionSize(*(grp->m_groupFooter)) + finishCurPageSize() + m_bottomMargin + m_yOffset >= m_maxHeight) createNewPage(); renderSection(*(grp->m_groupFooter)); } if (KReportDetailGroupSectionData::BreakAfterGroupFooter == grp->m_pagebreak) do_break = true; } // step ahead to where we should be and print the needed headers // if all is good status = m_kodata->moveNext(); if (do_break) createNewPage(); if (status == true) { for (int i = 0; i < shownGroups.count(); ++i) { grp = detailData->m_groupList[shownGroups.at(i)]; if (grp->m_groupHeader) { if (renderSectionSize(*(grp->m_groupHeader)) + finishCurPageSize() + m_bottomMargin + m_yOffset >= m_maxHeight) { m_kodata->movePrevious(); createNewPage(); m_kodata->moveNext(); } if (!keys[i].isEmpty()) keyValues[i] = m_kodata->value(m_kodata->fieldNumber(keys[i])).toString(); //Tell interested parties thak key values changed renderSection(*(grp->m_groupHeader)); } } } } } } } if (keys.size() > 0 && m_kodata->movePrevious()) { // finish footers // duplicated changes from above here for (int i = shownGroups.count() - 1; i >= 0; i--) { grp = detailData->m_groupList[shownGroups.at(i)]; if (grp->m_groupFooter) { if (renderSectionSize(*(grp->m_groupFooter)) + finishCurPageSize() + m_bottomMargin + m_yOffset >= m_maxHeight) createNewPage(); renderSection(*(grp->m_groupFooter)); emit(exitedGroup(keys[i], keyValues[i])); } } } } if (KReportDetailSectionData::BreakAtEnd == detailData->m_pageBreak) createNewPage(); } } qreal KReportPreRendererPrivate::renderSectionSize(const KReportSectionData & sectionData) { - qreal intHeight = POINT_TO_INCH(sectionData.height()) * KReportDpi::dpiX(); + qreal intHeight = POINT_TO_INCH(sectionData.height()) * KReportPrivate::dpiX(); int itemHeight = 0; if (sectionData.objects().count() == 0) return intHeight; QList objects = sectionData.objects(); foreach(KReportItemBase *ob, objects) { QPointF offset(m_leftMargin, m_yOffset); QVariant itemData = m_kodata->value(ob->itemDataSource()); //ASync objects cannot alter the section height KReportAsyncItemBase *async_ob = qobject_cast(ob); if (!async_ob) { itemHeight = ob->renderSimpleData(0, 0, offset, itemData, m_scriptHandler); if (itemHeight > intHeight) { intHeight = itemHeight; } } } return intHeight; } qreal KReportPreRendererPrivate::renderSection(const KReportSectionData & sectionData) { - qreal sectionHeight = POINT_TO_INCH(sectionData.height()) * KReportDpi::dpiX(); + qreal sectionHeight = POINT_TO_INCH(sectionData.height()) * KReportPrivate::dpiX(); int itemHeight = 0; //kreportDebug() << "Name: " << sectionData.name() << " Height: " << sectionHeight // << "Objects: " << sectionData.objects().count(); emit(renderingSection(const_cast(§ionData), m_page, QPointF(m_leftMargin, m_yOffset))); //Create a pre-rendered section for this section and add it to the document OROSection *sec = new OROSection(m_document); sec->setHeight(sectionData.height()); sec->setBackgroundColor(sectionData.backgroundColor()); sec->setType(sectionData.type()); m_document->addSection(sec); //Render section background ORORect* bg = new ORORect(); bg->setPen(QPen(Qt::NoPen)); bg->setBrush(sectionData.backgroundColor()); - qreal w = m_page->document()->pageLayout().fullRectPixels(KReportDpi::dpiX()).width() - m_page->document()->pageLayout().marginsPixels(KReportDpi::dpiX()).right() - m_leftMargin; + qreal w = m_page->document()->pageLayout().fullRectPixels(KReportPrivate::dpiX()).width() - m_page->document()->pageLayout().marginsPixels(KReportPrivate::dpiX()).right() - m_leftMargin; bg->setRect(QRectF(m_leftMargin, m_yOffset, w, sectionHeight)); m_page->insertPrimitive(bg, true); QList objects = sectionData.objects(); foreach(KReportItemBase *ob, objects) { QPointF offset(m_leftMargin, m_yOffset); QVariant itemData = m_kodata->value(ob->itemDataSource()); if (ob->supportsSubQuery()) { itemHeight = ob->renderReportData(m_page, sec, offset, m_kodata, m_scriptHandler); } else { KReportAsyncItemBase *async_ob = qobject_cast(ob); if (async_ob){ //kreportDebug() << "async object"; asyncManager->addItem(async_ob, m_page, sec, offset, itemData, m_scriptHandler); } else { //kreportDebug() << "sync object"; itemHeight = ob->renderSimpleData(m_page, sec, offset, itemData, m_scriptHandler); } } if (itemHeight > sectionHeight) { sectionHeight = itemHeight; } } for (int i = 0; i < m_page->primitiveCount(); ++i) { OROPrimitive *prim = m_page->primitive(i); if (dynamic_cast(prim)) { OROTextBox *text = dynamic_cast(prim); if (text->requiresPostProcessing()) { m_postProcText.append(text); } } } m_yOffset += sectionHeight; return sectionHeight; } #ifdef KREPORT_SCRIPTING void KReportPreRendererPrivate::initEngine() { delete m_scriptHandler; m_scriptHandler = new KReportScriptHandler(m_kodata, m_reportDocument); connect(this, SIGNAL(enteredGroup(QString,QVariant)), m_scriptHandler, SLOT(slotEnteredGroup(QString,QVariant))); connect(this, SIGNAL(exitedGroup(QString,QVariant)), m_scriptHandler, SLOT(slotExitedGroup(QString,QVariant))); connect(this, SIGNAL(renderingSection(KReportSectionData*,OROPage*,QPointF)), m_scriptHandler, SLOT(slotEnteredSection(KReportSectionData*,OROPage*,QPointF))); } #endif void KReportPreRendererPrivate::asyncItemsFinished() { //kreportDebug() << "Finished rendering async items"; asyncManager->deleteLater(); emit finishedAllASyncItems(); } bool KReportPreRendererPrivate::generateDocument() { if (!m_kodata) { m_kodata = m_oneRecord; } if (!m_valid || !m_reportDocument) { return false; } // Do this check now so we don't have to undo a lot of work later if it fails KReportLabelSizeInfo label; if (m_reportDocument->pageSize() == QLatin1String("Labels")) { label = KReportLabelSizeInfo::find(m_reportDocument->labelType()); if (label.isNull()) { return false; } } //kreportDebug() << "Creating Document"; m_document = new ORODocument(m_reportDocument->title()); m_pageCounter = 0; m_yOffset = 0.0; //kreportDebug() << "Calculating Margins"; if (!label.isNull()) { if (m_reportDocument->pageLayout().orientation() == QPageLayout::Portrait) { m_topMargin = (label.startY() / 100.0); m_bottomMargin = 0; m_rightMargin = 0; m_leftMargin = (label.startX() / 100.0); } else { m_topMargin = (label.startX() / 100.0); m_bottomMargin = 0; m_rightMargin = 0; m_leftMargin = (label.startY() / 100.0); } } else { m_topMargin = m_reportDocument->pageLayout().marginsPoints().top(); m_bottomMargin = m_reportDocument->pageLayout().marginsPoints().bottom(); m_rightMargin = m_reportDocument->pageLayout().marginsPoints().right(); m_leftMargin = m_reportDocument->pageLayout().marginsPoints().left(); //kreportDebug() << "Margins:" << m_topMargin << m_bottomMargin << m_rightMargin << m_leftMargin; } //kreportDebug() << "Calculating Page Size"; QPageLayout layout = m_reportDocument->pageLayout(); // This should reflect the information of the report page size if (m_reportDocument->pageSize() == QLatin1String("Custom")) { m_maxWidth = m_reportDocument->pageLayout().fullRectPoints().width(); m_maxHeight = m_reportDocument->pageLayout().fullRectPoints().height(); } else { if (!label.isNull()) { m_maxWidth = label.width(); m_maxHeight = label.height(); m_reportDocument->pageLayout().setPageSize(QPageSize(KReportPageSize::pageSize(label.paper()))); } else { // lookup the correct size information for the specified size paper - QSizeF pageSizePx = m_reportDocument->pageLayout().fullRectPixels(KReportDpi::dpiX()).size(); + QSizeF pageSizePx = m_reportDocument->pageLayout().fullRectPixels(KReportPrivate::dpiX()).size(); m_maxWidth = pageSizePx.width(); m_maxHeight = pageSizePx.height(); } } if (m_reportDocument->pageLayout().orientation() == QPageLayout::Landscape) { qreal tmp = m_maxWidth; m_maxWidth = m_maxHeight; m_maxHeight = tmp; } //kreportDebug() << "Page Size:" << m_maxWidth << m_maxHeight; m_document->setPageLayout(m_reportDocument->pageLayout()); m_kodata->setSorting(m_reportDocument->m_detailSection->m_sortedFields); if (!m_kodata->open()) { return false; } #ifdef KREPORT_SCRIPTING initEngine(); connect(m_scriptHandler, SIGNAL(groupChanged(QMap)), m_preRenderer, SIGNAL(groupChanged(QMap))); //Loop through all abjects that have been registered, and register them with the script handler if (m_scriptHandler) { QMapIterator i(m_scriptObjects); while (i.hasNext()) { i.next(); m_scriptHandler->registerScriptObject(i.value(), i.key()); } //execute the script, if it fails, abort and return the empty document if (!m_scriptHandler->trigger()) { m_scriptHandler->displayErrors(); return m_document; } } #endif createNewPage(); if (!label.isNull()) { // Label Print Run // remember the initial margin setting as we will be modifying // the value and restoring it as we move around qreal margin = m_leftMargin; m_yOffset = m_topMargin; qreal w = (label.width() / 100.0); qreal wg = (label.xGap() / 100.0); qreal h = (label.height() / 100.0); qreal hg = (label.yGap() / 100.0); int numCols = label.columns(); int numRows = label.rows(); qreal tmp; // flip the value around if we are printing landscape if (!m_reportDocument->pageLayout().orientation() == QPageLayout::Portrait) { w = (label.height() / 100.0); wg = (label.yGap() / 100.0); h = (label.width() / 100.0); hg = (label.xGap() / 100.0); numCols = label.rows(); numRows = label.columns(); } KReportDetailSectionData * detailData = m_reportDocument->m_detailSection; if (detailData->m_detailSection) { KReportData *mydata = m_kodata; if (mydata && mydata->recordCount() > 0) { /* && !((query = orqThis->getQuery())->eof()))*/ if (!mydata->moveFirst()) { return false; } int row = 0; int col = 0; do { tmp = m_yOffset; // store the value as renderSection changes it renderSection(*(detailData->m_detailSection)); m_yOffset = tmp; // restore the value that renderSection modified col++; m_leftMargin += w + wg; if (col >= numCols) { m_leftMargin = margin; // reset back to original value col = 0; row++; m_yOffset += h + hg; if (row >= numRows) { m_yOffset = m_topMargin; row = 0; createNewPage(); } } } while (mydata->moveNext()); } } } else { // Normal Print Run if (m_reportDocument->m_reportHeader) { renderSection(*(m_reportDocument->m_reportHeader)); } if (m_reportDocument->m_detailSection) { renderDetailSection(m_reportDocument->m_detailSection); } if (m_reportDocument->m_reportFooter) { if (renderSectionSize(*(m_reportDocument->m_reportFooter)) + finishCurPageSize(true) + m_bottomMargin + m_yOffset >= m_maxHeight) { createNewPage(); } renderSection(*(m_reportDocument->m_reportFooter)); } } finishCurPage(true); #ifdef KREPORT_SCRIPTING // _postProcText contains those text boxes that need to be updated // with information that wasn't available at the time it was added to the document m_scriptHandler->setPageTotal(m_document->pageCount()); for (int i = 0; i < m_postProcText.size(); i++) { OROTextBox * tb = m_postProcText.at(i); m_scriptHandler->setPageNumber(tb->page()->pageNumber() + 1); tb->setText(m_scriptHandler->evaluate(tb->text()).toString()); } #endif asyncManager->startRendering(); #ifdef KREPORT_SCRIPTING m_scriptHandler->displayErrors(); #endif if (!m_kodata->close()) { return false; } #ifdef KREPORT_SCRIPTING delete m_scriptHandler; m_scriptHandler = 0; #endif if (m_kodata != m_oneRecord) { delete m_kodata; m_kodata = 0; } m_postProcText.clear(); return true; } //===========================KReportPreRenderer=============================== KReportPreRenderer::KReportPreRenderer(const QDomElement &document) : d(new KReportPreRendererPrivate(this)) { setDocument(document); connect(d, &KReportPreRendererPrivate::finishedAllASyncItems, this, &KReportPreRenderer::finishedAllASyncItems); } KReportPreRenderer::~KReportPreRenderer() { delete d; } void KReportPreRenderer::setName(const QString &n) { d->m_reportDocument->setName(n); } bool KReportPreRenderer::isValid() const { if (d && d->m_valid) return true; return false; } ORODocument* KReportPreRenderer::document() { return d->m_document; } bool KReportPreRenderer::generateDocument() { // delete d->m_document; if (!d->generateDocument()) { delete d->m_document; d->m_document = 0; } return d->m_document; } void KReportPreRenderer::setSourceData(KReportData *data) { if (d && data != d->m_kodata) { delete d->m_kodata; d->m_kodata = data; } } bool KReportPreRenderer::setDocument(const QDomElement &document) { delete d->m_document; d->m_valid = false; if (document.tagName() != QLatin1String("report:content")) { kreportWarning() << "report schema is invalid"; return false; } d->m_reportDocument = new KReportDocument(document); d->m_valid = d->m_reportDocument->isValid(); return isValid(); } #ifdef KREPORT_SCRIPTING void KReportPreRenderer::registerScriptObject(QObject* obj, const QString& name) { //kreportDebug() << name; d->m_scriptObjects[name] = obj; } KReportScriptHandler *KReportPreRenderer::scriptHandler() { return d->m_scriptHandler; } #endif const KReportDocument* KReportPreRenderer::reportData() const { return d->m_reportDocument; } diff --git a/src/renderer/KReportPrintRenderer_p.cpp b/src/renderer/KReportPrintRenderer_p.cpp index ead0dbd9..f1dd2f1b 100644 --- a/src/renderer/KReportPrintRenderer_p.cpp +++ b/src/renderer/KReportPrintRenderer_p.cpp @@ -1,261 +1,261 @@ /* This file is part of the KDE project * Copyright (C) 2001-2007 by OpenMFG, LLC (info@openmfg.com) * Copyright (C) 2007-2008 by Adam Pigg (adam@piggz.co.uk) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include "KReportPrintRenderer_p.h" #include "kreport_debug.h" #include "KReportRenderObjects.h" #include "KReportPageSize.h" -#include "KReportDpi.h" +#include "KReportUtils_p.h" #include #include #include namespace KReportPrivate { PrintRenderer::PrintRenderer() { } PrintRenderer::~PrintRenderer() { } bool PrintRenderer::setupPrinter( ORODocument * document, QPrinter * pPrinter) { if (document == 0 || pPrinter == 0) return false; pPrinter->setCreator(QLatin1String("KReport Print Renderer")); pPrinter->setDocName(document->title()); pPrinter->setFullPage(true); pPrinter->setOrientation((document->pageLayout().orientation() == QPageLayout::Portrait ? QPrinter::Portrait : QPrinter::Landscape)); pPrinter->setPageOrder(QPrinter::FirstPageFirst); if (!document->pageLayout().pageSize().isValid()) { pPrinter->setPageSize(QPrinter::Custom); } else { pPrinter->setPageSize(QPageSize(document->pageLayout().pageSize())); } return true; } bool PrintRenderer::render(const KReportRendererContext &context, ORODocument *document, int page) { Q_UNUSED(page); if (document == 0 || context.printer() == 0 || context.painter() == 0) return false; setupPrinter(document, context.printer()); bool endWhenComplete = false; if (!context.painter()->isActive()) { endWhenComplete = true; if (!context.painter()->begin(context.printer())) return false; } int fromPage = context.printer()->fromPage(); if (fromPage > 0) fromPage -= 1; int toPage = context.printer()->toPage(); if (toPage == 0 || toPage > document->pageCount()) toPage = document->pageCount(); - qreal scaleX = context.printer()->resolution() / qreal(KReportDpi::dpiX()); - qreal scaleY = context.printer()->resolution() / qreal(KReportDpi::dpiY()); + qreal scaleX = context.printer()->resolution() / qreal(KReportPrivate::dpiX()); + qreal scaleY = context.printer()->resolution() / qreal(KReportPrivate::dpiY()); for (int copy = 0; copy < context.printer()->numCopies(); copy++) { for (int page = fromPage; page < toPage; page++) { if (page > fromPage) context.printer()->newPage(); OROPage * p = document->page(page); if (context.printer()->pageOrder() == QPrinter::LastPageFirst) p = document->page(toPage - 1 - page); // Render Page Objects for (int i = 0; i < p->primitiveCount(); i++) { OROPrimitive * prim = p->primitive(i); prim->setPosition(QPointF(prim->position().x() * scaleX, prim->position().y() * scaleY)); prim->setSize(QSizeF(prim->size().width() * scaleX, prim->size().height() * scaleY)); //kreportDebug() << "Rendering object" << i << "type" << prim->type(); if (dynamic_cast(prim)) { //kreportDebug() << "Text Box"; OROTextBox * tb = dynamic_cast(prim); QPointF ps = tb->position(); QSizeF sz = tb->size(); QRectF rc = QRectF(ps.x(), ps.y(), sz.width(), sz.height()); context.painter()->save(); //Background QColor bg = tb->textStyle().backgroundColor; bg.setAlphaF(0.01 * tb->textStyle().backgroundOpacity); //_painter()->setBackgroundMode(Qt::OpaqueMode); context.painter()->fillRect(rc, bg); //Text context.painter()->setBackgroundMode(Qt::TransparentMode); context.painter()->setFont(tb->textStyle().font); context.painter()->setPen(tb->textStyle().foregroundColor); context.painter()->drawText(rc, tb->flags(), tb->text()); //outer line context.painter()->setPen(QPen(tb->lineStyle().color(), tb->lineStyle().width() * scaleX, tb->lineStyle().penStyle())); context.painter()->drawRect(rc); //Reset back to defaults for next element context.painter()->restore(); } else if (dynamic_cast(prim)) { //kreportDebug() << "Line"; OROLine * ln = dynamic_cast(prim); QPointF s = ln->startPoint(); QPointF e(ln->endPoint().x() * scaleX, ln->endPoint().y() * scaleY); //QPen pen ( _painter()->pen() ); QPen pen(ln->lineStyle().color(), ln->lineStyle().width() * scaleX, ln->lineStyle().penStyle()); context.painter()->save(); context.painter()->setRenderHint(QPainter::Antialiasing, true); context.painter()->setPen(pen); context.painter()->drawLine(QLineF(s.x(), s.y(), e.x(), e.y())); context.painter()->setRenderHint(QPainter::Antialiasing, false); context.painter()->restore(); } else if (dynamic_cast(prim)) { //kreportDebug() << "Image"; OROImage * im = dynamic_cast(prim); QPointF ps = im->position(); QSizeF sz = im->size(); QRectF rc = QRectF(ps.x(), ps.y(), sz.width(), sz.height()); QImage img = im->image(); if (im->isScaled()) img = img.scaled(rc.size().toSize(), (Qt::AspectRatioMode) im->aspectRatioMode(), (Qt::TransformationMode) im->transformationMode()); QRectF sr = QRectF(QPointF(0.0, 0.0), rc.size().boundedTo(img.size())); context.painter()->drawImage(rc.topLeft(), img, sr); } else if (dynamic_cast(prim)) { //kreportDebug() << "Rect"; ORORect * re = dynamic_cast(prim); QPointF ps = re->position(); QSizeF sz = re->size(); QRectF rc = QRectF(ps.x(), ps.y(), sz.width(), sz.height()); context.painter()->save(); context.painter()->setPen(re->pen()); context.painter()->setBrush(re->brush()); context.painter()->drawRect(rc); context.painter()->restore(); } else if (dynamic_cast(prim)) { OROEllipse * re = dynamic_cast(prim); QPointF ps = re->position(); QSizeF sz = re->size(); QRectF rc = QRectF(ps.x(), ps.y(), sz.width(), sz.height()); context.painter()->save(); context.painter()->setPen(re->pen()); context.painter()->setBrush(re->brush()); context.painter()->drawEllipse(rc); context.painter()->restore(); } else if (dynamic_cast(prim)) { OROPicture * im = dynamic_cast(prim); QPointF ps = im->position(); QSizeF sz = im->size(); QRectF rc = QRectF(ps.x(), ps.y(), sz.width(), sz.height()); context.painter()->drawPicture(rc.topLeft(), *(im->picture())); } else if (dynamic_cast(prim)) { OROCheckBox * chk = dynamic_cast(prim); QPointF ps = chk->position(); QSizeF sz = chk->size(); QRectF rc = QRectF(ps.x(), ps.y(), sz.width(), sz.height()); context.painter()->save(); context.painter()->setBackgroundMode(Qt::OpaqueMode); context.painter()->setRenderHint(QPainter::Antialiasing); context.painter()->setPen(chk->foregroundColor()); if (chk->lineStyle().penStyle() == Qt::NoPen || chk->lineStyle().width() <= 0) { context.painter()->setPen(QPen(Qt::lightGray)); } else { context.painter()->setPen(QPen(chk->lineStyle().color(), chk->lineStyle().width() * scaleX, chk->lineStyle().penStyle())); } qreal ox = sz.width() / 5; qreal oy = sz.height() / 5; //Checkbox Style if (chk->checkType() == OROCheckBox::Cross) { context.painter()->drawRoundedRect(rc, sz.width() / 10 , sz.height() / 10); if (chk->value()) { QPen lp; lp.setColor(chk->foregroundColor()); lp.setWidth(ox > oy ? oy : ox); context.painter()->setPen(lp); context.painter()->drawLine(QPointF(ox, oy) + ps, QPointF(sz.width() - ox, sz.height() - oy) + ps); context.painter()->drawLine(QPointF(ox, sz.height() - oy) + ps, QPoint(sz.width() - ox, oy) + ps); } } else if (chk->checkType() == OROCheckBox::Dot) { //Radio Style context.painter()->drawEllipse(rc); if (chk->value()) { QBrush lb(chk->foregroundColor()); context.painter()->setBrush(lb); context.painter()->setPen(Qt::NoPen); context.painter()->drawEllipse(rc.center(), sz.width() / 2 - ox, sz.height() / 2 - oy); } } else { //Tickbox Style context.painter()->drawRoundedRect(rc, sz.width() / 10 , sz.height() / 10); if (chk->value()) { QPen lp; lp.setColor(chk->foregroundColor()); lp.setWidth(ox > oy ? oy : ox); context.painter()->setPen(lp); context.painter()->drawLine(QPointF(ox, sz.height() / 2) + ps, QPointF(sz.width() / 2, sz.height() - oy) + ps); context.painter()->drawLine(QPointF(sz.width() / 2, sz.height() - oy) + ps, QPointF(sz.width() - ox, oy) + ps); } } context.painter()->restore(); } } } } if (endWhenComplete) context.painter()->end(); return true; } } diff --git a/src/renderer/odtframe/KoOdtFrameReportDocument.cpp b/src/renderer/odtframe/KoOdtFrameReportDocument.cpp index ddee6c3e..10f79e7a 100644 --- a/src/renderer/odtframe/KoOdtFrameReportDocument.cpp +++ b/src/renderer/odtframe/KoOdtFrameReportDocument.cpp @@ -1,221 +1,221 @@ /* This file is part of the KDE project Copyright (C) 2012 by Dag Andersen (danders@get2net.dk) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "KoOdtFrameReportDocument.h" #include "KoOdtFrameReportPrimitive.h" #include "KReportRenderObjects.h" #include #include #include #include #include #include #include #include #include "kreport_debug.h" KoOdtFrameReportDocument::KoOdtFrameReportDocument() : manifestWriter(0) { } KoOdtFrameReportDocument::~KoOdtFrameReportDocument() { foreach (const QList &lst, m_pagemap) { foreach(KoOdtFrameReportPrimitive *p, lst) { delete p; } } } void KoOdtFrameReportDocument::setPageOptions(const ReportPageOptions &pageOptions) { m_pageOptions = pageOptions; } void KoOdtFrameReportDocument::startTable(OROSection* section) { Q_UNUSED(section); } void KoOdtFrameReportDocument::addPrimitive(KoOdtFrameReportPrimitive *data) { m_pagemap[data->pageNumber()].append( data); } QFile::FileError KoOdtFrameReportDocument::saveDocument(const QString& path) { // create output store KoStore *store = KoStore::createStore(path, KoStore::Write, "application/vnd.oasis.opendocument.text", KoStore::Zip); if (!store) { kreportWarning() << "Couldn't open the requested file."; return QFile::OpenError; } KoOdfWriteStore oasisStore(store); manifestWriter = oasisStore.manifestWriter("application/vnd.oasis.opendocument.text"); if (!manifestWriter) { return QFile::NoError; } // save extra data like images... foreach (const QList &lst, m_pagemap) { foreach(KoOdtFrameReportPrimitive *p, lst) { p->saveData(store, manifestWriter); } } //kreportDebug()<<"data saved"; KoGenStyles coll; createStyles(&coll); // create basic styles bool ok = createContent(&oasisStore, coll); if (ok) { // save styles to styles.xml ok = coll.saveOdfStylesDotXml(store, manifestWriter); } ok = oasisStore.closeManifestWriter() && ok; delete oasisStore.store(); return ok ? QFile::NoError : QFile::WriteError; } void KoOdtFrameReportDocument::createStyles(KoGenStyles *coll) { // convert to inches - qreal pw = m_pageOptions.widthPx() / KReportDpi::dpiX(); - qreal ph = m_pageOptions.heightPx() / KReportDpi::dpiY(); - qreal topMargin = m_pageOptions.getMarginTop() / KReportDpi::dpiY(); - qreal bottomMargin = m_pageOptions.getMarginBottom() / KReportDpi::dpiY(); - qreal leftMargin = m_pageOptions.getMarginLeft() / KReportDpi::dpiX(); - qreal rightMargin = m_pageOptions.getMarginRight() / KReportDpi::dpiX(); + qreal pw = m_pageOptions.widthPx() / KReportPrivate::dpiX(); + qreal ph = m_pageOptions.heightPx() / KReportPrivate::dpiY(); + qreal topMargin = m_pageOptions.getMarginTop() / KReportPrivate::dpiY(); + qreal bottomMargin = m_pageOptions.getMarginBottom() / KReportPrivate::dpiY(); + qreal leftMargin = m_pageOptions.getMarginLeft() / KReportPrivate::dpiX(); + qreal rightMargin = m_pageOptions.getMarginRight() / KReportPrivate::dpiX(); QString orientation = m_pageOptions.isPortrait() ? "portrait" : "landscape"; //kreportDebug()<<"Page:"<insert(page, "pm"); KoGenStyle master(KoGenStyle::MasterPageStyle, "master-page"); master.addAttribute("style:page-layout-name", pagename); coll->insert(master, "Standard", KoGenStyles::DontAddNumberToName); KoGenStyle fs(KoGenStyle::GraphicStyle, "graphic"); fs.addProperty("vertical-pos", "from-top"); fs.addProperty("vertical-rel", "page"); fs.addProperty("horizontal-pos", "from-left"); fs.addProperty("horizontal-rel", "page"); coll->insert(fs, "Frame", KoGenStyles::DontAddNumberToName); KoGenStyle ps(KoGenStyle::ParagraphStyle, "paragraph"); ps.addAttribute("style:parent-style-name", "Standard"); coll->insert(ps, "P1", KoGenStyles::DontAddNumberToName); } bool KoOdtFrameReportDocument::createContent(KoOdfWriteStore* store, KoGenStyles *coll) { KoXmlWriter* bodyWriter = store->bodyWriter(); KoXmlWriter* contentWriter = store->contentWriter(); if (!bodyWriter || !contentWriter || !manifestWriter) { kreportWarning()<<"Failed to created odt writer"; return false; } // OpenDocument spec requires the manifest to include a list of the files in this package manifestWriter->addManifestEntry("content.xml", "text/xml"); // manifestWriter->addManifestEntry("styles.xml", "text/xml"); contentWriter->startElement("office:automatic-styles"); //new page contentWriter->startElement("style:style"); contentWriter->addAttribute("style:name", "NewPage"); contentWriter->addAttribute("style:master-page-name", "Standard"); contentWriter->addAttribute("style:family", "paragraph"); contentWriter->startElement("style:paragraph-properties"); contentWriter->addAttribute("fo:font-family", "Arial"); contentWriter->addAttribute("fo:break-before", "page"); // needed by LibreOffice contentWriter->endElement(); // style:paragraph-properties contentWriter->endElement(); // style:style contentWriter->startElement("text:sequence-decls"); contentWriter->startElement("text:sequence-decl"); contentWriter->addAttribute("text:display-outline-level", "0"); contentWriter->addAttribute("text:name", "Illustration"); contentWriter->endElement(); //text:sequence-decl contentWriter->startElement("text:sequence-decl"); contentWriter->addAttribute("text:display-outline-level", "0"); contentWriter->addAttribute("text:name", "Table"); contentWriter->endElement(); //text:sequence-decl contentWriter->startElement("text:sequence-decl"); contentWriter->addAttribute("text:display-outline-level", "0"); contentWriter->addAttribute("text:name", "Text"); contentWriter->endElement(); //text:sequence-decl contentWriter->startElement("text:sequence-decl"); contentWriter->addAttribute("text:display-outline-level", "0"); contentWriter->addAttribute("text:name", "Drawing"); contentWriter->endElement(); //text:sequence-decl contentWriter->endElement(); //text:sequence-decls contentWriter->endElement(); // office:automatic-styles // office:body bodyWriter->startElement("office:body"); bodyWriter->startElement("office:text"); createPages(bodyWriter, coll); bodyWriter->endElement(); // office:text bodyWriter->endElement(); // office:body return store->closeContentWriter(); } void KoOdtFrameReportDocument::createPages(KoXmlWriter* bodyWriter, KoGenStyles *coll) { QMap >::const_iterator it; for (it = m_pagemap.constBegin(); it != m_pagemap.constEnd(); ++it) { bodyWriter->startElement("text:p"); bodyWriter->addAttribute("text:style-name", "NewPage"); // all frames need to be *inside* or else LibreWriter shows nothing foreach (KoOdtFrameReportPrimitive *data, it.value()) { data->createStyle(coll); data->createBody(bodyWriter); } bodyWriter->endElement(); // text:p } if (m_pagemap.isEmpty()) { // words crashes if there is no text element bodyWriter->startElement("text:p"); bodyWriter->addAttribute("text:style-name", "P1"); bodyWriter->endElement(); // text:p } } diff --git a/src/renderer/odtframe/KoOdtFrameReportLine.cpp b/src/renderer/odtframe/KoOdtFrameReportLine.cpp index 5b557b83..9ec6cc47 100644 --- a/src/renderer/odtframe/KoOdtFrameReportLine.cpp +++ b/src/renderer/odtframe/KoOdtFrameReportLine.cpp @@ -1,115 +1,115 @@ /* This file is part of the KDE project Copyright (C) 2011, 2012 by Dag Andersen (danders@get2net.dk) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "KoOdtFrameReportLine.h" #include "KReportRenderObjects.h" #include #include #include #include #include #include #include #include "kreport_debug.h" KoOdtFrameReportLine::KoOdtFrameReportLine(OROLine *primitive) : KoOdtFrameReportPrimitive(primitive) { } KoOdtFrameReportLine::~KoOdtFrameReportLine() { } OROLine *KoOdtFrameReportLine::line() const { return static_cast(m_primitive); } void KoOdtFrameReportLine::createStyle(KoGenStyles *coll) { KoGenStyle ps(KoGenStyle::ParagraphStyle, "paragraph"); m_paragraphStyleName = coll->insert(ps, "P"); KoGenStyle gs(KoGenStyle::GraphicStyle, "graphic"); gs.addProperty("draw:fill", "none"); gs.addPropertyPt("fo:margin", 0); gs.addProperty("style:horizontal-pos", "from-left"); gs.addProperty("style:horizontal-rel", "page"); gs.addProperty("style:vertical-pos", "from-top"); gs.addProperty("style:vertical-rel", "page"); gs.addProperty("style:wrap", "dynamic"); gs.addPropertyPt("style:wrap-dynamic-threshold", 0); QPen pen; qreal weight = line()->lineStyle().weight; if (weight < 1.0) { weight = 1.0; } pen.setWidthF(weight); pen.setColor(line()->lineStyle().lineColor); pen.setStyle(line()->lineStyle().style); KoOdfGraphicStyles::saveOdfStrokeStyle(gs, coll, pen); m_frameStyleName = coll->insert(gs, "F"); //kreportDebug()<<*coll; } void KoOdtFrameReportLine::createBody(KoXmlWriter *bodyWriter) const { // convert to inches - qreal sx = INCH_TO_POINT(line()->startPoint().x() / KReportDpi::dpiX()); - qreal sy = INCH_TO_POINT(line()->startPoint().y() / KReportDpi::dpiY()); - qreal ex = INCH_TO_POINT(line()->endPoint().x() / KReportDpi::dpiX()); - qreal ey = INCH_TO_POINT(line()->endPoint().y() / KReportDpi::dpiY()); + qreal sx = INCH_TO_POINT(line()->startPoint().x() / KReportPrivate::dpiX()); + qreal sy = INCH_TO_POINT(line()->startPoint().y() / KReportPrivate::dpiY()); + qreal ex = INCH_TO_POINT(line()->endPoint().x() / KReportPrivate::dpiX()); + qreal ey = INCH_TO_POINT(line()->endPoint().y() / KReportPrivate::dpiY()); qreal width = ex - sx; qreal height = ey - sy; //kreportDebug()<startPoint()<endPoint(); bodyWriter->startElement("draw:rect"); bodyWriter->addAttribute("draw:id", itemName()); bodyWriter->addAttribute("xml:id", itemName()); bodyWriter->addAttribute("draw:name", itemName()); bodyWriter->addAttribute("text:anchor-type", "page"); bodyWriter->addAttribute("text:anchor-page-number", pageNumber()); bodyWriter->addAttribute("draw:style-name", m_frameStyleName); bodyWriter->addAttribute("draw:z-index", "3"); if (height == 0.0 && width >= 0.0) { // just a horizontal line bodyWriter->addAttributePt("svg:x", sx); bodyWriter->addAttributePt("svg:y", sy); bodyWriter->addAttributePt("svg:width", width); bodyWriter->addAttributePt("svg:height", 0.0); } else { // rotate qreal l = sqrt(width*width + height*height); bodyWriter->addAttributePt("svg:width", l); bodyWriter->addAttributePt("svg:height", 0.0); qreal sina = height / l; qreal cosa = width / l; QTransform rotate(cosa, sina, -sina, cosa, sx, sy); bodyWriter->addAttribute("draw:transform", KoOdfGraphicStyles::saveTransformation(rotate)); } bodyWriter->endElement(); // draw:frame } diff --git a/src/renderer/odtframe/KoOdtFrameReportPrimitive.cpp b/src/renderer/odtframe/KoOdtFrameReportPrimitive.cpp index 2861d395..aea59479 100644 --- a/src/renderer/odtframe/KoOdtFrameReportPrimitive.cpp +++ b/src/renderer/odtframe/KoOdtFrameReportPrimitive.cpp @@ -1,107 +1,107 @@ /* This file is part of the KDE project Copyright (C) 2011, 2012 by Dag Andersen (danders@get2net.dk) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "KoOdtFrameReportPrimitive.h" #include "KReportRenderObjects.h" #include #include #include #include KoOdtFrameReportPrimitive::KoOdtFrameReportPrimitive(OROPrimitive *primitive) : m_primitive(primitive) , m_uid(0) { } KoOdtFrameReportPrimitive::~KoOdtFrameReportPrimitive() { } bool KoOdtFrameReportPrimitive::isValid() const { return (bool)m_primitive; } void KoOdtFrameReportPrimitive::setPrimitive(OROPrimitive *primitive) { m_primitive = primitive; } int KoOdtFrameReportPrimitive::pageNumber() const { return isValid() && m_primitive->page() ? m_primitive->page()->pageNumber() + 1 : 0; } void KoOdtFrameReportPrimitive::setUID(int uid) { m_uid = uid; } int KoOdtFrameReportPrimitive::uid() const { return m_uid; } QString KoOdtFrameReportPrimitive::itemName() const { return QString("Item_%1").arg(m_uid); } void KoOdtFrameReportPrimitive::createStyle(KoGenStyles *coll) { KoGenStyle gs(KoGenStyle::GraphicStyle, "graphic"); gs.addProperty("draw:fill", "none"); gs.addPropertyPt("fo:margin", 0); gs.addProperty("style:horizontal-pos", "from-left"); gs.addProperty("style:horizontal-rel", "page"); gs.addProperty("style:vertical-pos", "from-top"); gs.addProperty("style:vertical-rel", "page"); gs.addProperty("style:wrap", "dynamic"); gs.addPropertyPt("style:wrap-dynamic-threshold", 0); m_frameStyleName = coll->insert(gs, "F"); } void KoOdtFrameReportPrimitive::createBody(KoXmlWriter *bodyWriter) const { Q_UNUSED(bodyWriter); } void KoOdtFrameReportPrimitive::commonAttributes(KoXmlWriter *bodyWriter) const { // convert to inches - qreal x = m_primitive->position().x() / KReportDpi::dpiX(); - qreal y = m_primitive->position().y() / KReportDpi::dpiX(); - qreal w = m_primitive->size().width() / KReportDpi::dpiX(); - qreal h = m_primitive->size().height() / KReportDpi::dpiY(); + qreal x = m_primitive->position().x() / KReportPrivate::dpiX(); + qreal y = m_primitive->position().y() / KReportPrivate::dpiX(); + qreal w = m_primitive->size().width() / KReportPrivate::dpiX(); + qreal h = m_primitive->size().height() / KReportPrivate::dpiY(); bodyWriter->addAttribute("svg:x", QString("%1in").arg(x)); bodyWriter->addAttribute("svg:y", QString("%1in").arg(y)); bodyWriter->addAttribute("svg:width", QString("%1in").arg(w)); bodyWriter->addAttribute("svg:height", QString("%1in").arg(h)); bodyWriter->addAttribute("draw:z-index", "3"); } bool KoOdtFrameReportPrimitive::saveData(KoStore */*store*/, KoXmlWriter*) const { return true; } diff --git a/src/wrtembed/KReportDesigner.cpp b/src/wrtembed/KReportDesigner.cpp index 84d8cf3c..0804bb35 100644 --- a/src/wrtembed/KReportDesigner.cpp +++ b/src/wrtembed/KReportDesigner.cpp @@ -1,1553 +1,1553 @@ /* This file is part of the KDE project * Copyright (C) 2001-2007 by OpenMFG, LLC * Copyright (C) 2007-2010 by Adam Pigg * Copyright (C) 2011 Jarosław Staniek * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include "KReportDesigner.h" #include "KReportDesignerSection.h" #include "KReportDesignerSectionScene.h" #include "KReportDesignerSectionView.h" #include "KReportDesignerSectionDetailGroup.h" #include "KReportPropertiesButton.h" #include "KReportSectionEditor.h" #include "KReportDesignerSectionDetail.h" #include "KReportDesignerItemLine.h" #include "KReportRuler_p.h" #include "KReportZoomHandler.h" #include "KReportPageSize.h" -#include "KReportDpi.h" +#include "KReportUtils_p.h" #include "KReportUtils.h" #include "KReportPluginInterface.h" #include "KReportPluginManager.h" #include "KReportSection.h" #include "KReportPluginMetaData.h" #include "kreport_debug.h" #include #include #include #include #include #include #include #include #include #include #include #include #include //! Also add public method for runtime? const char ns[] = "http://kexi-project.org/report/2.0"; static QDomElement propertyToElement(QDomDocument* d, KProperty* p) { QDomElement e = d->createElement(QLatin1String("report:" + p->name().toLower())); e.appendChild(d->createTextNode(p->value().toString())); return e; } // // define and implement the ReportWriterSectionData class // a simple class to hold/hide data in the ReportHandler class // class ReportWriterSectionData { public: ReportWriterSectionData() { selected_x_offset = 0; selected_y_offset = 0; mouseAction = ReportWriterSectionData::MA_None; } virtual ~ReportWriterSectionData() { } enum MouseAction { MA_None = 0, MA_Insert = 1, MA_Grab = 2, MA_MoveStartPoint, MA_MoveEndPoint, MA_ResizeNW = 8, MA_ResizeN, MA_ResizeNE, MA_ResizeE, MA_ResizeSE, MA_ResizeS, MA_ResizeSW, MA_ResizeW }; int selected_x_offset; int selected_y_offset; MouseAction mouseAction; QString insertItem; QList copy_list; QList cut_list; }; //! @internal class Q_DECL_HIDDEN KReportDesigner::Private { public: Private() : activeScene(0) , reportHeader(0) , pageHeaderFirst(0) , pageHeaderOdd(0) , pageHeaderEven(0) , pageHeaderLast(0) , pageHeaderAny(0) , pageFooterFirst(0) , pageFooterOdd(0) , pageFooterEven(0) , pageFooterLast(0) , pageFooterAny(0) , reportFooter(0) , detail(0) , pressX(-1) , pressY(-1) , releaseX(-1) , releaseY(-1) , modified(false) , kordata(0) {} ~Private() { delete zoom; delete sectionData; delete set; delete kordata; } QGridLayout *grid; KReportRuler *hruler; KReportZoomHandler *zoom; QVBoxLayout *vboxlayout; KReportPropertiesButton *pageButton; QGraphicsScene *activeScene; ReportWriterSectionData *sectionData; KReportDesignerSection *reportHeader; KReportDesignerSection *pageHeaderFirst; KReportDesignerSection *pageHeaderOdd; KReportDesignerSection *pageHeaderEven; KReportDesignerSection *pageHeaderLast; KReportDesignerSection *pageHeaderAny; KReportDesignerSection *pageFooterFirst; KReportDesignerSection *pageFooterOdd; KReportDesignerSection *pageFooterEven; KReportDesignerSection *pageFooterLast; KReportDesignerSection *pageFooterAny; KReportDesignerSection *reportFooter; KReportDesignerSectionDetail *detail; //Properties KPropertySet *set; KPropertySet *itmset; KProperty *title; KProperty *pageSize; KProperty *orientation; KProperty *unit; KProperty *customHeight; KProperty *customWidth; KProperty *leftMargin; KProperty *rightMargin; KProperty *topMargin; KProperty *bottomMargin; KProperty *showGrid; KProperty *gridDivisions; KProperty *gridSnap; KProperty *labelType; #ifdef KREPORT_SCRIPTING KProperty *script; #endif //Actions QAction *editCutAction; QAction *editCopyAction; QAction *editPasteAction; QAction *editDeleteAction; QAction *sectionEdit; QAction *parameterEdit; QAction *itemRaiseAction; QAction *itemLowerAction; qreal pressX; qreal pressY; qreal releaseX; qreal releaseY; bool modified; // true if this document has been modified, false otherwise QString originalInterpreter; //Value of the script interpreter at load time QString originalScript; //Value of the script at load time KReportData *kordata; }; KReportDesigner::KReportDesigner(QWidget * parent) : QWidget(parent), d(new Private()) { init(); } void KReportDesigner::init() { KReportPluginManager::self(); // this loads icons early enough d->sectionData = new ReportWriterSectionData(); createProperties(); createActions(); d->grid = new QGridLayout(this); d->grid->setSpacing(0); d->grid->setMargin(0); d->grid->setColumnStretch(1, 1); d->grid->setRowStretch(1, 1); d->grid->setSizeConstraint(QLayout::SetFixedSize); d->vboxlayout = new QVBoxLayout(); d->vboxlayout->setSpacing(0); d->vboxlayout->setMargin(0); d->vboxlayout->setSizeConstraint(QLayout::SetFixedSize); //Create nice rulers d->zoom = new KReportZoomHandler(); d->hruler = new KReportRuler(this, Qt::Horizontal, d->zoom); d->pageButton = new KReportPropertiesButton(this); d->hruler->setUnit(KReportUnit(KReportUnit::Centimeter)); d->grid->addWidget(d->pageButton, 0, 0); d->grid->addWidget(d->hruler, 0, 1); d->grid->addLayout(d->vboxlayout, 1, 0, 1, 2); d->pageButton->setMaximumSize(QSize(19, 22)); d->pageButton->setMinimumSize(QSize(19, 22)); d->detail = new KReportDesignerSectionDetail(this); d->vboxlayout->insertWidget(0, d->detail); setLayout(d->grid); connect(d->pageButton, SIGNAL(released()), this, SLOT(slotPageButton_Pressed())); emit pagePropertyChanged(*d->set); connect(d->set, SIGNAL(propertyChanged(KPropertySet&,KProperty&)), this, SLOT(slotPropertyChanged(KPropertySet&,KProperty&))); changeSet(d->set); } KReportDesigner::~KReportDesigner() { delete d; } ///The loading Code KReportDesigner::KReportDesigner(QWidget *parent, const QDomElement &data) : QWidget(parent), d(new Private()) { init(); if (data.tagName() != QLatin1String("report:content")) { // arg we got an xml file but not one i know of kreportWarning() << "root element was not "; } //kreportDebug() << data.text(); deleteDetail(); QDomNodeList nlist = data.childNodes(); QDomNode it; for (int i = 0; i < nlist.count(); ++i) { it = nlist.item(i); // at this level all the children we get should be Elements if (it.isElement()) { QString n = it.nodeName().toLower(); //kreportDebug() << n; if (n == QLatin1String("report:title")) { setReportTitle(it.firstChild().nodeValue()); #ifdef KREPORT_SCRIPTING } else if (n == QLatin1String("report:script")) { d->originalInterpreter = it.toElement().attribute(QLatin1String("report:script-interpreter")); d->originalScript = it.firstChild().nodeValue(); d->script->setValue(d->originalScript); if (d->originalInterpreter != QLatin1String("javascript") && d->originalInterpreter != QLatin1String("qtscript")) { QString msg = tr("This report contains scripts of type \"%1\". " "Only scripts written in JavaScript language are " "supported. To prevent losing the scripts, their type " "and content will not be changed unless you change these scripts." ).arg(d->originalInterpreter); QMessageBox::warning(this, tr("Unsupported Script Type"), msg); } #endif } else if (n == QLatin1String("report:grid")) { d->showGrid->setValue(it.toElement().attribute(QLatin1String("report:grid-visible"), QString::number(1)).toInt() != 0); d->gridSnap->setValue(it.toElement().attribute(QLatin1String("report:grid-snap"), QString::number(1)).toInt() != 0); d->gridDivisions->setValue(it.toElement().attribute(QLatin1String("report:grid-divisions"), QString::number(4)).toInt()); d->unit->setValue(it.toElement().attribute(QLatin1String("report:page-unit"), QLatin1String("cm"))); } //! @todo Load page options else if (n == QLatin1String("report:page-style")) { QString pagetype = it.firstChild().nodeValue(); if (pagetype == QLatin1String("predefined")) { d->pageSize->setValue(it.toElement().attribute(QLatin1String("report:page-size"), QLatin1String("A4"))); } else if (pagetype == QLatin1String("custom")) { d->pageSize->setValue(QLatin1String("custom")); d->customHeight->setValue(KReportUnit::parseValue(it.toElement().attribute(QLatin1String("report:custom-page-height"), QLatin1String("")))); d->customWidth->setValue(KReportUnit::parseValue(it.toElement().attribute(QLatin1String("report:custom-page-widtht"), QLatin1String("")))); } else if (pagetype == QLatin1String("label")) { //! @todo } d->rightMargin->setValue(KReportUnit::parseValue(it.toElement().attribute(QLatin1String("fo:margin-right"), QLatin1String("1.0cm")))); d->leftMargin->setValue(KReportUnit::parseValue(it.toElement().attribute(QLatin1String("fo:margin-left"), QLatin1String("1.0cm")))); d->topMargin->setValue(KReportUnit::parseValue(it.toElement().attribute(QLatin1String("fo:margin-top"), QLatin1String("1.0cm")))); d->bottomMargin->setValue(KReportUnit::parseValue(it.toElement().attribute(QLatin1String("fo:margin-bottom"), QLatin1String("1.0cm")))); d->orientation->setValue(it.toElement().attribute(QLatin1String("report:print-orientation"), QLatin1String("portrait"))); } else if (n == QLatin1String("report:body")) { QDomNodeList sectionlist = it.childNodes(); QDomNode sec; for (int s = 0; s < sectionlist.count(); ++s) { sec = sectionlist.item(s); if (sec.isElement()) { QString sn = sec.nodeName().toLower(); //kreportDebug() << sn; if (sn == QLatin1String("report:section")) { QString sectiontype = sec.toElement().attribute(QLatin1String("report:section-type")); if (section(KReportSectionData::sectionTypeFromString(sectiontype)) == 0) { insertSection(KReportSectionData::sectionTypeFromString(sectiontype)); section(KReportSectionData::sectionTypeFromString(sectiontype))->initFromXML(sec); } } else if (sn == QLatin1String("report:detail")) { KReportDesignerSectionDetail * rsd = new KReportDesignerSectionDetail(this); rsd->initFromXML(&sec); setDetail(rsd); } } else { kreportWarning() << "Encountered an unknown Element: " << n; } } } } else { kreportWarning() << "Encountered a child node of root that is not an Element"; } } this->slotPageButton_Pressed(); emit reportDataChanged(); slotPropertyChanged(*d->set, *d->unit); // set unit for all items setModified(false); } ///The saving code QDomElement KReportDesigner::document() const { QDomDocument doc; QString saveInterpreter; QDomElement content = doc.createElement(QLatin1String("report:content")); content.setAttribute(QLatin1String("xmlns:report"), QLatin1String(ns)); content.setAttribute(QLatin1String("xmlns:fo"), QLatin1String("urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0")); content.setAttribute(QLatin1String("xmlns:svg"), QLatin1String("urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0")); doc.appendChild(content); //title content.appendChild(propertyToElement(&doc, d->title)); #ifdef KREPORT_SCRIPTING if (!d->script->value().toString().isEmpty()) { if (d->script->value().toString() != d->originalScript || d->originalInterpreter == QLatin1String("qtscript")) { //The script has changed so force interpreter to 'javascript'. Also set if was using qtscript saveInterpreter = QLatin1String("javascript"); } else { saveInterpreter = d->originalInterpreter; } QDomElement scr = propertyToElement(&doc, d->script); scr.setAttribute(QLatin1String("report:script-interpreter"), saveInterpreter); content.appendChild(scr); } #endif QDomElement grd = doc.createElement(QLatin1String("report:grid")); KReportUtils::addPropertyAsAttribute(&grd, d->showGrid); KReportUtils::addPropertyAsAttribute(&grd, d->gridDivisions); KReportUtils::addPropertyAsAttribute(&grd, d->gridSnap); KReportUtils::addPropertyAsAttribute(&grd, d->unit); content.appendChild(grd); // pageOptions // -- size QDomElement pagestyle = doc.createElement(QLatin1String("report:page-style")); if (d->pageSize->value().toString() == QLatin1String("Custom")) { pagestyle.appendChild(doc.createTextNode(QLatin1String("custom"))); KReportUtils::setAttribute(&pagestyle, QLatin1String("report:custom-page-width"), d->customWidth->value().toDouble()); KReportUtils::setAttribute(&pagestyle, QLatin1String("report:custom-page-height"), d->customHeight->value().toDouble()); } else if (d->pageSize->value().toString() == QLatin1String("Label")) { pagestyle.appendChild(doc.createTextNode(QLatin1String("label"))); pagestyle.setAttribute(QLatin1String("report:page-label-type"), d->labelType->value().toString()); } else { pagestyle.appendChild(doc.createTextNode(QLatin1String("predefined"))); KReportUtils::addPropertyAsAttribute(&pagestyle, d->pageSize); //pagestyle.setAttribute("report:page-size", d->pageSize->value().toString()); } // -- orientation KReportUtils::addPropertyAsAttribute(&pagestyle, d->orientation); // -- margins: save as points, and not localized KReportUtils::setAttribute(&pagestyle, QLatin1String("fo:margin-top"), d->topMargin->value().toDouble()); KReportUtils::setAttribute(&pagestyle, QLatin1String("fo:margin-bottom"), d->bottomMargin->value().toDouble()); KReportUtils::setAttribute(&pagestyle, QLatin1String("fo:margin-right"), d->rightMargin->value().toDouble()); KReportUtils::setAttribute(&pagestyle, QLatin1String("fo:margin-left"), d->leftMargin->value().toDouble()); content.appendChild(pagestyle); QDomElement body = doc.createElement(QLatin1String("report:body")); QDomElement domsection; for (int i = KReportSectionData::PageHeaderFirst; i <= KReportSectionData::PageFooterAny; ++i) { KReportDesignerSection *sec = section((KReportSectionData::Section)i); if (sec) { domsection = doc.createElement(QLatin1String("report:section")); domsection.setAttribute(QLatin1String("report:section-type"), KReportSectionData::sectionTypeString(KReportSectionData::Section(i))); sec->buildXML(&doc, &domsection); body.appendChild(domsection); } } QDomElement detail = doc.createElement(QLatin1String("report:detail")); d->detail->buildXML(&doc, &detail); body.appendChild(detail); content.appendChild(body); return content; } void KReportDesigner::slotSectionEditor() { KReportSectionEditor se(this); (void)se.exec(); } void KReportDesigner::setReportData(KReportData* kodata) { if (d->kordata == kodata) { return; } delete d->kordata; d->kordata = kodata; slotPageButton_Pressed(); setModified(true); emit reportDataChanged(); } KReportDesignerSection * KReportDesigner::section(KReportSectionData::Section s) const { KReportDesignerSection *sec; switch (s) { case KReportSectionData::PageHeaderAny: sec = d->pageHeaderAny; break; case KReportSectionData::PageHeaderEven: sec = d->pageHeaderEven; break; case KReportSectionData::PageHeaderOdd: sec = d->pageHeaderOdd; break; case KReportSectionData::PageHeaderFirst: sec = d->pageHeaderFirst; break; case KReportSectionData::PageHeaderLast: sec = d->pageHeaderLast; break; case KReportSectionData::PageFooterAny: sec = d->pageFooterAny; break; case KReportSectionData::PageFooterEven: sec = d->pageFooterEven; break; case KReportSectionData::PageFooterOdd: sec = d->pageFooterOdd; break; case KReportSectionData::PageFooterFirst: sec = d->pageFooterFirst; break; case KReportSectionData::PageFooterLast: sec = d->pageFooterLast; break; case KReportSectionData::ReportHeader: sec = d->reportHeader; break; case KReportSectionData::ReportFooter: sec = d->reportFooter; break; default: sec = 0; } return sec; } void KReportDesigner::removeSection(KReportSectionData::Section s) { KReportDesignerSection* sec = section(s); if (sec) { delete sec; switch (s) { case KReportSectionData::PageHeaderAny: d->pageHeaderAny = 0; break; case KReportSectionData::PageHeaderEven: sec = d->pageHeaderEven = 0; break; case KReportSectionData::PageHeaderOdd: d->pageHeaderOdd = 0; break; case KReportSectionData::PageHeaderFirst: d->pageHeaderFirst = 0; break; case KReportSectionData::PageHeaderLast: d->pageHeaderLast = 0; break; case KReportSectionData::PageFooterAny: d->pageFooterAny = 0; break; case KReportSectionData::PageFooterEven: d->pageFooterEven = 0; break; case KReportSectionData::PageFooterOdd: d->pageFooterOdd = 0; break; case KReportSectionData::PageFooterFirst: d->pageFooterFirst = 0; break; case KReportSectionData::PageFooterLast: d->pageFooterLast = 0; break; case KReportSectionData::ReportHeader: d->reportHeader = 0; break; case KReportSectionData::ReportFooter: d->reportFooter = 0; break; default: sec = 0; } setModified(true); adjustSize(); } } void KReportDesigner::insertSection(KReportSectionData::Section s) { KReportDesignerSection* sec = section(s); if (!sec) { int idx = 0; for (int i = 1; i <= s; ++i) { if (section((KReportSectionData::Section)i)) idx++; } if (s > KReportSectionData::ReportHeader) idx++; //kreportDebug() << idx; KReportDesignerSection *rs = new KReportDesignerSection(this); d->vboxlayout->insertWidget(idx, rs); switch (s) { case KReportSectionData::PageHeaderAny: rs->setTitle(tr("Page Header (Any)")); d->pageHeaderAny = rs; break; case KReportSectionData::PageHeaderEven: rs->setTitle(tr("Page Header (Even)")); d->pageHeaderEven = rs; break; case KReportSectionData::PageHeaderOdd: rs->setTitle(tr("Page Header (Odd)")); d->pageHeaderOdd = rs; break; case KReportSectionData::PageHeaderFirst: rs->setTitle(tr("Page Header (First)")); d->pageHeaderFirst = rs; break; case KReportSectionData::PageHeaderLast: rs->setTitle(tr("Page Header (Last)")); d->pageHeaderLast = rs; break; case KReportSectionData::PageFooterAny: rs->setTitle(tr("Page Footer (Any)")); d->pageFooterAny = rs; break; case KReportSectionData::PageFooterEven: rs->setTitle(tr("Page Footer (Even)")); d->pageFooterEven = rs; break; case KReportSectionData::PageFooterOdd: rs->setTitle(tr("Page Footer (Odd)")); d->pageFooterOdd = rs; break; case KReportSectionData::PageFooterFirst: rs->setTitle(tr("Page Footer (First)")); d->pageFooterFirst = rs; break; case KReportSectionData::PageFooterLast: rs->setTitle(tr("Page Footer (Last)")); d->pageFooterLast = rs; break; case KReportSectionData::ReportHeader: rs->setTitle(tr("Report Header")); d->reportHeader = rs; break; case KReportSectionData::ReportFooter: rs->setTitle(tr("Report Footer")); d->reportFooter = rs; break; //These sections cannot be inserted this way case KReportSectionData::None: case KReportSectionData::GroupHeader: case KReportSectionData::GroupFooter: case KReportSectionData::Detail: break; } rs->show(); setModified(true); adjustSize(); emit pagePropertyChanged(*d->set); } } void KReportDesigner::setReportTitle(const QString & str) { if (reportTitle() != str) { d->title->setValue(str); setModified(true); } } KPropertySet * KReportDesigner::propertySet() const { return d->set; } KPropertySet* KReportDesigner::itemPropertySet() const { return d->itmset; } KReportData *KReportDesigner::reportData() const { return d->kordata; } KReportDesignerSectionDetail * KReportDesigner::detailSection() const { return d->detail; } QString KReportDesigner::reportTitle() const { return d->title->value().toString(); } bool KReportDesigner::isModified() const { return d->modified; } void KReportDesigner::setModified(bool mod) { d->modified = mod; if (d->modified) { emit dirty(); } } QStringList KReportDesigner::fieldNames() const { QStringList qs; qs << QString(); if (d->kordata) qs << d->kordata->fieldNames(); return qs; } QStringList KReportDesigner::fieldKeys() const { QStringList qs; qs << QString(); if (d->kordata) qs << d->kordata->fieldKeys(); return qs; } void KReportDesigner::createProperties() { QStringList keys, strings; d->set = new KPropertySet; KReportDesigner::addMetaProperties(d->set, tr("Report", "Main report element"), QLatin1String("kreport-report-element")); connect(d->set, SIGNAL(propertyChanged(KPropertySet&,KProperty&)), this, SLOT(slotPropertyChanged(KPropertySet&,KProperty&))); d->title = new KProperty("title", QLatin1String("Report"), tr("Title"), tr("Report Title")); keys.clear(); keys = KReportPageSize::pageFormatKeys(); strings = KReportPageSize::pageFormatNames(); QString defaultKey = KReportPageSize::pageSizeKey(KReportPageSize::defaultSize()); d->pageSize = new KProperty("page-size", keys, strings, defaultKey, tr("Page Size")); keys.clear(); strings.clear(); keys << QLatin1String("portrait") << QLatin1String("landscape"); strings << tr("Portrait") << tr("Landscape"); d->orientation = new KProperty("print-orientation", keys, strings, QLatin1String("portrait"), tr("Page Orientation")); keys.clear(); strings.clear(); strings = KReportUnit::listOfUnitNameForUi(KReportUnit::HidePixel); QString unit; foreach(const QString &un, strings) { unit = un.mid(un.indexOf(QLatin1String("(")) + 1, 2); keys << unit; } d->unit = new KProperty("page-unit", keys, strings, QLatin1String("cm"), tr("Page Unit")); d->showGrid = new KProperty("grid-visible", true, tr("Show Grid")); d->gridSnap = new KProperty("grid-snap", true, tr("Snap to Grid")); d->gridDivisions = new KProperty("grid-divisions", 4, tr("Grid Divisions")); d->leftMargin = new KProperty("margin-left", KReportUnit(KReportUnit::Centimeter).fromUserValue(1.0), tr("Left Margin"), tr("Left Margin"), KProperty::Double); d->rightMargin = new KProperty("margin-right", KReportUnit(KReportUnit::Centimeter).fromUserValue(1.0), tr("Right Margin"), tr("Right Margin"), KProperty::Double); d->topMargin = new KProperty("margin-top", KReportUnit(KReportUnit::Centimeter).fromUserValue(1.0), tr("Top Margin"), tr("Top Margin"), KProperty::Double); d->bottomMargin = new KProperty("margin-bottom", KReportUnit(KReportUnit::Centimeter).fromUserValue(1.0), tr("Bottom Margin"), tr("Bottom Margin"), KProperty::Double); d->leftMargin->setOption("unit", QLatin1String("cm")); d->rightMargin->setOption("unit", QLatin1String("cm")); d->topMargin->setOption("unit", QLatin1String("cm")); d->bottomMargin->setOption("unit", QLatin1String("cm")); d->set->addProperty(d->title); d->set->addProperty(d->pageSize); d->set->addProperty(d->orientation); d->set->addProperty(d->unit); d->set->addProperty(d->gridSnap); d->set->addProperty(d->showGrid); d->set->addProperty(d->gridDivisions); d->set->addProperty(d->leftMargin); d->set->addProperty(d->rightMargin); d->set->addProperty(d->topMargin); d->set->addProperty(d->bottomMargin); #ifdef KREPORT_SCRIPTING d->script = new KProperty("script", QStringList(), QStringList(), QString(), tr("Object Script")); d->set->addProperty(d->script); #endif // KProperty* _customHeight; // KProperty* _customWidth; } /** @brief Handle property changes */ void KReportDesigner::slotPropertyChanged(KPropertySet &s, KProperty &p) { setModified(true); emit pagePropertyChanged(s); if (p.name() == "page-unit") { d->hruler->setUnit(pageUnit()); QString newstr = d->set->property("page-unit").value().toString(); d->set->property("margin-left").setOption("unit", newstr); d->set->property("margin-right").setOption("unit", newstr); d->set->property("margin-top").setOption("unit", newstr); d->set->property("margin-bottom").setOption("unit", newstr); } } void KReportDesigner::slotPageButton_Pressed() { #ifdef KREPORT_SCRIPTING if (d->kordata) { QStringList sl = d->kordata->scriptList(); sl.prepend(QLatin1String("")); d->script->setListData(sl, sl); } changeSet(d->set); #endif } QSize KReportDesigner::sizeHint() const { int w = 0; int h = 0; if (d->pageFooterAny) h += d->pageFooterAny->sizeHint().height(); if (d->pageFooterEven) h += d->pageFooterEven->sizeHint().height(); if (d->pageFooterFirst) h += d->pageFooterFirst->sizeHint().height(); if (d->pageFooterLast) h += d->pageFooterLast->sizeHint().height(); if (d->pageFooterOdd) h += d->pageFooterOdd->sizeHint().height(); if (d->pageHeaderAny) h += d->pageHeaderAny->sizeHint().height(); if (d->pageHeaderEven) h += d->pageHeaderEven->sizeHint().height(); if (d->pageHeaderFirst) h += d->pageHeaderFirst->sizeHint().height(); if (d->pageHeaderLast) h += d->pageHeaderLast->sizeHint().height(); if (d->pageHeaderOdd) h += d->pageHeaderOdd->sizeHint().height(); if (d->reportHeader) h += d->reportHeader->sizeHint().height(); if (d->reportFooter) { h += d->reportFooter->sizeHint().height(); } if (d->detail) { h += d->detail->sizeHint().height(); w += d->detail->sizeHint().width(); } h += d->hruler->height(); return QSize(w, h); } int KReportDesigner::pageWidthPx() const { QPageLayout layout; layout.setPageSize(QPageSize(KReportPageSize::pageSize(d->set->property("page-size").value().toString()))); layout.setOrientation(d->set->property("print-orientation").value().toString() == QLatin1String("portrait") ? QPageLayout::Portrait : QPageLayout::Landscape); - QSize pageSizePx = layout.fullRectPixels(KReportDpi::dpiX()).size(); + QSize pageSizePx = layout.fullRectPixels(KReportPrivate::dpiX()).size(); int width = pageSizePx.width(); - width = width - POINT_TO_INCH(d->set->property("margin-left").value().toDouble()) * KReportDpi::dpiX(); - width = width - POINT_TO_INCH(d->set->property("margin-right").value().toDouble()) * KReportDpi::dpiX(); + width = width - POINT_TO_INCH(d->set->property("margin-left").value().toDouble()) * KReportPrivate::dpiX(); + width = width - POINT_TO_INCH(d->set->property("margin-right").value().toDouble()) * KReportPrivate::dpiX(); return width; } void KReportDesigner::resizeEvent(QResizeEvent * event) { Q_UNUSED(event); d->hruler->setRulerLength(pageWidthPx()); } void KReportDesigner::setDetail(KReportDesignerSectionDetail *rsd) { if (!d->detail) { int idx = 0; if (d->pageHeaderFirst) idx++; if (d->pageHeaderOdd) idx++; if (d->pageHeaderEven) idx++; if (d->pageHeaderLast) idx++; if (d->pageHeaderAny) idx++; if (d->reportHeader) idx++; d->detail = rsd; d->vboxlayout->insertWidget(idx, d->detail); } } void KReportDesigner::deleteDetail() { delete d->detail; d->detail = 0; } KReportUnit KReportDesigner::pageUnit() const { QString u; bool found; u = d->unit->value().toString(); KReportUnit unit = KReportUnit::fromSymbol(u, &found); if (!found) { unit = KReportUnit(KReportUnit::Centimeter); } return unit; } void KReportDesigner::setGridOptions(bool vis, int div) { d->showGrid->setValue(QVariant(vis)); d->gridDivisions->setValue(div); } // // methods for the sectionMouse*Event() // void KReportDesigner::sectionContextMenuEvent(KReportDesignerSectionScene * s, QGraphicsSceneContextMenuEvent * e) { Q_UNUSED(s); QMenu pop; bool itemsSelected = selectionCount() > 0; if (itemsSelected) { //! @todo KF5 use KStandardAction QAction *a = new QAction(QIcon::fromTheme(QLatin1String("edit-cut")), tr("Cut"), this); connect(a, SIGNAL(triggered()), this, SLOT(slotEditCut())); pop.addAction(a); //! @todo KF5 use KStandardAction a = new QAction(QIcon::fromTheme(QLatin1String("edit-copy")), tr("Copy"), this); connect(a, SIGNAL(triggered()), this, SLOT(slotEditCopy())); pop.addAction(a); } if (!d->sectionData->copy_list.isEmpty()) { QAction *a = new QAction(QIcon::fromTheme(QLatin1String("edit-paste")), tr("Paste"), this); connect(a, SIGNAL(triggered()), this, SLOT(slotEditPaste())); pop.addAction(a); } if (itemsSelected) { pop.addSeparator(); //! @todo KF5 use KStandard* //const KGuiItem del = KStandardGuiItem::del(); //a->setToolTip(del.toolTip()); //a->setShortcut(QKeySequence(QKeySequence::Delete)); QAction *a = new QAction(QIcon::fromTheme(QLatin1String("edit-delete")), tr("Delete"), this); connect(a, SIGNAL(triggered()), SLOT(slotEditDelete())); pop.addAction(a); } if (!pop.actions().isEmpty()) { pop.exec(e->screenPos()); } } void KReportDesigner::sectionMousePressEvent(KReportDesignerSectionView * v, QMouseEvent * e) { Q_UNUSED(v); d->pressX = e->pos().x(); d->pressY = e->pos().y(); } void KReportDesigner::sectionMouseReleaseEvent(KReportDesignerSectionView * v, QMouseEvent * e) { e->accept(); d->releaseX = e->pos().x(); d->releaseY = e->pos().y(); if (e->button() == Qt::LeftButton) { QPointF pos(d->pressX, d->pressY); QPointF end(d->releaseX, d->releaseY); if (d->releaseY >= v->scene()->height()) { d->releaseY = v->scene()->height(); end.setY(v->scene()->height()); } if (d->releaseX >= v->scene()->width()) { d->releaseX = v->scene()->width(); end.setX(v->scene()->width()); } if (d->sectionData->mouseAction == ReportWriterSectionData::MA_Insert) { QGraphicsItem * item = 0; QString classString; QString iconName; if (d->sectionData->insertItem == QLatin1String("org.kde.kreport.line")) { item = new KReportDesignerItemLine(v->designer(), v->scene(), pos, end); classString = tr("Line", "Report line element"); iconName = QLatin1String("kreport-line-element"); } else { KReportPluginManager* pluginManager = KReportPluginManager::self(); KReportPluginInterface *plug = pluginManager->plugin(d->sectionData->insertItem); if (plug) { QObject *obj = plug->createDesignerInstance(v->designer(), v->scene(), pos); if (obj) { item = dynamic_cast(obj); classString = plug->metaData()->name(); iconName = plug->metaData()->iconName(); } } else { kreportWarning() << "attempted to insert an unknown item"; } } if (item) { item->setVisible(true); item->setSelected(true); KReportItemBase* baseReportItem = dynamic_cast(item); if (baseReportItem) { baseReportItem->setUnit(pageUnit()); KPropertySet *set = baseReportItem->propertySet(); KReportDesigner::addMetaProperties(set, classString, iconName); changeSet(set); if (v && v->designer()) { v->designer()->setModified(true); } emit itemInserted(d->sectionData->insertItem); } } d->sectionData->mouseAction = ReportWriterSectionData::MA_None; d->sectionData->insertItem.clear(); unsetSectionCursor(); } } } unsigned int KReportDesigner::selectionCount() const { if (activeScene()) return activeScene()->selectedItems().count(); else return 0; } void KReportDesigner::changeSet(KPropertySet *s) { //Set the checked state of the report properties button if (s == d->set) d->pageButton->setCheckState(Qt::Checked); else d->pageButton->setCheckState(Qt::Unchecked); d->itmset = s; emit propertySetChanged(); } // // Actions // void KReportDesigner::slotItem(const QString &entity) { //kreportDebug() << entity; d->sectionData->mouseAction = ReportWriterSectionData::MA_Insert; d->sectionData->insertItem = entity; setSectionCursor(QCursor(Qt::CrossCursor)); } void KReportDesigner::slotEditDelete() { QGraphicsItem * item = 0; bool modified = false; while (selectionCount() > 0) { item = activeScene()->selectedItems().value(0); if (item) { QGraphicsScene * scene = item->scene(); delete item; scene->update(); d->sectionData->mouseAction = ReportWriterSectionData::MA_None; modified = true; } } activeScene()->selectedItems().clear(); /*! @todo temporary: clears cut and copy lists to make sure we do not crash if weve deleted something in the list should really check if an item is in the list first and remove it. */ d->sectionData->cut_list.clear(); d->sectionData->copy_list.clear(); if (modified) { setModified(true); } } void KReportDesigner::slotEditCut() { if (selectionCount() > 0) { //First delete any items that are curerntly in the list //so as not to leak memory qDeleteAll(d->sectionData->cut_list); d->sectionData->cut_list.clear(); QGraphicsItem * item = activeScene()->selectedItems().first(); bool modified = false; if (item) { d->sectionData->copy_list.clear(); foreach(QGraphicsItem *item, activeScene()->selectedItems()) { d->sectionData->cut_list.append(dynamic_cast(item)); d->sectionData->copy_list.append(dynamic_cast(item)); } foreach(QGraphicsItem *item, activeScene()->selectedItems()) { activeScene()->removeItem(item); activeScene()->update(); modified = true; } d->sectionData->selected_x_offset = 10; d->sectionData->selected_y_offset = 10; } if (modified) { setModified(true); } } } void KReportDesigner::slotEditCopy() { if (selectionCount() < 1) return; QGraphicsItem * item = activeScene()->selectedItems().first(); if (item) { d->sectionData->copy_list.clear(); foreach(QGraphicsItem *item, activeScene()->selectedItems()) { d->sectionData->copy_list.append(dynamic_cast(item)); } d->sectionData->selected_x_offset = 10; d->sectionData->selected_y_offset = 10; } } void KReportDesigner::slotEditPaste() { // call the editPaste function passing it a reportsection slotEditPaste(activeScene()); } void KReportDesigner::slotEditPaste(QGraphicsScene * canvas) { // paste a new item of the copy we have in the specified location if (!d->sectionData->copy_list.isEmpty()) { QList activeItems = canvas->selectedItems(); QGraphicsItem *activeItem = 0; if (activeItems.count() == 1) { activeItem = activeItems.first(); } canvas->clearSelection(); d->sectionData->mouseAction = ReportWriterSectionData::MA_None; //! @todo this code sucks :) //! The setPos calls only work AFTER the name has been set ?!?!? foreach(KReportDesignerItemBase *item, d->sectionData->copy_list) { KReportItemBase *obj = dynamic_cast(item); const QString type = obj ? obj->typeName() : QLatin1String("object"); //kreportDebug() << type; KReportDesignerItemBase *ent = item->clone(); KReportItemBase *new_obj = dynamic_cast(ent); new_obj->setEntityName(suggestEntityName(type)); if (activeItem) { new_obj->setPosition(KReportItemBase::positionFromScene(QPointF(activeItem->x() + 10, activeItem->y() + 10))); } else { new_obj->setPosition(KReportItemBase::positionFromScene(QPointF(0, 0))); } changeSet(new_obj->propertySet()); QGraphicsItem *pasted_ent = dynamic_cast(ent); if (pasted_ent) { pasted_ent->setSelected(true); canvas->addItem(pasted_ent); pasted_ent->show(); d->sectionData->mouseAction = ReportWriterSectionData::MA_Grab; setModified(true); } } } } void KReportDesigner::slotRaiseSelected() { dynamic_cast(activeScene())->raiseSelected(); } void KReportDesigner::slotLowerSelected() { dynamic_cast(activeScene())->lowerSelected(); } QGraphicsScene* KReportDesigner::activeScene() const { return d->activeScene; } void KReportDesigner::setActiveScene(QGraphicsScene* a) { if (d->activeScene && d->activeScene != a) d->activeScene->clearSelection(); d->activeScene = a; //Trigger an update so that the last scene redraws its title; update(); } KReportZoomHandler* KReportDesigner::zoomHandler() const { return d->zoom; } QString KReportDesigner::suggestEntityName(const QString &n) const { KReportDesignerSection *sec; int itemCount = 0; //Count items in the main sections for (int i = 1; i <= KReportSectionData::PageFooterAny; i++) { sec = section((KReportSectionData::Section) i); if (sec) { const QGraphicsItemList l = sec->items(); itemCount += l.count(); } } if (d->detail) { //Count items in the group headers/footers for (int i = 0; i < d->detail->groupSectionCount(); i++) { sec = d->detail->groupSection(i)->groupHeader(); if (sec) { const QGraphicsItemList l = sec->items(); itemCount += l.count(); } sec = d->detail->groupSection(i)->groupFooter(); if (sec) { const QGraphicsItemList l = sec->items(); itemCount += l.count(); } } sec = d->detail->detailSection(); if (sec) { const QGraphicsItemList l = sec->items(); itemCount += l.count(); } } while (!isEntityNameUnique(n + QString::number(itemCount))) { itemCount++; } return n + QString::number(itemCount); } bool KReportDesigner::isEntityNameUnique(const QString &n, KReportItemBase* ignore) const { KReportDesignerSection *sec; bool unique = true; //Check items in the main sections for (int i = 1; i <= KReportSectionData::PageFooterAny; i++) { sec = section((KReportSectionData::Section)i); if (sec) { const QGraphicsItemList l = sec->items(); for (QGraphicsItemList::const_iterator it = l.constBegin(); it != l.constEnd(); ++it) { KReportItemBase* itm = dynamic_cast(*it); if (itm && itm->entityName() == n && itm != ignore) { unique = false; break; } } if (!unique) break; } } //Count items in the group headers/footers if (unique && d->detail) { for (int i = 0; i < d->detail->groupSectionCount(); ++i) { sec = d->detail->groupSection(i)->groupHeader(); if (sec) { const QGraphicsItemList l = sec->items(); for (QGraphicsItemList::const_iterator it = l.constBegin(); it != l.constEnd(); ++it) { KReportItemBase* itm = dynamic_cast(*it); if (itm && itm->entityName() == n && itm != ignore) { unique = false; break; } } } sec = d->detail->groupSection(i)->groupFooter(); if (unique && sec) { const QGraphicsItemList l = sec->items(); for (QGraphicsItemList::const_iterator it = l.constBegin(); it != l.constEnd(); ++it) { KReportItemBase* itm = dynamic_cast(*it); if (itm && itm->entityName() == n && itm != ignore) { unique = false; break; } } } } } if (unique && d->detail) { sec = d->detail->detailSection(); if (sec) { const QGraphicsItemList l = sec->items(); for (QGraphicsItemList::const_iterator it = l.constBegin(); it != l.constEnd(); ++it) { KReportItemBase* itm = dynamic_cast(*it); if (itm && itm->entityName() == n && itm != ignore) { unique = false; break; } } } } return unique; } static bool actionPriortyLessThan(QAction* act1, QAction* act2) { if (act1->data().toInt() > 0 && act2->data().toInt() > 0) { return act1->data().toInt() < act2->data().toInt(); } return false; } QList KReportDesigner::itemActions(QActionGroup* group) { KReportPluginManager* manager = KReportPluginManager::self(); QList actList = manager->createActions(group); //! @todo make line a real plugin so this isn't needed: QAction *act = new QAction(QIcon::fromTheme(QLatin1String("kreport-line-element")), tr("Line"), group); act->setObjectName(QLatin1String("org.kde.kreport.line")); act->setData(9); act->setCheckable(true); actList << act; qSort(actList.begin(), actList.end(), actionPriortyLessThan); int i = 0; /*! @todo maybe this is a bit hackish It finds the first plugin based on the priority in userdata The lowest oriority a plugin can have is 10 And inserts a separator before it. */ bool sepInserted = false; foreach(QAction *a, actList) { ++i; if (!sepInserted && a->data().toInt() >= 10) { QAction *sep = new QAction(QLatin1String("separator"), group); sep->setSeparator(true); actList.insert(i-1, sep); sepInserted = true; } if (group) { group->addAction(a); } } return actList; } QList< QAction* > KReportDesigner::designerActions() { QList al; QAction *sep = new QAction(QString(), this); sep->setSeparator(true); al << d->editCutAction << d->editCopyAction << d->editPasteAction << d->editDeleteAction << sep << d->sectionEdit << sep << d->itemLowerAction << d->itemRaiseAction; return al; } void KReportDesigner::createActions() { d->editCutAction = new QAction(QIcon::fromTheme(QLatin1String("edit-cut")), tr("Cu&t"), this); d->editCutAction->setObjectName(QLatin1String("edit_cut")); d->editCutAction->setToolTip(tr("Cut selection to clipboard")); d->editCutAction->setShortcuts(KStandardShortcut::cut()); d->editCutAction->setProperty("iconOnly", true); d->editCopyAction = new QAction(QIcon::fromTheme(QLatin1String("edit-copy")), tr("&Copy"), this); d->editCopyAction->setObjectName(QLatin1String("edit_copy")); d->editCopyAction->setToolTip(tr("Copy selection to clipboard")); d->editCopyAction->setShortcuts(KStandardShortcut::copy()); d->editCopyAction->setProperty("iconOnly", true); d->editPasteAction = new QAction(QIcon::fromTheme(QLatin1String("edit-paste")), tr("&Paste"), this); d->editPasteAction->setObjectName(QLatin1String("edit_paste")); d->editPasteAction->setToolTip(tr("Paste clipboard content")); d->editPasteAction->setShortcuts(KStandardShortcut::paste()); d->editPasteAction->setProperty("iconOnly", true); const KGuiItem del = KStandardGuiItem::del(); d->editDeleteAction = new QAction(del.icon(), del.text(), this); d->editDeleteAction->setObjectName(QLatin1String("edit_delete")); d->editDeleteAction->setToolTip(del.toolTip()); d->editDeleteAction->setWhatsThis(del.whatsThis()); d->editDeleteAction->setProperty("iconOnly", true); d->sectionEdit = new QAction(tr("Edit Sections"), this); d->sectionEdit->setObjectName(QLatin1String("section_edit")); d->itemRaiseAction = new QAction(QIcon::fromTheme(QLatin1String("arrow-up")), tr("Raise"), this); d->itemRaiseAction->setObjectName(QLatin1String("item_raise")); d->itemLowerAction = new QAction(QIcon::fromTheme(QLatin1String("arrow-down")), tr("Lower"), this); d->itemLowerAction->setObjectName(QLatin1String("item_lower")); //Edit Actions connect(d->editCutAction, SIGNAL(triggered(bool)), this, SLOT(slotEditCut())); connect(d->editCopyAction, SIGNAL(triggered(bool)), this, SLOT(slotEditCopy())); connect(d->editPasteAction, SIGNAL(triggered(bool)), this, SLOT(slotEditPaste())); connect(d->editDeleteAction, SIGNAL(triggered(bool)), this, SLOT(slotEditDelete())); connect(d->sectionEdit, SIGNAL(triggered(bool)), this, SLOT(slotSectionEditor())); //Raise/Lower connect(d->itemRaiseAction, SIGNAL(triggered(bool)), this, SLOT(slotRaiseSelected())); connect(d->itemLowerAction, SIGNAL(triggered(bool)), this, SLOT(slotLowerSelected())); } void KReportDesigner::setSectionCursor(const QCursor& c) { if (d->pageFooterAny) d->pageFooterAny->setSectionCursor(c); if (d->pageFooterEven) d->pageFooterEven->setSectionCursor(c); if (d->pageFooterFirst) d->pageFooterFirst->setSectionCursor(c); if (d->pageFooterLast) d->pageFooterLast->setSectionCursor(c); if (d->pageFooterOdd) d->pageFooterOdd->setSectionCursor(c); if (d->pageHeaderAny) d->pageHeaderAny->setSectionCursor(c); if (d->pageHeaderEven) d->pageHeaderEven->setSectionCursor(c); if (d->pageHeaderFirst) d->pageHeaderFirst->setSectionCursor(c); if (d->pageHeaderLast) d->pageHeaderLast->setSectionCursor(c); if (d->pageHeaderOdd) d->pageHeaderOdd->setSectionCursor(c); if (d->detail) d->detail->setSectionCursor(c); } void KReportDesigner::unsetSectionCursor() { if (d->pageFooterAny) d->pageFooterAny->unsetSectionCursor(); if (d->pageFooterEven) d->pageFooterEven->unsetSectionCursor(); if (d->pageFooterFirst) d->pageFooterFirst->unsetSectionCursor(); if (d->pageFooterLast) d->pageFooterLast->unsetSectionCursor(); if (d->pageFooterOdd) d->pageFooterOdd->unsetSectionCursor(); if (d->pageHeaderAny) d->pageHeaderAny->unsetSectionCursor(); if (d->pageHeaderEven) d->pageHeaderEven->unsetSectionCursor(); if (d->pageHeaderFirst) d->pageHeaderFirst->unsetSectionCursor(); if (d->pageHeaderLast) d->pageHeaderLast->unsetSectionCursor(); if (d->pageHeaderOdd) d->pageHeaderOdd->unsetSectionCursor(); if (d->detail) d->detail->unsetSectionCursor(); } qreal KReportDesigner::countSelectionHeight() const { if (d->releaseY == -1 || d->pressY == -1) { return -1; } return qAbs(d->releaseY - d->pressY); } qreal KReportDesigner::countSelectionWidth() const { if (d->releaseX == -1 || d->pressX == -1) { return -1; } return qAbs(d->releaseX - d->pressX); } qreal KReportDesigner::getSelectionPressX() const { return d->pressX; } qreal KReportDesigner::getSelectionPressY() const { return d->pressY; } QPointF KReportDesigner::getPressPoint() const { return QPointF(d->pressX, d->pressY); } QPointF KReportDesigner::getReleasePoint() const { return QPointF(d->releaseX, d->releaseY); } void KReportDesigner::plugItemActions(const QList &actList) { foreach(QAction *a, actList) { connect(a, SIGNAL(triggered(bool)), this, SLOT(slotItemTriggered(bool))); } } void KReportDesigner::slotItemTriggered(bool checked) { if (!checked) { return; } QObject *theSender = sender(); if (!theSender) { return; } slotItem(theSender->objectName()); } void KReportDesigner::addMetaProperties(KPropertySet* set, const QString &classString, const QString &iconName) { Q_ASSERT(set); KProperty *prop; set->addProperty(prop = new KProperty("this:classString", classString)); prop->setVisible(false); set->addProperty(prop = new KProperty("this:iconName", iconName)); prop->setVisible(false); } diff --git a/src/wrtembed/KReportDesignerItemRectBase.cpp b/src/wrtembed/KReportDesignerItemRectBase.cpp index 45bbaf90..b5f84118 100644 --- a/src/wrtembed/KReportDesignerItemRectBase.cpp +++ b/src/wrtembed/KReportDesignerItemRectBase.cpp @@ -1,387 +1,387 @@ /* This file is part of the KDE project * Copyright (C) 2001-2007 by OpenMFG, LLC (info@openmfg.com) * Copyright (C) 2007-2008 by Adam Pigg (adam@piggz.co.uk) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include "KReportDesignerItemRectBase.h" #include "KReportDesignerSectionView.h" #include "KReportDesigner.h" #include "KReportDesignerSectionScene.h" -#include "KReportDpi.h" +#include "KReportUtils_p.h" #include #include #include class Q_DECL_HIDDEN KReportDesignerItemRectBase::Private { public: Private(); ~Private(); int grabAction; }; KReportDesignerItemRectBase::Private::Private() { } KReportDesignerItemRectBase::Private::~Private() { } KReportDesignerItemRectBase::KReportDesignerItemRectBase(KReportDesigner *r, KReportItemBase *b) : QGraphicsRectItem(), KReportDesignerItemBase(r, b), d(new KReportDesignerItemRectBase::Private) { - m_dpiX = KReportDpi::dpiX(); - m_dpiY = KReportDpi::dpiY(); + m_dpiX = KReportPrivate::dpiX(); + m_dpiY = KReportPrivate::dpiY(); d->grabAction = 0; setAcceptHoverEvents(true); setFlags(ItemIsSelectable | ItemIsMovable | ItemSendsGeometryChanges); } KReportDesignerItemRectBase::~KReportDesignerItemRectBase() { delete d; } QRectF KReportDesignerItemRectBase::sceneRect() { return QRectF(KReportItemBase::scenePosition(item()->position()), KReportItemBase::sceneSize(item()->size())); } QRectF KReportDesignerItemRectBase::pointRect() const { return QRectF(item()->position(), item()->size()); } void KReportDesignerItemRectBase::setSceneRect(const QPointF& topLeft, const QSizeF& size, UpdatePropertyFlag update) { setSceneRect(QRectF(topLeft, size), update); } void KReportDesignerItemRectBase::setSceneRect(const QRectF& rect, UpdatePropertyFlag update) { QGraphicsRectItem::setPos(rect.x(), rect.y()); setRect(0, 0, rect.width(), rect.height()); if (update == UpdateProperty) { item()->setPosition(KReportItemBase::positionFromScene(QPointF(rect.x(), rect.y()))); item()->setSize(KReportItemBase::sizeFromScene(QSizeF(rect.width(), rect.height()))); } this->update(); } void KReportDesignerItemRectBase::mousePressEvent(QGraphicsSceneMouseEvent * event) { //Update and show properties item()->setPosition(KReportItemBase::positionFromScene(QPointF(sceneRect().x(), sceneRect().y()))); designer()->changeSet(item()->propertySet()); setSelected(true); scene()->update(); QGraphicsItem::mousePressEvent(event); } void KReportDesignerItemRectBase::mouseReleaseEvent(QGraphicsSceneMouseEvent * event) { //Keep the size and position in sync item()->setPosition(KReportItemBase::positionFromScene(pos())); item()->setSize(KReportItemBase::sizeFromScene(QSizeF(rect().width(), rect().height()))); QGraphicsItem::mouseReleaseEvent(event); } void KReportDesignerItemRectBase::mouseMoveEvent(QGraphicsSceneMouseEvent * event) { //kreportDebug() << m_grabAction; qreal w, h; QPointF p = dynamic_cast(scene())->gridPoint(event->scenePos()); w = p.x() - scenePos().x(); h = p.y() - scenePos().y(); //! @todo use an enum for the directions switch (d->grabAction) { case 1: if (sceneRect().y() - p.y() + rect().height() > 0 && sceneRect().x() - p.x() + rect().width() >= 0) setSceneRect(QPointF(p.x(), p.y()), QSizeF(sceneRect().x() - p.x() + rect().width(), sceneRect().y() - p.y() + rect().height())); break; case 2: if (sceneRect().y() - p.y() + rect().height() >= 0) setSceneRect(QPointF(sceneRect().x(), p.y()), QSizeF(rect().width(), sceneRect().y() - p.y() + rect().height())); break; case 3: if (sceneRect().y() - p.y() + rect().height() >= 0 && w >= 0) setSceneRect(QPointF(sceneRect().x(), p.y()), QSizeF(w, sceneRect().y() - p.y() + rect().height())); break; case 4: if (w >= 0) setSceneRect(QPointF(sceneRect().x(), sceneRect().y()), QSizeF(w, (rect().height()))); break; case 5: if (h >= 0 && w >= 0) setSceneRect(QPointF(sceneRect().x(), sceneRect().y()), QSizeF(w, h)); break; case 6: if (h >= 0) setSceneRect(QPointF(sceneRect().x(), sceneRect().y()), QSizeF((rect().width()), h)); break; case 7: if (sceneRect().x() - p.x() + rect().width() >= 0 && h >= 0) setSceneRect(QPointF(p.x(), sceneRect().y()), QSizeF(sceneRect().x() - p.x() + rect().width(), h)); break; case 8: if (sceneRect().x() - p.x() + rect().width() >= 0) setSceneRect(QPointF(p.x(), sceneRect().y()), QSizeF(sceneRect().x() - p.x() + rect().width(), rect().height())); break; default: QGraphicsItem::mouseMoveEvent(event); } } void KReportDesignerItemRectBase::hoverMoveEvent(QGraphicsSceneHoverEvent * event) { //m_grabAction = 0; if (isSelected()) { d->grabAction = grabHandle(event->pos()); switch (d->grabAction) { case 1: setCursor(Qt::SizeFDiagCursor); break; case 2: setCursor(Qt::SizeVerCursor); break; case 3: setCursor(Qt::SizeBDiagCursor); break; case 4: setCursor(Qt::SizeHorCursor); break; case 5: setCursor(Qt::SizeFDiagCursor); break; case 6: setCursor(Qt::SizeVerCursor); break; case 7: setCursor(Qt::SizeBDiagCursor); break; case 8: setCursor(Qt::SizeHorCursor); break; default: unsetCursor(); } } //kreportDebug() << m_grabAction; } void KReportDesignerItemRectBase::drawHandles(QPainter *painter) { if (isSelected()) { // draw a selected border for visual purposes painter->setPen(QPen(QColor(128, 128, 255), 0, Qt::DotLine)); painter->drawRect(rect()); const QRectF r = rect(); double halfW = (r.width() / 2); double halfH = (r.height() / 2); QPointF center = r.center(); center += QPointF(0.75,0.75); painter->fillRect(center.x() - halfW, center.y() - halfH , 5, 5, QColor(128, 128, 255)); painter->fillRect(center.x() - 2, center.y() - halfH , 5, 5, QColor(128, 128, 255)); painter->fillRect(center.x() + halfW - 4, center.y() - halfH, 5, 5, QColor(128, 128, 255)); painter->fillRect(center.x() + (halfW - 4), center.y() - 2, 5, 5, QColor(128, 128, 255)); painter->fillRect(center.x() + halfW - 4 , center.y() + halfH - 4 , 5, 5, QColor(128, 128, 255)); painter->fillRect(center.x() - 2, center.y() + halfH - 4, 5, 5, QColor(128, 128, 255)); painter->fillRect(center.x() - halfW, center.y() + halfH - 4 , 5, 5, QColor(128, 128, 255)); painter->fillRect(center.x() - halfW, center.y() - 2, 5, 5, QColor(128, 128, 255)); } } /** @return 1 2 3 8 0 4 7 6 5 */ int KReportDesignerItemRectBase::grabHandle(QPointF pos) { QRectF r = boundingRect(); int halfW = (int)(r.width() / 2); int halfH = (int)(r.height() / 2); QPointF center = r.center(); if (QRectF(center.x() - (halfW), center.y() - (halfH), 5, 5).contains(pos)) { // we are over the top-left handle return 1; } else if (QRectF(center.x() - 2, center.y() - (halfH), 5, 5).contains(pos)) { // top-middle handle return 2; } else if (QRectF(center.x() + (halfW - 4), center.y() - (halfH), 5, 5).contains(pos)) { // top-right return 3; } else if (QRectF(center.x() + (halfW - 4), center.y() - 2, 5, 5).contains(pos)) { // middle-right return 4; } else if (QRectF(center.x() + (halfW - 4), center.y() + (halfH - 4), 5, 5).contains(pos)) { // bottom-left return 5; } else if (QRectF(center.x() - 2, center.y() + (halfH - 4), 5, 5).contains(pos)) { // bottom-middle return 6; } else if (QRectF(center.x() - (halfW), center.y() + (halfH - 4), 5, 5).contains(pos)) { // bottom-right return 7; } else if (QRectF(center.x() - (halfW), center.y() - 2, 5, 5).contains(pos)) { // middle-right return 8; } return 0; } QVariant KReportDesignerItemRectBase::itemChange(GraphicsItemChange change, const QVariant &value) { if (change == ItemPositionChange && scene()) { QPointF newPos = value.toPointF(); newPos = dynamic_cast(scene())->gridPoint(newPos); if (newPos.x() < 0) newPos.setX(0); else if (newPos.x() > (scene()->width() - rect().width())) newPos.setX(scene()->width() - rect().width()); if (newPos.y() < 0) newPos.setY(0); else if (newPos.y() > (scene()->height() - rect().height())) newPos.setY(scene()->height() - rect().height()); return newPos; } else if (change == ItemPositionHasChanged && scene()) { item()->setPosition(KReportItemBase::positionFromScene(value.toPointF())); //TODO dont update property //m_ppos->setScenePos(value.toPointF(), KReportPosition::DontUpdateProperty); } else if (change == ItemSceneHasChanged && scene() && item()) { QPointF newPos = pos(); newPos = dynamic_cast(scene())->gridPoint(newPos); if (newPos.x() < 0) newPos.setX(0); else if (newPos.x() > (scene()->width() - rect().width())) newPos.setX(scene()->width() - rect().width()); if (newPos.y() < 0) newPos.setY(0); else if (newPos.y() > (scene()->height() - rect().height())) newPos.setY(scene()->height() - rect().height()); setSceneRect(newPos, KReportItemBase::sceneSize(item()->size()), KReportDesignerItemRectBase::DontUpdateProperty); } return QGraphicsItem::itemChange(change, value); } void KReportDesignerItemRectBase::propertyChanged(const KPropertySet &s, const KProperty &p) { Q_UNUSED(s) if (p.name() == "position") { item()->setPosition(p.value().toPointF()); //TODO dont update property } else if (p.name() == "size") { item()->setSize(p.value().toSizeF()); //TODO dont update property } setSceneRect(KReportItemBase::scenePosition(item()->position()), KReportItemBase::sceneSize(item()->size()), DontUpdateProperty); } void KReportDesignerItemRectBase::move(const QPointF& /*m*/) { //! @todo } QPointF KReportDesignerItemRectBase::properPressPoint(const KReportDesigner &d) const { const QPointF pressPoint = d.getPressPoint(); const QPointF releasePoint = d.getReleasePoint(); if (releasePoint.x() < pressPoint.x() && releasePoint.y() < pressPoint.y()) { return releasePoint; } if (releasePoint.x() < pressPoint.x() && releasePoint.y() > pressPoint.y()) { return QPointF(releasePoint.x(), pressPoint.y()); } if (releasePoint.x() > pressPoint.x() && releasePoint.y() < pressPoint.y()) { return QPointF(pressPoint.x(), releasePoint.y()); } return QPointF(pressPoint); } QRectF KReportDesignerItemRectBase::properRect(const KReportDesigner &d, qreal minWidth, qreal minHeight) const { QPointF tempPressPoint = properPressPoint(d); qreal currentPressX = tempPressPoint.x(); qreal currentPressY = tempPressPoint.y(); const qreal width = qMax(d.countSelectionWidth(), minWidth); const qreal height = qMax(d.countSelectionHeight(), minHeight); qreal tempReleasePointX = tempPressPoint.x() + width; qreal tempReleasePointY = tempPressPoint.y() + height; if (tempReleasePointX > scene()->width()) { int offsetWidth = tempReleasePointX - scene()->width(); currentPressX = tempPressPoint.x() - offsetWidth; } if (tempReleasePointY > scene()->height()) { int offsetHeight = tempReleasePointY - scene()->height(); currentPressY = tempPressPoint.y() - offsetHeight; } return (QRectF(QPointF(currentPressX, currentPressY), QSizeF(width, height))); } void KReportDesignerItemRectBase::enterInlineEditingMode() { } void KReportDesignerItemRectBase::exitInlineEditingMode() { } void KReportDesignerItemBase::updateRenderText(const QString &itemDataSource, const QString &itemStaticValue, const QString &itemType) { if (itemDataSource.isEmpty()) { if (itemType.isEmpty()) { setRenderText(itemStaticValue); } else { setRenderText(dataSourceAndObjectTypeName(itemStaticValue, itemType)); } } else { if (itemType.isEmpty()) { setRenderText(itemDataSource); } else { setRenderText(dataSourceAndObjectTypeName(itemDataSource, itemType)); } } } diff --git a/src/wrtembed/KReportDesignerSection.cpp b/src/wrtembed/KReportDesignerSection.cpp index aa897f47..7a64c3ac 100644 --- a/src/wrtembed/KReportDesignerSection.cpp +++ b/src/wrtembed/KReportDesignerSection.cpp @@ -1,427 +1,427 @@ /* This file is part of the KDE project * Copyright (C) 2001-2007 by OpenMFG, LLC (info@openmfg.com) * Copyright (C) 2007-2008 by Adam Pigg (adam@piggz.co.uk) * Copyright (C) 2014 Jarosław Staniek * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include "KReportDesignerSection.h" #include "KReportDesignerSectionScene.h" #include "KReportDesignerSectionView.h" #include "KReportDesigner.h" #include "KReportDesignerItemBase.h" #include "KReportUtils.h" #include "KReportPluginInterface.h" #include "KReportPluginManager.h" #include "KReportDesignerItemRectBase.h" #include "KReportDesignerItemLine.h" #include "KReportRuler_p.h" #include "KReportZoomHandler.h" -#include "KReportDpi.h" +#include "KReportUtils_p.h" #include "KReportPluginMetaData.h" #include "kreport_debug.h" #include #include #include #include #include #include #include #include #include //! @internal class ReportResizeBar : public QFrame { Q_OBJECT public: explicit ReportResizeBar(QWidget * parent = 0, Qt::WindowFlags f = 0); Q_SIGNALS: void barDragged(int delta); protected: void mouseMoveEvent(QMouseEvent * e); }; //! @internal class KReportDesignerSectionTitle : public QLabel { Q_OBJECT public: explicit KReportDesignerSectionTitle(QWidget *parent = 0); ~KReportDesignerSectionTitle(); Q_SIGNALS: void clicked(); protected: virtual void paintEvent(QPaintEvent* event); virtual void mousePressEvent(QMouseEvent *event); }; //! @internal class Q_DECL_HIDDEN KReportDesignerSection::Private { public: explicit Private() {} ~Private() {} KReportDesignerSectionTitle *title; KReportDesignerSectionScene *scene; ReportResizeBar *resizeBar; KReportDesignerSectionView *sceneView; KReportDesigner*reportDesigner; KReportRuler *sectionRuler; KReportSectionData *sectionData; int dpiY; }; KReportDesignerSection::KReportDesignerSection(KReportDesigner * rptdes) : QWidget(rptdes) , d(new Private()) { Q_ASSERT(rptdes); d->sectionData = new KReportSectionData(this); connect(d->sectionData->propertySet(), SIGNAL(propertyChanged(KPropertySet&,KProperty&)), this, SLOT(slotPropertyChanged(KPropertySet&,KProperty&))); - d->dpiY = KReportDpi::dpiY(); + d->dpiY = KReportPrivate::dpiY(); d->reportDesigner = rptdes; setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); QGridLayout * glayout = new QGridLayout(this); glayout->setSpacing(0); glayout->setMargin(0); glayout->setColumnStretch(1, 1); glayout->setRowStretch(1, 1); glayout->setSizeConstraint(QLayout::SetFixedSize); // ok create the base interface d->title = new KReportDesignerSectionTitle(this); d->title->setObjectName(QLatin1String("detail")); d->title->setText(tr("Detail")); d->sectionRuler = new KReportRuler(this, Qt::Vertical, d->reportDesigner->zoomHandler()); d->sectionRuler->setUnit(d->reportDesigner->pageUnit()); d->scene = new KReportDesignerSectionScene(d->reportDesigner->pageWidthPx(), d->dpiY, rptdes); d->scene->setBackgroundBrush(d->sectionData->backgroundColor()); d->sceneView = new KReportDesignerSectionView(rptdes, d->scene, this); d->sceneView->setObjectName(QLatin1String("scene view")); d->sceneView->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); d->resizeBar = new ReportResizeBar(this); connect(d->resizeBar, SIGNAL(barDragged(int)), this, SLOT(slotResizeBarDragged(int))); connect(d->reportDesigner, SIGNAL(pagePropertyChanged(KPropertySet&)), this, SLOT(slotPageOptionsChanged(KPropertySet&))); connect(d->scene, SIGNAL(clicked()), this, (SLOT(slotSceneClicked()))); connect(d->scene, SIGNAL(lostFocus()), d->title, SLOT(update())); connect(d->title, SIGNAL(clicked()), this, (SLOT(slotSceneClicked()))); glayout->addWidget(d->title, 0, 0, 1, 2); glayout->addWidget(d->sectionRuler, 1, 0); glayout->addWidget(d->sceneView , 1, 1); glayout->addWidget(d->resizeBar, 2, 0, 1, 2); d->sectionRuler->setFixedWidth(d->sectionRuler->sizeHint().width()); setLayout(glayout); slotResizeBarDragged(0); } KReportDesignerSection::~KReportDesignerSection() { delete d; } void KReportDesignerSection::setTitle(const QString & s) { d->title->setText(s); } void KReportDesignerSection::slotResizeBarDragged(int delta) { if (d->sceneView->designer() && d->sceneView->designer()->propertySet()->property("page-size").value().toString() == QLatin1String("Labels")) { return; // we don't want to allow this on reports that are for labels } slotSceneClicked(); // switches property set to this section qreal h = d->scene->height() + delta; if (h < 1) h = 1; h = d->scene->gridPoint(QPointF(0, h)).y(); d->sectionData->m_height->setValue(INCH_TO_POINT(h/d->dpiY)); d->sectionRuler->setRulerLength(h); d->scene->setSceneRect(0, 0, d->scene->width(), h); d->sceneView->resizeContents(QSize(d->scene->width(), h)); d->reportDesigner->setModified(true); } void KReportDesignerSection::buildXML(QDomDocument *doc, QDomElement *section) { KReportUtils::setAttribute(section, QLatin1String("svg:height"), d->sectionData->m_height->value().toDouble()); section->setAttribute(QLatin1String("fo:background-color"), d->sectionData->backgroundColor().name()); // now get a list of all the QGraphicsItems on this scene and output them. QGraphicsItemList list = d->scene->items(); for (QGraphicsItemList::iterator it = list.begin(); it != list.end(); ++it) { KReportDesignerItemBase::buildXML((*it), doc, section); } } void KReportDesignerSection::initFromXML(const QDomNode & section) { QDomNodeList nl = section.childNodes(); QDomNode node; QString n; qreal h = KReportUnit::parseValue(section.toElement().attribute(QLatin1String("svg:height"), QLatin1String("2.0cm"))); d->sectionData->m_height->setValue(h); h = POINT_TO_INCH(h) * d->dpiY; //kreportDebug() << "Section Height: " << h; d->scene->setSceneRect(0, 0, d->scene->width(), h); slotResizeBarDragged(0); d->sectionData->m_backgroundColor->setValue(QColor(section.toElement().attribute(QLatin1String("fo:background-color"), QLatin1String("#ffffff")))); for (int i = 0; i < nl.count(); ++i) { node = nl.item(i); n = node.nodeName(); if (n.startsWith(QLatin1String("report:"))) { //Load objects //report:line is a special case as it is not a plugin QString reportItemName = n.mid(qstrlen("report:")); if (reportItemName == QLatin1String("line")) { (new KReportDesignerItemLine(node, d->sceneView->designer(), d->scene))->setVisible(true); continue; } KReportPluginManager* manager = KReportPluginManager::self(); KReportPluginInterface *plugin = manager->plugin(reportItemName); if (plugin) { QObject *obj = plugin->createDesignerInstance(node, d->reportDesigner, d->scene); if (obj) { KReportDesignerItemRectBase *entity = dynamic_cast(obj); if (entity) { entity->setVisible(true); } KReportItemBase *item = dynamic_cast(obj); if (item) { item->setUnit(d->reportDesigner->pageUnit()); KReportDesigner::addMetaProperties(item->propertySet(), plugin->metaData()->name(), plugin->metaData()->iconName()); } continue; } } } kreportWarning() << "Encountered unknown node while parsing section: " << n; } } QSize KReportDesignerSection::sizeHint() const { return QSize(d->scene->width() + d->sectionRuler->frameSize().width(), d->title->frameSize().height() + d->sceneView->sizeHint().height() + d->resizeBar->frameSize().height()); } void KReportDesignerSection::slotPageOptionsChanged(KPropertySet &set) { Q_UNUSED(set) KReportUnit unit = d->reportDesigner->pageUnit(); d->sectionData->m_height->setOption("unit", unit.symbol()); //update items position with unit QList itms = d->scene->items(); for (int i = 0; i < itms.size(); ++i) { KReportItemBase *obj = dynamic_cast(itms[i]); if (obj) { obj->setUnit(unit); } } d->scene->setSceneRect(0, 0, d->reportDesigner->pageWidthPx(), d->scene->height()); d->title->setMinimumWidth(d->reportDesigner->pageWidthPx() + d->sectionRuler->frameSize().width()); d->sectionRuler->setUnit(d->reportDesigner->pageUnit()); //Trigger a redraw of the background d->sceneView->resetCachedContent(); d->reportDesigner->adjustSize(); d->reportDesigner->repaint(); slotResizeBarDragged(0); } void KReportDesignerSection::slotSceneClicked() { d->reportDesigner->setActiveScene(d->scene); d->reportDesigner->changeSet(d->sectionData->propertySet()); } void KReportDesignerSection::slotPropertyChanged(KPropertySet &s, KProperty &p) { Q_UNUSED(s) //kreportDebug() << p.name(); //Handle Background Color if (p.name() == "background-color") { d->scene->setBackgroundBrush(p.value().value()); } if (p.name() == "height") { d->scene->setSceneRect(0, 0, d->scene->width(), POINT_TO_INCH(p.value().toDouble()) * d->dpiY); slotResizeBarDragged(0); } if (d->reportDesigner) d->reportDesigner->setModified(true); d->sceneView->resetCachedContent(); d->scene->update(); } void KReportDesignerSection::setSectionCursor(const QCursor& c) { if (d->sceneView) d->sceneView->setCursor(c); } void KReportDesignerSection::unsetSectionCursor() { if (d->sceneView) d->sceneView->unsetCursor(); } QGraphicsItemList KReportDesignerSection::items() const { QGraphicsItemList items; if (d->scene) { foreach (QGraphicsItem *itm, d->scene->items()) { if (itm->parentItem() == 0) { items << itm; } } } return items; } // // class ReportResizeBar // ReportResizeBar::ReportResizeBar(QWidget * parent, Qt::WindowFlags f) : QFrame(parent, f) { setCursor(QCursor(Qt::SizeVerCursor)); setFrameStyle(QFrame::HLine); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); } void ReportResizeBar::mouseMoveEvent(QMouseEvent * e) { e->accept(); emit barDragged(e->y()); } //============================================================================= KReportDesignerSectionTitle::KReportDesignerSectionTitle(QWidget*parent) : QLabel(parent) { setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); setAlignment(Qt::AlignLeft | Qt::AlignTop); setMinimumHeight(qMax(fontMetrics().lineSpacing(),16 + 2)); //16 = Small icon size } KReportDesignerSectionTitle::~KReportDesignerSectionTitle() { } //! \return true if \a o has parent \a par. static bool hasParent(QObject* par, QObject* o) { if (!o || !par) return false; while (o && o != par) o = o->parent(); return o == par; } static void replaceColors(QPixmap* original, const QColor& color) { QImage dest(original->toImage()); QPainter p(&dest); p.setCompositionMode(QPainter::CompositionMode_SourceIn); p.fillRect(dest.rect(), color); *original = QPixmap::fromImage(dest); } void KReportDesignerSectionTitle::paintEvent(QPaintEvent * event) { QPainter painter(this); KReportDesignerSection* _section = dynamic_cast(parent()); const bool current = _section->d->scene == _section->d->reportDesigner->activeScene(); QPalette::ColorGroup cg = QPalette::Inactive; QWidget *activeWindow = QApplication::activeWindow(); if (activeWindow) { QWidget *par = activeWindow->focusWidget(); if (qobject_cast(par)) { par = par->parentWidget(); // we're close, pick common parent } if (hasParent(par, this)) { cg = QPalette::Active; } } if (current) { painter.fillRect(rect(), palette().brush(cg, QPalette::Highlight)); } painter.setPen(palette().color(cg, current ? QPalette::HighlightedText : QPalette::WindowText)); QPixmap pixmap(QIcon::fromTheme(QLatin1String("arrow-down")).pixmap(16,16)); replaceColors(&pixmap, painter.pen().color()); const int left = 25; painter.drawPixmap(QPoint(left, (height() - pixmap.height()) / 2), pixmap); painter.drawText(rect().adjusted(left + pixmap.width() + 4, 0, 0, 0), Qt::AlignLeft | Qt::AlignVCenter, text()); QFrame::paintEvent(event); } void KReportDesignerSectionTitle::mousePressEvent(QMouseEvent *event) { QLabel::mousePressEvent(event); if (event->button() == Qt::LeftButton) { emit clicked(); } } #include "KReportDesignerSection.moc" diff --git a/src/wrtembed/KReportDesignerSectionScene.cpp b/src/wrtembed/KReportDesignerSectionScene.cpp index 95def202..a86c33e4 100644 --- a/src/wrtembed/KReportDesignerSectionScene.cpp +++ b/src/wrtembed/KReportDesignerSectionScene.cpp @@ -1,260 +1,260 @@ /* This file is part of the KDE project * Copyright (C) 2001-2007 by OpenMFG, LLC (info@openmfg.com) * Copyright (C) 2007-2008 by Adam Pigg (adam@piggz.co.uk) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include "KReportDesignerSectionScene.h" #include "KReportDesignerItemRectBase.h" #include "KReportDesigner.h" #include "KReportLabelSizeInfo.h" -#include "KReportDpi.h" +#include "KReportUtils_p.h" #include "kreport_debug.h" #include #include #include #include KReportDesignerSectionScene::KReportDesignerSectionScene(qreal w, qreal h, KReportDesigner *rd) : QGraphicsScene(0, 0, w, h, rd) { m_rd = rd; m_minorSteps = 0; - m_dpiX = KReportDpi::dpiX(); - m_dpiY = KReportDpi::dpiY(); + m_dpiX = KReportPrivate::dpiX(); + m_dpiY = KReportPrivate::dpiY(); if (m_unit.type() != m_rd->pageUnit().type()) { m_unit = m_rd->pageUnit(); if (m_unit.type() == KReportUnit::Cicero || m_unit.type() == KReportUnit::Pica || m_unit.type() == KReportUnit::Millimeter) { m_majorX = POINT_TO_INCH(m_unit.fromUserValue(10)) * m_dpiX; m_majorY = POINT_TO_INCH(m_unit.fromUserValue(10)) * m_dpiY; } else if (m_unit.type() == KReportUnit::Point) { m_majorX = POINT_TO_INCH(m_unit.fromUserValue(100)) * m_dpiX; m_majorY = POINT_TO_INCH(m_unit.fromUserValue(100)) * m_dpiY; } else { m_majorX = POINT_TO_INCH(m_unit.fromUserValue(1)) * m_dpiX; m_majorY = POINT_TO_INCH(m_unit.fromUserValue(1)) * m_dpiY; } } } KReportDesignerSectionScene::~KReportDesignerSectionScene() { // Qt should be handling everything for us } void KReportDesignerSectionScene::drawBackground(QPainter* painter, const QRectF & clip) { //Draw the default background colour QGraphicsScene::drawBackground(painter, clip); painter->setRenderHint(QPainter::Antialiasing, false); if (m_rd->propertySet()->property("grid-visible").value().toBool()) { if (m_unit.type() != m_rd->pageUnit().type()) { m_unit = m_rd->pageUnit(); if (m_unit.type() == KReportUnit::Cicero || m_unit.type() == KReportUnit::Pica || m_unit.type() == KReportUnit::Millimeter) { m_majorX = POINT_TO_INCH(m_unit.fromUserValue(10)) * m_dpiX; m_majorY = POINT_TO_INCH(m_unit.fromUserValue(10)) * m_dpiY; } else if (m_unit.type() == KReportUnit::Point) { m_majorX = POINT_TO_INCH(m_unit.fromUserValue(100)) * m_dpiX; m_majorY = POINT_TO_INCH(m_unit.fromUserValue(100)) * m_dpiY; } else { m_majorX = POINT_TO_INCH(m_unit.fromUserValue(1)) * m_dpiX; m_majorY = POINT_TO_INCH(m_unit.fromUserValue(1)) * m_dpiY; } } m_minorSteps = m_rd->propertySet()->property("grid-divisions").value().toInt(); m_pixelIncrementX = (m_majorX / m_minorSteps); m_pixelIncrementY = (m_majorY / m_minorSteps); QPen pen = painter->pen(); painter->setPen(Qt::lightGray); - //kreportDebug() << "dpix" << KReportDpi::dpiX() << "dpiy" << KReportDpi::dpiY() << "mayorx:" << majorx << "majory" << majory << "pix:" << pixel_incrementx << "piy:" << pixel_incrementy; + //kreportDebug() << "dpix" << KReportPrivate::dpiX() << "dpiy" << KReportPrivate::dpiY() << "mayorx:" << majorx << "majory" << majory << "pix:" << pixel_incrementx << "piy:" << pixel_incrementy; QVector lines; QVector points; if (m_pixelIncrementX > 2) { // do not bother painting points if increments are so small int wpoints = qRound(sceneRect().width() / m_pixelIncrementX); int hpoints = qRound(sceneRect().height() / m_pixelIncrementY); for (int i = 0; i < wpoints; ++i) { for (int j = 0; j < hpoints; ++j) { //if (clip.contains(i * pixel_incrementx, j * pixel_incrementy)){ if (i % m_minorSteps == 0 && j % m_minorSteps == 0) { lines << QLine(QPoint(i * m_pixelIncrementX, j * m_pixelIncrementY), QPoint(i * m_pixelIncrementX, j * m_pixelIncrementY + m_majorX)); //painter->drawLine(); lines << QLine(QPoint(i * m_pixelIncrementX, j * m_pixelIncrementY), QPoint(i * m_pixelIncrementX + m_majorY, j * m_pixelIncrementY)); //painter->drawLine(); } else { points << QPoint(i * m_pixelIncrementX, j * m_pixelIncrementY); //painter->drawPoint(); } //} } } painter->drawPoints(points); painter->drawLines(lines); } pen.setWidth(1); //update ( clip ); } } void KReportDesignerSectionScene::mousePressEvent(QGraphicsSceneMouseEvent * e) { // clear the selection if Shift Key has not been pressed and it's a left mouse button and // if the right mouse button has been pressed over an item which is not part of selected items if (((e->modifiers() & Qt::ShiftModifier) == 0 && e->button() == Qt::LeftButton) || (!(selectedItems().contains(itemAt(e->scenePos(), QTransform()))) && e->button() == Qt::RightButton)) clearSelection(); //This will be caught by the section to display its properties, if an item is under the cursor then they will display their properties QGraphicsItem* itemUnderCursor = itemAt(e->scenePos(), QTransform()); emit clicked(); KReportDesignerItemRectBase *rectUnderCursor = qgraphicsitem_cast< KReportDesignerItemRectBase* >(itemUnderCursor); if (itemUnderCursor && !rectUnderCursor) { rectUnderCursor = qgraphicsitem_cast< KReportDesignerItemRectBase* >(itemUnderCursor->parentItem()); } exitInlineEditingModeInItems(rectUnderCursor); QGraphicsScene::mousePressEvent(e); } void KReportDesignerSectionScene::contextMenuEvent(QGraphicsSceneContextMenuEvent * e) { m_rd->sectionContextMenuEvent(this, e); } QPointF KReportDesignerSectionScene::gridPoint(const QPointF& p) { if (!m_rd->propertySet()->property("grid-snap").value().toBool()) { return p; } if (m_unit.type() != m_rd->pageUnit().type()) { m_unit = m_rd->pageUnit(); //! @todo Again? Copy&Paste error? if (m_unit.type() != m_rd->pageUnit().type()) { m_unit = m_rd->pageUnit(); if (m_unit.type() == KReportUnit::Cicero || m_unit.type() == KReportUnit::Pica || m_unit.type() == KReportUnit::Millimeter) { m_majorX = POINT_TO_INCH(m_unit.fromUserValue(10)) * m_dpiX; m_majorY = POINT_TO_INCH(m_unit.fromUserValue(10)) * m_dpiY; } else if (m_unit.type() == KReportUnit::Point) { m_majorX = POINT_TO_INCH(m_unit.fromUserValue(100)) * m_dpiX; m_majorY = POINT_TO_INCH(m_unit.fromUserValue(100)) * m_dpiY; } else { m_majorX = POINT_TO_INCH(m_unit.fromUserValue(1)) * m_dpiX; m_majorY = POINT_TO_INCH(m_unit.fromUserValue(1)) * m_dpiY; } } } m_minorSteps = m_rd->propertySet()->property("grid-divisions").value().toInt(); m_pixelIncrementX = (m_majorX / m_minorSteps); m_pixelIncrementY = (m_majorY / m_minorSteps); return QPointF(qRound((p.x() / m_pixelIncrementX)) * m_pixelIncrementX, qRound((p.y() / m_pixelIncrementY)) * m_pixelIncrementY); } void KReportDesignerSectionScene::focusOutEvent(QFocusEvent * focusEvent) { exitInlineEditingModeInItems(0); emit lostFocus(); QGraphicsScene::focusOutEvent(focusEvent); } qreal KReportDesignerSectionScene::lowestZValue() { qreal z; qreal zz; z = 0; QGraphicsItemList list = items(); for (QGraphicsItemList::iterator it = list.begin(); it != list.end(); ++it) { zz = (*it)->zValue(); if (zz < z) { z = zz; } } return z; } qreal KReportDesignerSectionScene::highestZValue() { qreal z; qreal zz; z = 0; QGraphicsItemList list = items(); for (QGraphicsItemList::iterator it = list.begin(); it != list.end(); ++it) { zz = (*it)->zValue(); if (zz > z) { z = zz; } } return z; } void KReportDesignerSectionScene::lowerSelected() { QGraphicsItemList list = selectedItems(); for (QGraphicsItemList::iterator it = list.begin(); it != list.end(); ++it) { (*it)->setZValue(lowestZValue() - 1); } } void KReportDesignerSectionScene::raiseSelected() { QGraphicsItemList list = selectedItems(); for (QGraphicsItemList::iterator it = list.begin(); it != list.end(); ++it) { (*it)->setZValue(highestZValue() + 1); } } QGraphicsItemList KReportDesignerSectionScene::itemsOrdered() const { QGraphicsItemList r; QGraphicsItemList list = items(); for (QGraphicsItemList::iterator it = list.begin(); it != list.end(); ++it) { for (QGraphicsItemList::iterator rit = r.begin(); rit != r.end(); ++rit) { } } return r; } void KReportDesignerSectionScene::exitInlineEditingModeInItems(KReportDesignerItemRectBase *rectUnderCursor) { foreach(QGraphicsItem *it, items()) { KReportDesignerItemRectBase *itm = qgraphicsitem_cast< KReportDesignerItemRectBase* >(it); if (itm && itm != rectUnderCursor) { itm->exitInlineEditingMode(); } } } diff --git a/src/wrtembed/KReportDpi.cpp b/src/wrtembed/KReportDpi.cpp deleted file mode 100644 index eebe091d..00000000 --- a/src/wrtembed/KReportDpi.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2001 David Faure - Copyright 2003 Nicolas GOUTTE - Copyright 2009 Thomas Zander - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#include "KReportDpi.h" - -#ifdef Q_WS_X11 -#include -#else -#include -#include -#endif -#include - - -class KReportDpiSingleton -{ -public: - KReportDpiSingleton(); - - int m_dpiX; - int m_dpiY; -}; - -KReportDpiSingleton::KReportDpiSingleton() -{ - // Another way to get the DPI of the display would be QPaintDeviceMetrics, - // but we have no widget here (and moving this to KoView wouldn't allow - // using this from the document easily). -#ifdef Q_WS_X11 - m_dpiX = QX11Info::appDpiX(); - m_dpiY = QX11Info::appDpiY(); -#else - QDesktopWidget *w = QApplication::desktop(); - if (w) { - m_dpiX = w->logicalDpiX(); - m_dpiY = w->logicalDpiY(); - } else { - m_dpiX = 75; - m_dpiY = 75; - } -#endif -} - -Q_GLOBAL_STATIC(KReportDpiSingleton, s_instance) - -namespace KReportDpi -{ - -int dpiX() -{ - return s_instance->m_dpiX; -} - -int dpiY() -{ - return s_instance->m_dpiY; -} - -void setDpi(int x, int y) -{ - s_instance->m_dpiX = x; - s_instance->m_dpiY = y; -} - -} diff --git a/src/wrtembed/KReportDpi.h b/src/wrtembed/KReportDpi.h deleted file mode 100644 index 160900a3..00000000 --- a/src/wrtembed/KReportDpi.h +++ /dev/null @@ -1,41 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 1998, 1999 Torben Weis - Copyright 2002, 2003 David Faure - Copyright 2003 Nicolas GOUTTE - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. -*/ - -#ifndef KREPORT_DPI_h -#define KREPORT_DPI_h - - -#include "kreport_export.h" - -/** - * Singleton to store user-overwritten DPI information. - */ -namespace KReportDpi -{ - KREPORT_EXPORT int dpiX(); - - KREPORT_EXPORT int dpiY(); - - /// @internal, for KoApplication - KREPORT_EXPORT void setDpi(int x, int y); -} - -#endif // KREPORT_DPI_h diff --git a/src/wrtembed/KReportZoomHandler.cpp b/src/wrtembed/KReportZoomHandler.cpp index 0a1e7790..f0784fbd 100644 --- a/src/wrtembed/KReportZoomHandler.cpp +++ b/src/wrtembed/KReportZoomHandler.cpp @@ -1,169 +1,169 @@ /* This file is part of the KDE project Copyright (C) 2001-2005 David Faure Copyright (C) 2006 Thomas Zander Copyright (C) 2010 KO GmbH This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "KReportZoomHandler.h" #include "KReportUnit.h" // for POINT_TO_INCH -#include "KReportDpi.h" +#include "KReportUtils_p.h" #include #include KReportZoomHandler::KReportZoomHandler() : m_zoomMode(KReportZoomMode::ZOOM_CONSTANT) , m_resolutionX(0) , m_resolutionY(0) , m_zoomedResolutionX(0) , m_zoomedResolutionY(0) , m_zoomLevel(1.0) { setZoom(1.0); setZoomMode( KReportZoomMode::ZOOM_CONSTANT ); - setDpi(KReportDpi::dpiX(), KReportDpi::dpiY()); + setDpi(KReportPrivate::dpiX(), KReportPrivate::dpiY()); } KReportZoomHandler::~KReportZoomHandler() { } void KReportZoomHandler::setResolutionToStandard() { - setDpi(KReportDpi::dpiX(), KReportDpi::dpiY()); + setDpi(KReportPrivate::dpiX(), KReportPrivate::dpiY()); } void KReportZoomHandler::setDpi(int dpiX, int dpiY) { setResolution(POINT_TO_INCH(static_cast(dpiX)), POINT_TO_INCH(static_cast(dpiY))); } void KReportZoomHandler::setResolution( qreal resolutionX, qreal resolutionY ) { m_resolutionX = resolutionX; m_resolutionY = resolutionY; if (qFuzzyCompare(m_resolutionX, 1)) m_resolutionX = 1; if (qFuzzyCompare(m_resolutionY, 1)) m_resolutionY = 1; m_zoomedResolutionX = zoom() * resolutionX; m_zoomedResolutionY = zoom() * resolutionY; } void KReportZoomHandler::setZoomedResolution( qreal zoomedResolutionX, qreal zoomedResolutionY ) { // zoom() doesn't matter, it's only used in setZoom() to calculated the zoomed resolutions // Here we know them. The whole point of this method is to allow a different zoom factor // for X and for Y, as can be useful for e.g. fullscreen kpresenter presentations. m_zoomedResolutionX = zoomedResolutionX; m_zoomedResolutionY = zoomedResolutionY; } void KReportZoomHandler::setZoom( qreal zoom ) { if (qFuzzyCompare(zoom, qreal(0.0)) || qFuzzyCompare(zoom, qreal(1.0))) { zoom = 1.0; } m_zoomLevel = zoom; if( zoom == 1.0 ) { m_zoomedResolutionX = m_resolutionX; m_zoomedResolutionY = m_resolutionY; } else { m_zoomedResolutionX = zoom * m_resolutionX; m_zoomedResolutionY = zoom * m_resolutionY; } } QPointF KReportZoomHandler::documentToView( const QPointF &documentPoint ) const { return QPointF( zoomItX( documentPoint.x() ), zoomItY( documentPoint.y() )); } QPointF KReportZoomHandler::viewToDocument( const QPointF &viewPoint ) const { return QPointF( unzoomItX( viewPoint.x() ), unzoomItY( viewPoint.y() ) ); } QRectF KReportZoomHandler::documentToView( const QRectF &documentRect ) const { QRectF r (zoomItX( documentRect.x() ), zoomItY( documentRect.y() ), zoomItX( documentRect.width() ), zoomItY( documentRect.height() ) ); return r; } QRectF KReportZoomHandler::viewToDocument( const QRectF &viewRect ) const { QRectF r ( unzoomItX( viewRect.x() ), unzoomItY( viewRect.y()), unzoomItX( viewRect.width() ), unzoomItY( viewRect.height() ) ); return r; } QSizeF KReportZoomHandler::documentToView( const QSizeF &documentSize ) const { return QSizeF( zoomItX( documentSize.width() ), zoomItY( documentSize.height() ) ); } QSizeF KReportZoomHandler::viewToDocument( const QSizeF &viewSize ) const { return QSizeF( unzoomItX( viewSize.width() ), unzoomItY( viewSize.height() ) ); } qreal KReportZoomHandler::documentToViewX( qreal documentX ) const { return zoomItX( documentX ); } qreal KReportZoomHandler::documentToViewY( qreal documentY ) const { return zoomItY( documentY ); } qreal KReportZoomHandler::viewToDocumentX( qreal viewX ) const { return unzoomItX( viewX ); } qreal KReportZoomHandler::viewToDocumentY( qreal viewY ) const { return unzoomItY( viewY ); } void KReportZoomHandler::zoom(qreal *zoomX, qreal *zoomY) const { *zoomX = zoomItX(100.0) / 100.0; *zoomY = zoomItY(100.0) / 100.0; } qreal KReportZoomHandler::zoom() const { return m_zoomLevel; }