diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index dc3852de..9d9aa6d1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,303 +1,304 @@ # Options option(KREPORT_SCRIPTING "Enable scripting" OFF) configure_file(config-kreport.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-kreport.h) if(KREPORT_SCRIPTING) find_package(Qt5Qml REQUIRED) - set(SCRIPTING_LIBS Qt5Qml) + set(SCRIPTING_LIBS Qt5::Qml) endif() add_subdirectory(plugins) #add_subdirectory(pics) set(kreport_LIB_SRCS common/kreport_debug.cpp common/kreportplugin_debug.cpp common/krutils.cpp common/krpos.cpp common/krsize.cpp common/KoReportItemBase.cpp common/KoReportASyncItemBase.cpp common/krsectiondata.cpp common/labelsizeinfo.cpp common/reportpageoptions.cpp common/krreportdata.cpp common/krdetailsectiondata.cpp common/KoReportPluginInterface.cpp common/KoReportItemLine.cpp common/renderobjects.cpp common/KoReportPluginManager.cpp common/KReportJsonTrader_p.cpp common/KReportPluginMetaData.cpp common/KoReportData.cpp common/KReportPageFormat.cpp common/KReportUnit.cpp renderer/KoReportPrintRenderer.cpp renderer/KoReportPreRenderer.cpp renderer/KoReportASyncItemManager.cpp renderer/KoReportScreenRenderer.cpp renderer/KoReportHTMLTableRenderer.cpp renderer/KoReportHTMLCSSRenderer.cpp #TODO renderer/KoReportKSpreadRenderer.cpp #TODO renderer/KoReportODTRenderer.cpp #TODO renderer/KoOdtFrameReportRenderer.cpp renderer/KoReportRendererBase.cpp renderer/KoReportPage.cpp renderer/KReportView.cpp renderer/KReportOneRecordData.cpp wrtembed/detailgroupsectiondialog.cpp wrtembed/KoReportDesignerItemBase.cpp wrtembed/KoReportDesignerItemRectBase.cpp wrtembed/KoReportDesignerItemLine.cpp wrtembed/reportsection.cpp wrtembed/reportsectiondetailgroup.cpp wrtembed/reportsectiondetail.cpp wrtembed/reportscene.cpp wrtembed/reportsceneview.cpp wrtembed/KoReportDesigner.cpp wrtembed/reportpropertiesbutton.cpp wrtembed/sectioneditor.cpp wrtembed/KReportDpi.cpp wrtembed/KReportRuler.cpp wrtembed/KReportZoomHandler.cpp wrtembed/KReportZoomMode.cpp items/label/KoReportItemLabel.cpp items/label/KoReportDesignerItemLabel.cpp items/label/KoReportLabelPlugin.cpp items/label/BoundedTextItem.cpp items/check/KoReportItemCheck.cpp items/check/KoReportDesignerItemCheck.cpp items/check/KoReportCheckPlugin.cpp items/field/KoReportItemField.cpp items/field/KoReportDesignerItemField.cpp items/field/KoReportFieldPlugin.cpp items/image/KoReportItemImage.cpp items/image/KoReportDesignerItemImage.cpp items/image/KoReportImagePlugin.cpp items/text/KoReportItemText.cpp items/text/KoReportDesignerItemText.cpp items/text/KoReportTextPlugin.cpp ) if(KREPORT_SCRIPTING) list(APPEND kreport_LIB_SRCS renderer/scripting/krscripthandler.cpp renderer/scripting/krscriptconstants.cpp renderer/scripting/krscriptdebug.cpp renderer/scripting/krscriptdraw.cpp renderer/scripting/krscriptreport.cpp renderer/scripting/krscriptsection.cpp renderer/scripting/krscriptline.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/krscriptlabel.cpp items/check/KoReportScriptCheck.cpp items/field/krscriptfield.cpp items/image/krscriptimage.cpp items/text/krscripttext.cpp ) endif() qt5_wrap_ui(kreport_LIB_SRCS wrtembed/detailgroupsectiondialog.ui wrtembed/sectioneditor.ui ) ecm_create_qm_loader(kreport_LIB_SRCS kreport_qt) add_library(KReport SHARED ${kreport_LIB_SRCS}) generate_export_header(KReport) #qt5_use_modules(KReport Widgets Xml PrintSupport) set(kreport_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/kreport ${CMAKE_CURRENT_BINARY_DIR}/kreport/common ${CMAKE_CURRENT_BINARY_DIR}/kreport/wrtembed ${CMAKE_CURRENT_BINARY_DIR}/kreport/renderer ${CMAKE_CURRENT_BINARY_DIR}/kreport/renderer/scripting ${CMAKE_CURRENT_SOURCE_DIR}/common ${CMAKE_CURRENT_SOURCE_DIR}/wrtembed ${CMAKE_CURRENT_SOURCE_DIR}/renderer ${CMAKE_CURRENT_SOURCE_DIR}/renderer/scripting ) target_include_directories(KReport PUBLIC "$" INTERFACE "$" PRIVATE common renderer renderer/scripting wrtembed ) target_link_libraries(KReport PUBLIC Qt5::PrintSupport Qt5::Xml KF5::CoreAddons KProperty + Qt5::Network PRIVATE KF5::WidgetsAddons KF5::ConfigGui # KStandardShortcut ${SCRIPTING_LIBS} #KF5::KIOCore #KF5::KIOFileWidgets #KF5::KIOWidgets #KF5::KIONTLM ) set_target_properties(KReport PROPERTIES VERSION 1.0 SOVERSION 1.0.0 EXPORT_NAME KReport ) ecm_setup_version(${KREPORT_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") 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 LIB_NAME KReport DEPS "widgets" FILENAME_VAR PRI_FILENAME INCLUDE_INSTALL_DIR ${INCLUDE_INSTALL_DIR}/KReport ) install(FILES ${PRI_FILENAME} DESTINATION ${ECM_MKSPECS_INSTALL_DIR}) kcoreaddons_desktop_to_json(KReport items/check/check.desktop) kcoreaddons_desktop_to_json(KReport items/field/field.desktop) kcoreaddons_desktop_to_json(KReport items/image/image.desktop) kcoreaddons_desktop_to_json(KReport items/label/label.desktop) kcoreaddons_desktop_to_json(KReport items/text/text.desktop) #TODO #install(FILES koreport_itemplugin.desktop DESTINATION ${SERVICETYPES_INSTALL_DIR}) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/kreport_version.h" DESTINATION "${INCLUDE_INSTALL_DIR}" COMPONENT Devel) ecm_generate_headers(kreport_FORWARDING_HEADERS REQUIRED_HEADERS kreport_HEADERS ORIGINAL CAMELCASE PREFIX kreport RELATIVE common HEADER_NAMES KReportPageFormat KoReportData KoReportItemBase KoReportItemLine KReportPluginMetaData KoReportPluginManager KoReportPluginInterface KReportUnit krsize krpos krreportdata krsectiondata reportpageoptions renderobjects KoReportASyncItemBase ) ecm_generate_headers(kreport_FORWARDING_HEADERS REQUIRED_HEADERS kreport_HEADERS ORIGINAL CAMELCASE PREFIX kreport RELATIVE renderer HEADER_NAMES KoReportPage KoReportRendererBase KoReportPreRenderer KReportView ) ecm_generate_headers(kreport_FORWARDING_HEADERS REQUIRED_HEADERS kreport_HEADERS ORIGINAL CAMELCASE PREFIX kreport RELATIVE renderer/scripting HEADER_NAMES krscripthandler krscriptdraw krscriptconstants ) ecm_generate_headers(kreport_FORWARDING_HEADERS REQUIRED_HEADERS kreport_HEADERS ORIGINAL CAMELCASE PREFIX kreport RELATIVE wrtembed HEADER_NAMES KReportZoomMode reportsectiondetail reportsection KReportDpi KReportZoomHandler KoReportDesignerItemBase reportsectiondetailgroup KoReportDesignerItemRectBase KoReportDesigner ) install( FILES ${kreport_HEADERS} DESTINATION ${INCLUDE_INSTALL_DIR}/KReport/kreport COMPONENT Devel ) install( FILES ${kreport_FORWARDING_HEADERS} ${PROJECT_BINARY_DIR}/src/kreport_export.h ${PROJECT_BINARY_DIR}/src/config-kreport.h DESTINATION ${INCLUDE_INSTALL_DIR}/KReport COMPONENT Devel ) diff --git a/src/common/KoReportData.cpp b/src/common/KoReportData.cpp index 377b75a9..e0ff4367 100644 --- a/src/common/KoReportData.cpp +++ b/src/common/KoReportData.cpp @@ -1,81 +1,80 @@ /* 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 . */ #include "KoReportData.h" #include #include KoReportData::~KoReportData() { } KoReportData::SortedField::SortedField() : order(Qt::AscendingOrder) { } QStringList KoReportData::fieldKeys() const { return fieldNames(); } QString KoReportData::sourceName() const { return QString(); } void KoReportData::setSorting(const QList &sorting) { Q_UNUSED(sorting); } void KoReportData::addExpression(const QString &field, const QVariant &value, char relation) { Q_UNUSED(field); Q_UNUSED(value); Q_UNUSED(relation); } #ifdef KREPORT_SCRIPTING QStringList KoReportData::scriptList() const { return QStringList(); } QString KoReportData::scriptCode(const QString &script) const { Q_UNUSED(script); return QString(); } #endif QStringList KoReportData::dataSources() const { return QStringList(); } QStringList KoReportData::dataSourceNames() const { - qDebug() << "Returning data sources"; return dataSources(); } KoReportData* KoReportData::data(const QString &source) { Q_UNUSED(source); return 0; } diff --git a/src/common/renderobjects.cpp b/src/common/renderobjects.cpp index ab71af63..0036a721 100644 --- a/src/common/renderobjects.cpp +++ b/src/common/renderobjects.cpp @@ -1,510 +1,513 @@ /* 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 "renderobjects.h" #include "kreport_debug.h" // // ORODocument // ORODocument::ORODocument(const QString & pTitle) : m_title(pTitle) { } ORODocument::~ORODocument() { qDeleteAll(m_pages); m_pages.clear(); qDeleteAll(m_sections); m_sections.clear(); } void ORODocument::setTitle(const QString & pTitle) { m_title = pTitle; } OROPage* ORODocument::page(int pnum) { - return m_pages.at(pnum); + if (pnum >= 0 && pnum < m_pages.count()) { + return m_pages.at(pnum); + } + return nullptr; } void ORODocument::addPage(OROPage* p) { if (p == 0) return; // check that this page is not already in another document p->m_document = this; m_pages.append(p); } OROSection* ORODocument::section(int pnum) { return m_sections.at(pnum); } void ORODocument::addSection(OROSection* s) { if (s == 0) return; // check that this page is not already in another document s->m_document = this; m_sections.append(s); } void ORODocument::setPageOptions(const ReportPageOptions & options) { m_pageOptions = options; } void ORODocument::notifyChange(int pageNo) { emit(updated(pageNo)); } // // OROPage // OROPage::OROPage(ORODocument * pDocument) : m_document(pDocument) { } OROPage::~OROPage() { if (m_document) { m_document->m_pages.removeOne(this); m_document = 0; } qDeleteAll(m_primitives); m_primitives.clear(); } int OROPage::page() const { if (m_document) { for (int i = 0; i < m_document->m_pages.size(); i++) { if (m_document->m_pages.at(i) == this) return i; } } return -1; } OROPrimitive* OROPage::primitive(int idx) { return m_primitives.at(idx); } void OROPage::addPrimitive(OROPrimitive* p, bool atBeginning, bool notify) { //kreportDebug() << "Adding primitive" << p->type() << "to page" << page(); if (p == 0) return; // check that this primitve is not already in another page p->m_page = this; if (atBeginning) { m_primitives.prepend(p); } else { m_primitives.append(p); } if (notify) { document()->notifyChange(page()); } } // // OROSection // OROSection::OROSection(ORODocument * pDocument) : m_document(pDocument) { m_height = 0; m_backgroundColor = Qt::white; } OROSection::~OROSection() { if (m_document) { m_document->m_sections.removeOne(this); m_document = 0; } qDeleteAll(m_primitives); m_primitives.clear(); } OROPrimitive* OROSection::primitive(int idx) { return m_primitives.at(idx); } void OROSection::addPrimitive(OROPrimitive* p) { if (p == 0) return; m_primitives.append(p); } void OROSection::setHeight(int h) { m_height = h; } int OROSection::height() { return m_height; } void OROSection::setBackgroundColor(const QColor &c) { m_backgroundColor = c; } QColor OROSection::backgroundColor() { return m_backgroundColor; } void OROSection::sortPrimatives(Sort s) { if (s == SortX) { qSort(m_primitives.begin(), m_primitives.end(), xLessThan); } } bool OROSection::xLessThan(OROPrimitive* s1, OROPrimitive* s2) { return s1->position().x() < s2->position().x(); } // // OROPrimitive // OROPrimitive::OROPrimitive(int pType) : m_type(pType) { m_page = 0; } OROPrimitive::~OROPrimitive() { if (m_page) { m_page->m_primitives.removeAt(m_page->m_primitives.indexOf(this)); m_page = 0; } } void OROPrimitive::setPosition(const QPointF & p) { m_position = p; } void OROPrimitive::setSize(const QSizeF & s) { m_size = s; } // // OROTextBox // const int OROTextBox::TextBox = 1; OROTextBox::OROTextBox() : OROPrimitive(OROTextBox::TextBox) { m_flags = 0; m_lineStyle.lineColor = Qt::black; m_lineStyle.weight = 0; m_lineStyle.style = Qt::NoPen; m_requiresPostProcessing = false; m_wordWrap = false; m_canGrow = false; } OROTextBox::~OROTextBox() { } void OROTextBox::setText(const QString & s) { m_text = s; } void OROTextBox::setTextStyle(const KRTextStyleData & ts) { m_textStyle = ts; } void OROTextBox::setLineStyle(const KRLineStyleData & ls) { m_lineStyle = ls; } void OROTextBox::setFont(const QFont & f) { m_textStyle.font = f; } void OROTextBox::setFlags(int f) { m_flags = f; } OROPrimitive* OROTextBox::clone() { OROTextBox *theClone = new OROTextBox(); theClone->setSize(m_size); theClone->setPosition(m_position); theClone->setText(m_text); theClone->setTextStyle(m_textStyle); theClone->setLineStyle(m_lineStyle); theClone->setFlags(m_alignment); return theClone; } // // OROLine // const int OROLine::Line = 2; OROLine::OROLine() : OROPrimitive(OROLine::Line) { } OROLine::~OROLine() { } void OROLine::setStartPoint(const QPointF & p) { setPosition(p); } void OROLine::setEndPoint(const QPointF & p) { m_endPoint = p; } void OROLine::setLineStyle(const KRLineStyleData& ls) { m_lineStyle = ls; } OROPrimitive* OROLine::clone() { OROLine *theClone = new OROLine(); theClone->setStartPoint(m_position); theClone->setEndPoint(m_endPoint); theClone->setLineStyle(m_lineStyle); return theClone; } // // OROImage // const int OROImage::Image = 3; OROImage::OROImage() : OROPrimitive(OROImage::Image) { m_scaled = false; m_transformFlags = Qt::FastTransformation; m_aspectFlags = Qt::IgnoreAspectRatio; } OROImage::~OROImage() { } void OROImage::setImage(const QImage & img) { m_image = img; } void OROImage::setScaled(bool b) { m_scaled = b; } void OROImage::setTransformationMode(int tm) { m_transformFlags = tm; } void OROImage::setAspectRatioMode(int arm) { m_aspectFlags = arm; } OROPrimitive* OROImage::clone() { OROImage *theClone = new OROImage(); theClone->setSize(m_size); theClone->setPosition(m_position); theClone->setImage(m_image); theClone->setScaled(m_scaled); theClone->setTransformationMode(m_transformFlags); theClone->setAspectRatioMode(m_aspectFlags); return theClone; } // // OROPicture // const int OROPicture::Picture = 6; OROPicture::OROPicture() : OROPrimitive(OROPicture::Picture) { } OROPicture::~OROPicture() { } OROPrimitive* OROPicture::clone() { OROPicture *theClone = new OROPicture(); theClone->setSize(m_size); theClone->setPosition(m_position); theClone->setPicture(m_picture); return theClone; } // // ORORect // const int ORORect::Rect = 4; ORORect::ORORect() : OROPrimitive(ORORect::Rect) { } ORORect::~ORORect() { } void ORORect::setRect(const QRectF & r) { setPosition(r.topLeft()); setSize(r.size()); } void ORORect::setPen(const QPen & p) { m_pen = p; } void ORORect::setBrush(const QBrush & b) { m_brush = b; } OROPrimitive* ORORect::clone() { ORORect *theClone = new ORORect(); theClone->setSize(m_size); theClone->setPosition(m_position); theClone->setPen(m_pen); theClone->setBrush(m_brush); return theClone; } // // OROEllipse // const int OROEllipse::Ellipse = 5; OROEllipse::OROEllipse() : OROPrimitive(OROEllipse::Ellipse) { } OROEllipse::~OROEllipse() { } void OROEllipse::setRect(const QRectF & r) { setPosition(r.topLeft()); setSize(r.size()); } void OROEllipse::setPen(const QPen & p) { m_pen = p; } void OROEllipse::setBrush(const QBrush & b) { m_brush = b; } OROPrimitive* OROEllipse::clone() { OROEllipse *theClone = new OROEllipse(); theClone->setSize(m_size); theClone->setPosition(m_position); theClone->setPen(m_pen); theClone->setBrush(m_brush); return theClone; } const int OROCheck::Check = 7; OROCheck::OROCheck() : OROPrimitive(OROCheck::Check) { } OROCheck::~OROCheck() { } OROPrimitive* OROCheck::clone() { OROCheck *theClone = new OROCheck(); theClone->setSize(m_size); theClone->setPosition(m_position); theClone->setLineStyle(m_lineStyle); theClone->setForegroundColor(m_fgColor); theClone->setValue(m_value); return theClone; } diff --git a/src/renderer/KoReportPreRenderer.cpp b/src/renderer/KoReportPreRenderer.cpp index e1292a85..d1fe2c4d 100644 --- a/src/renderer/KoReportPreRenderer.cpp +++ b/src/renderer/KoReportPreRenderer.cpp @@ -1,659 +1,662 @@ /* 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 "KoReportPreRenderer.h" #include "KoReportPreRenderer_p.h" #include "KoReportASyncItemManager.h" #include "KReportOneRecordData.h" #include "common/renderobjects.h" #include "common/KoReportData.h" #include "common/KoReportItemBase.h" #include "common/krreportdata.h" #include "common/krdetailsectiondata.h" #include "common/labelsizeinfo.h" #include "common/KReportPageFormat.h" #ifdef KREPORT_SCRIPTING #include "scripting/krscripthandler.h" #endif #include #include #include #include "kreport_debug.h" KoReportPreRendererPrivate::KoReportPreRendererPrivate() { m_valid = false; m_reportData = 0; m_document = 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 KReportOneRecordData(); m_kodata = m_oneRecord; asyncManager = new KoReportASyncItemManager(this); connect(asyncManager, SIGNAL(finished()), this, SLOT(asyncItemsFinished())); } KoReportPreRendererPrivate::~KoReportPreRendererPrivate() { delete m_reportData; delete m_oneRecord; m_postProcText.clear(); } void KoReportPreRendererPrivate::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_reportData->m_pageHeaderFirst) renderSection(*(m_reportData->m_pageHeaderFirst)); else if (lastPage == true && m_reportData->m_pageHeaderLast) renderSection(*(m_reportData->m_pageHeaderLast)); else if ((m_pageCounter % 2) == 1 && m_reportData->m_pageHeaderOdd) renderSection(*(m_reportData->m_pageHeaderOdd)); else if ((m_pageCounter % 2) == 0 && m_reportData->m_pageHeaderAny) renderSection(*(m_reportData->m_pageHeaderAny)); else if (m_reportData->m_pageHeaderAny) renderSection(*(m_reportData->m_pageHeaderAny)); } qreal KoReportPreRendererPrivate::finishCurPageSize(bool lastPage) { qreal retval = 0.0; if (lastPage && m_reportData->m_pageFooterLast) retval = renderSectionSize(* (m_reportData->m_pageFooterLast)); else if (m_pageCounter == 1 && m_reportData->m_pageFooterFirst) retval = renderSectionSize(* (m_reportData->m_pageFooterFirst)); else if ((m_pageCounter % 2) == 1 && m_reportData->m_pageFooterOdd) retval = renderSectionSize(* (m_reportData->m_pageFooterOdd)); else if ((m_pageCounter % 2) == 0 && m_reportData->m_pageFooterEven) retval = renderSectionSize(* (m_reportData->m_pageFooterEven)); else if (m_reportData->m_pageFooterAny) retval = renderSectionSize(* (m_reportData->m_pageFooterAny)); //kreportDebug() << retval; return retval; } qreal KoReportPreRendererPrivate::finishCurPage(bool lastPage) { qreal offset = m_maxHeight - m_bottomMargin; qreal retval = 0.0; //kreportDebug() << offset; if (lastPage && m_reportData->m_pageFooterLast) { //kreportDebug() << "Last Footer"; m_yOffset = offset - renderSectionSize(* (m_reportData->m_pageFooterLast)); retval = renderSection(* (m_reportData->m_pageFooterLast)); } else if (m_pageCounter == 1 && m_reportData->m_pageFooterFirst) { //kreportDebug() << "First Footer"; m_yOffset = offset - renderSectionSize(* (m_reportData->m_pageFooterFirst)); retval = renderSection(* (m_reportData->m_pageFooterFirst)); } else if ((m_pageCounter % 2) == 1 && m_reportData->m_pageFooterOdd) { //kreportDebug() << "Odd Footer"; m_yOffset = offset - renderSectionSize(* (m_reportData->m_pageFooterOdd)); retval = renderSection(* (m_reportData->m_pageFooterOdd)); } else if ((m_pageCounter % 2) == 0 && m_reportData->m_pageFooterEven) { //kreportDebug() << "Even Footer"; m_yOffset = offset - renderSectionSize(* (m_reportData->m_pageFooterEven)); retval = renderSection(* (m_reportData->m_pageFooterEven)); } else if (m_reportData->m_pageFooterAny) { //kreportDebug() << "Any Footer"; m_yOffset = offset - renderSectionSize(* (m_reportData->m_pageFooterAny)); retval = renderSection(* (m_reportData->m_pageFooterAny)); } return retval; } void KoReportPreRendererPrivate::renderDetailSection(KRDetailSectionData *detailData) { if (detailData->m_detailSection) { if (m_kodata/* && !curs->eof()*/) { QStringList keys; QStringList keyValues; QList shownGroups; ORDetailGroupSectionData * grp = 0; bool status = m_kodata->moveFirst(); m_recordCount = m_kodata->recordCount(); //kreportDebug() << "Record Count:" << m_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) { long l = m_kodata->at(); //kreportDebug() << "At:" << l << "Y:" << m_yOffset << "Max Height:" << m_maxHeight; if (renderSectionSize(*(detailData->m_detailSection)) + finishCurPageSize((l + 1 == m_recordCount)) + m_bottomMargin + m_yOffset >= m_maxHeight) { //kreportDebug() << "Next section is too big for this page"; if (l > 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 (ORDetailGroupSectionData::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 (KRDetailSectionData::BreakAtEnd == detailData->m_pageBreak) createNewPage(); } } qreal KoReportPreRendererPrivate::renderSectionSize(const KRSectionData & sectionData) { QScreen *srn = QApplication::screens().at(0); qreal intHeight = POINT_TO_INCH(sectionData.height()) * srn->logicalDotsPerInchX(); int itemHeight = 0; if (sectionData.objects().count() == 0) return intHeight; QList objects = sectionData.objects(); foreach(KoReportItemBase *ob, objects) { QPointF offset(m_leftMargin, m_yOffset); QVariant itemData = m_kodata->value(ob->itemDataSource()); //ASync objects cannot alter the section height KoReportASyncItemBase *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 KoReportPreRendererPrivate::renderSection(const KRSectionData & sectionData) { QScreen *srn = QApplication::screens().at(0); qreal sectionHeight = POINT_TO_INCH(sectionData.height()) * srn->logicalDotsPerInchX(); 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()->pageOptions().widthPx() - m_page->document()->pageOptions().getMarginRight() - m_leftMargin; bg->setRect(QRectF(m_leftMargin, m_yOffset, w, sectionHeight)); m_page->addPrimitive(bg, true); QList objects = sectionData.objects(); foreach(KoReportItemBase *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 { KoReportASyncItemBase *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->primitives(); ++i) { OROPrimitive *prim = m_page->primitive(i); if (prim->type() == OROTextBox::TextBox) { OROTextBox *text = static_cast(prim); if (text->requiresPostProcessing()) { m_postProcText.append(text); } } } m_yOffset += sectionHeight; return sectionHeight; } #ifdef KREPORT_SCRIPTING void KoReportPreRendererPrivate::initEngine() { m_scriptHandler = new KRScriptHandler(m_kodata, m_reportData); 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(KRSectionData*,OROPage*,QPointF)), m_scriptHandler, SLOT(slotEnteredSection(KRSectionData*,OROPage*,QPointF))); } #endif void KoReportPreRendererPrivate::asyncItemsFinished() { //kreportDebug() << "Finished rendering async items"; delete asyncManager; } //===========================KoReportPreRenderer=============================== KoReportPreRenderer::KoReportPreRenderer(const QDomElement & document) : d(new KoReportPreRendererPrivate()) { setDocument(document); } KoReportPreRenderer::~KoReportPreRenderer() { delete d; } void KoReportPreRenderer::setName(const QString &n) { d->m_reportData->setName(n); } ORODocument* KoReportPreRenderer::generate() { QScreen *srn = QApplication::screens().at(0); int dpiX = srn->logicalDotsPerInchX(); int dpiY = srn->logicalDotsPerInchY(); if (d == 0 || !d->m_valid || d->m_reportData == 0 || d->m_kodata == 0) return 0; // Do this check now so we don't have to undo a lot of work later if it fails LabelSizeInfo label; if (d->m_reportData->page.getPageSize() == QLatin1String("Labels")) { label = LabelSizeInfo::find(d->m_reportData->page.getLabelType()); if (label.isNull()) return 0; } //kreportDebug() << "Creating Document"; d->m_document = new ORODocument(d->m_reportData->m_title); d->m_pageCounter = 0; d->m_yOffset = 0.0; //kreportDebug() << "Calculating Margins"; if (!label.isNull()) { if (d->m_reportData->page.isPortrait()) { d->m_topMargin = (label.startY() / 100.0); d->m_bottomMargin = 0; d->m_rightMargin = 0; d->m_leftMargin = (label.startX() / 100.0); } else { d->m_topMargin = (label.startX() / 100.0); d->m_bottomMargin = 0; d->m_rightMargin = 0; d->m_leftMargin = (label.startY() / 100.0); } } else { d->m_topMargin = d->m_reportData->page.getMarginTop(); d->m_bottomMargin = d->m_reportData->page.getMarginBottom(); d->m_rightMargin = d->m_reportData->page.getMarginRight(); d->m_leftMargin = d->m_reportData->page.getMarginLeft(); //kreportDebug() << "Margins:" << d->m_topMargin << d->m_bottomMargin << d->m_rightMargin << d->m_leftMargin; } //kreportDebug() << "Calculating Page Size"; ReportPageOptions rpo(d->m_reportData->page); // This should reflect the information of the report page size if (d->m_reportData->page.getPageSize() == QLatin1String("Custom")) { d->m_maxWidth = d->m_reportData->page.getCustomWidth(); d->m_maxHeight = d->m_reportData->page.getCustomHeight(); } else { if (!label.isNull()) { d->m_maxWidth = label.width(); d->m_maxHeight = label.height(); rpo.setPageSize(label.paper()); } else { // lookup the correct size information for the specified size paper d->m_maxWidth = KReportPageFormat::width(KReportPageFormat::formatFromString(d->m_reportData->page.getPageSize()), KReportPageFormat::Portrait); d->m_maxHeight = KReportPageFormat::height(KReportPageFormat::formatFromString(d->m_reportData->page.getPageSize()), KReportPageFormat::Portrait); KReportUnit pageUnit(KReportUnit::Millimeter); d->m_maxWidth = KReportUnit::toInch(pageUnit.fromUserValue(d->m_maxWidth)) * dpiX; d->m_maxHeight = KReportUnit::toInch(pageUnit.fromUserValue(d->m_maxHeight)) * dpiY; } } if (!d->m_reportData->page.isPortrait()) { qreal tmp = d->m_maxWidth; d->m_maxWidth = d->m_maxHeight; d->m_maxHeight = tmp; } //kreportDebug() << "Page Size:" << d->m_maxWidth << d->m_maxHeight; d->m_document->setPageOptions(rpo); d->m_kodata->setSorting(d->m_reportData->m_detailSection->m_sortedFields); d->m_kodata->open(); #ifdef KREPORT_SCRIPTING d->initEngine(); //Loop through all abjects that have been registered, and register them with the script handler if (d->m_scriptHandler) { QMapIterator i(d->m_scriptObjects); while (i.hasNext()) { i.next(); d->m_scriptHandler->registerScriptObject(i.value(), i.key()); //! @todo This is a hack if (i.key() == QLatin1String("field")) QObject::connect(d->m_scriptHandler, SIGNAL(groupChanged(QString)), i.value(), SLOT(setWhere(QString))); } - //execute the script - d->m_scriptHandler->trigger(); + //execute the script, if it fails, abort and return the empty document + if (!d->m_scriptHandler->trigger()) { + d->m_scriptHandler->displayErrors(); + return d->m_document; + } } #endif d->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 = d->m_leftMargin; d->m_yOffset = d->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 (!d->m_reportData->page.isPortrait()) { 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(); } KRDetailSectionData * detailData = d->m_reportData->m_detailSection; if (detailData->m_detailSection) { KoReportData *mydata = d->m_kodata; if (mydata && mydata->recordCount() > 0) { /* && !((query = orqThis->getQuery())->eof()))*/ mydata->moveFirst(); int row = 0; int col = 0; do { tmp = d->m_yOffset; // store the value as renderSection changes it d->renderSection(*(detailData->m_detailSection)); d->m_yOffset = tmp; // restore the value that renderSection modified col++; d->m_leftMargin += w + wg; if (col >= numCols) { d->m_leftMargin = margin; // reset back to original value col = 0; row++; d->m_yOffset += h + hg; if (row >= numRows) { d->m_yOffset = d->m_topMargin; row = 0; d->createNewPage(); } } } while (mydata->moveNext()); } } } else { // Normal Print Run if (d->m_reportData->m_reportHeader) { d->renderSection(*(d->m_reportData->m_reportHeader)); } if (d->m_reportData->m_detailSection) { d->renderDetailSection(d->m_reportData->m_detailSection); } if (d->m_reportData->m_reportFooter) { if (d->renderSectionSize(*(d->m_reportData->m_reportFooter)) + d->finishCurPageSize(true) + d->m_bottomMargin + d->m_yOffset >= d->m_maxHeight) { d->createNewPage(); } d->renderSection(*(d->m_reportData->m_reportFooter)); } } d->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 d->m_scriptHandler->setPageTotal(d->m_document->pages()); for (int i = 0; i < d->m_postProcText.size(); i++) { OROTextBox * tb = d->m_postProcText.at(i); d->m_scriptHandler->setPageNumber(tb->page()->page() + 1); tb->setText(d->m_scriptHandler->evaluate(tb->text()).toString()); } #endif d->asyncManager->startRendering(); #ifdef KREPORT_SCRIPTING d->m_scriptHandler->displayErrors(); #endif d->m_kodata->close(); #ifdef KREPORT_SCRIPTING delete d->m_scriptHandler; #endif //! @todo check ownership delete d->m_kodata; d->m_postProcText.clear(); return d->m_document; } void KoReportPreRenderer::setSourceData(KoReportData *data) { if (data) { d->m_kodata = data; } } bool KoReportPreRenderer::setDocument(const QDomElement &document) { delete d->m_reportData; d->m_valid = false; if (document.tagName() != QLatin1String("report:content")) { kreportWarning() << "report schema is invalid"; return false; } d->m_reportData = new KoReportReportData(document); d->m_valid = d->m_reportData->isValid(); return isValid(); } bool KoReportPreRenderer::isValid() const { if (d && d->m_valid) return true; return false; } #ifdef KREPORT_SCRIPTING void KoReportPreRenderer::registerScriptObject(QObject* obj, const QString& name) { //kreportDebug() << name; d->m_scriptObjects[name] = obj; } #endif const KoReportReportData* KoReportPreRenderer::reportData() const { return d->m_reportData; } diff --git a/src/renderer/KoReportScreenRenderer.cpp b/src/renderer/KoReportScreenRenderer.cpp index 6672a814..ac0c1f83 100644 --- a/src/renderer/KoReportScreenRenderer.cpp +++ b/src/renderer/KoReportScreenRenderer.cpp @@ -1,217 +1,221 @@ /* 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 "KoReportScreenRenderer.h" #include "common/renderobjects.h" #include "common/KReportPageFormat.h" #include "common/KReportUnit.h" #include "kreport_debug.h" KoReportScreenRenderer::KoReportScreenRenderer() { } KoReportScreenRenderer::~KoReportScreenRenderer() { } //void KRScreenRender::setPainter(QPainter * pPainter) //{ // context.painter = pPainter; //} bool KoReportScreenRenderer::render(const KoReportRendererContext& context, ORODocument *document, int page) { if (!document) return false; if (!context.painter) return false; OROPage *p = document->page(page); + if (p == nullptr) { + return false; + } + // Render Page Objects for (int i = 0; i < p->primitives(); i++) { OROPrimitive *prim = p->primitive(i); if (prim->type() == OROTextBox::TextBox) { 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 context.painter->setBackgroundMode(Qt::TransparentMode); QColor bg = tb->textStyle().backgroundColor; bg.setAlphaF(0.01 * tb->textStyle().backgroundOpacity); context.painter->fillRect(rc, bg); //Text context.painter->setFont(tb->textStyle().font); context.painter->setPen(tb->textStyle().foregroundColor); context.painter->drawText(rc.adjusted(2, 2, 0, 0), tb->flags(), tb->text()); //outer line context.painter->setPen(QPen(tb->lineStyle().lineColor, tb->lineStyle().weight, tb->lineStyle().style)); context.painter->drawRect(rc); //Reset back to defaults for next element context.painter->restore(); } else if (prim->type() == OROLine::Line) { OROLine * ln = dynamic_cast(prim); QPointF s = ln->startPoint(); QPointF e = ln->endPoint(); //QPen pen ( _painter->pen() ); QPen pen(ln->lineStyle().lineColor, ln->lineStyle().weight, ln->lineStyle().style); 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 (prim->type() == ORORect::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 (prim->type() == OROEllipse::Ellipse) { 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 (prim->type() == OROImage::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->scaled()) 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 (prim->type() == OROPicture::Picture) { 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->save(); context.painter->drawPicture(rc.topLeft(), *(im->picture())); context.painter->restore(); } else if (prim->type() == OROCheck::Check) { OROCheck * 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().style == Qt::NoPen || chk->lineStyle().weight <= 0) { context.painter->setPen(QPen(Qt::lightGray)); } else { context.painter->setPen(QPen(chk->lineStyle().lineColor, chk->lineStyle().weight, chk->lineStyle().style)); } qreal ox = sz.width() / 5; qreal oy = sz.height() / 5; //Checkbox Style if (chk->checkType() == QLatin1String("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() == QLatin1String("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(); } else { kreportWarning() << "unrecognized primitive type"; } } return true; } diff --git a/src/renderer/scripting/krscripthandler.cpp b/src/renderer/scripting/krscripthandler.cpp index 797c5ca6..90998d7f 100644 --- a/src/renderer/scripting/krscripthandler.cpp +++ b/src/renderer/scripting/krscripthandler.cpp @@ -1,180 +1,181 @@ /* This file is part of the KDE project * Copyright (C) 2007-2008 by Adam Pigg * Copyright (C) 2012 JarosÅ‚aw Staniek * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include "krscripthandler.h" #include "krscriptsection.h" #include "krscriptdebug.h" #include "krscriptreport.h" #include "krscriptdraw.h" #include "krscriptconstants.h" - #include "krsectiondata.h" #include "KoReportItemBase.h" #include "krreportdata.h" #include "krdetailsectiondata.h" #include "renderobjects.h" +#include "kreport_debug.h" #include - -#include "kreport_debug.h" -#include -#include +#include +#include KRScriptHandler::KRScriptHandler(const KoReportData* kodata, KoReportReportData* d) { m_reportData = d; m_koreportData = kodata; m_engine = 0; m_constants = 0; m_debug = 0; m_draw = 0; // Create the script engine instance . m_engine = new QJSEngine(this); //Add constants object m_constants = new KRScriptConstants(); registerScriptObject(m_constants, QLatin1String("constants")); //A simple debug function to allow printing from functions m_debug = new KRScriptDebug(); registerScriptObject(m_debug, QLatin1String("debug")); //A simple drawing object m_draw = new KRScriptDraw(); registerScriptObject(m_draw, QLatin1String("draw")); //Add a general report object m_report = new Scripting::Report(m_reportData); QJSValue r = registerScriptObject(m_report, m_reportData->name()); //Add the sections QList secs = m_reportData->sections(); foreach(KRSectionData *sec, secs) { m_sectionMap[sec] = new Scripting::Section(sec); m_sectionMap[sec]->setParent(m_report); m_sectionMap[sec]->setObjectName(sec->name().replace(QLatin1Char('-'), QLatin1Char('_')) .remove(QLatin1String("report:"))); QJSValue s = m_engine->newQObject(m_sectionMap[sec]); r.setProperty(m_sectionMap[sec]->objectName(), s); kreportDebug() << "Added" << m_sectionMap[sec]->objectName() << "to report" << m_reportData->name(); } kreportDebug() << "Report name is" << m_reportData->name(); } -void KRScriptHandler::trigger() +bool KRScriptHandler::trigger() { - //kreportDebug() << m_engine->code(); QString code = m_koreportData->scriptCode(m_reportData->script()); - qDebug() << code; - m_scriptValue = m_engine->evaluate(code); + kreportDebug() << code; + + if (code.isEmpty()) { + return true; + } + + m_scriptValue = m_engine->evaluate(code, m_reportData->script()); if (m_scriptValue.isError()) { - QMessageBox::warning(0, tr("Script Error"), m_scriptValue.toString()); + return false; }/*TODO else { kreportDebug() << "Function Names:" << m_engine->functionNames(); }*/ m_report->eventOnOpen(); + return true; } KRScriptHandler::~KRScriptHandler() { delete m_report; - delete m_constants; - delete m_debug; - delete m_draw; delete m_engine; } void KRScriptHandler::newPage() { if (m_report) { m_report->eventOnNewPage(); } } void KRScriptHandler::slotEnteredGroup(const QString &key, const QVariant &value) { //kreportDebug() << key << value; m_groups[key] = value; emit(groupChanged(where())); } void KRScriptHandler::slotExitedGroup(const QString &key, const QVariant &value) { Q_UNUSED(value); //kreportDebug() << key << value; m_groups.remove(key); emit(groupChanged(where())); } void KRScriptHandler::slotEnteredSection(KRSectionData *section, OROPage* cp, QPointF off) { if (cp) m_draw->setPage(cp); m_draw->setOffset(off); Scripting::Section *ss = m_sectionMap[section]; if (ss) { ss->eventOnRender(); } } QVariant KRScriptHandler::evaluate(const QString &code) { if (!m_scriptValue.isError()) { QJSValue result = m_engine->evaluate(code); - return result.toVariant(); - } else { - return QVariant(); + if (!result.isError()) { + return result.toVariant(); + } else { + QMessageBox::warning(0, tr("Script Error"), m_scriptValue.toString()); + } } + return QVariant(); } void KRScriptHandler::displayErrors() { if (m_scriptValue.isError()) { QMessageBox::warning(0, tr("Script Error"), m_scriptValue.toString()); } } QString KRScriptHandler::where() { QString w; QMap::const_iterator i = m_groups.constBegin(); while (i != m_groups.constEnd()) { w += QLatin1Char('(') + i.key() + QLatin1String(" = '") + i.value().toString() + QLatin1String("') AND "); ++i; } w.chop(4); //kreportDebug() << w; return w; } QJSValue KRScriptHandler::registerScriptObject(QObject* obj, const QString& name) { QJSValue val; - if (m_engine) { - val = m_engine->newQObject(obj); - m_engine->globalObject().setProperty(name, val); - } + val = m_engine->newQObject(obj); + m_engine->globalObject().setProperty(name, val); return val; } diff --git a/src/renderer/scripting/krscripthandler.h b/src/renderer/scripting/krscripthandler.h index 5124be45..ce8b9745 100644 --- a/src/renderer/scripting/krscripthandler.h +++ b/src/renderer/scripting/krscripthandler.h @@ -1,94 +1,94 @@ /* 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 . */ #ifndef KRSCRIPTHANDLER_H #define KRSCRIPTHANDLER_H #include "config-kreport.h" class KoReportReportData; class OROPage; #ifdef KREPORT_SCRIPTING #include "krscriptconstants.h" #include "KoReportData.h" #include class KRScriptDebug; class KRScriptDraw; class KRSectionData; class QJSEngine; namespace Scripting { class Report; class Section; } class KRScriptHandler : public QObject { Q_OBJECT public: KRScriptHandler(const KoReportData *, KoReportReportData*); ~KRScriptHandler(); QVariant evaluate(const QString&); void displayErrors(); QJSValue registerScriptObject(QObject*, const QString&); - void trigger(); + bool trigger(); public Q_SLOTS: void slotEnteredSection(KRSectionData*, OROPage*, QPointF); void slotEnteredGroup(const QString&, const QVariant&); void slotExitedGroup(const QString&, const QVariant&); void setPageNumber(int p) { m_constants->setPageNumber(p); } void setPageTotal(int t) { m_constants->setPageTotal(t); } void newPage(); Q_SIGNALS: void groupChanged(const QString& whereCondition); private: KRScriptConstants *m_constants; KRScriptDebug *m_debug; KRScriptDraw *m_draw; Scripting::Report *m_report; const KoReportData *m_koreportData; QString m_source; KoReportReportData *m_reportData; QJSEngine* m_engine; QJSValue m_scriptValue; QMap m_groups; QMap m_sectionMap; QString where(); }; #else // !KREPORT_SCRIPTING #define KRScriptHandler void #endif #endif diff --git a/src/renderer/scripting/krscriptreport.cpp b/src/renderer/scripting/krscriptreport.cpp index b71a3bb2..20fb966b 100644 --- a/src/renderer/scripting/krscriptreport.cpp +++ b/src/renderer/scripting/krscriptreport.cpp @@ -1,118 +1,118 @@ /* 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 "krscriptreport.h" #include "krreportdata.h" #include "KoReportItemBase.h" #include "KoReportPluginManager.h" #include "KoReportPluginInterface.h" #include "krscriptline.h" #include "krscriptsection.h" #include "KoReportItemLine.h" #include "kreport_debug.h" namespace Scripting { Report::Report(KoReportReportData *r) { m_reportData = r; m_scriptObject = 0; } Report::~Report() { } QString Report::title() { return m_reportData->m_title; } QString Report::name() { return m_reportData->name(); } QString Report::recordSource() { return m_reportData->query(); } QObject* Report::objectByName(const QString &n) { QListobs = m_reportData->objects(); foreach(KoReportItemBase *o, obs) { if (o->entityName() == n) { if (o->typeName() == QLatin1String("line")) { return new Scripting::Line(dynamic_cast(o)); } else { KoReportPluginManager* manager = KoReportPluginManager::self(); KoReportPluginInterface *plugin = manager->plugin(o->typeName()); if (plugin) { QObject *obj = plugin->createScriptInstance(o); if (obj) { return obj; } } else { kreportWarning() << "Encountered unknown node while parsing section: " << o->typeName(); } } } } return 0; } QObject* Report::sectionByName(const QString &n) { KRSectionData *sec = m_reportData->section(n); if (sec) { return new Scripting::Section(sec); } else { return new QObject(); } } -void Report::initialize(QJSValue val) +void Report::initialize(const QJSValue &val) { m_scriptObject = val; } void Report::eventOnOpen() { - if (m_scriptObject.isObject()) + if (m_scriptObject.isObject() && m_scriptObject.hasProperty(QLatin1String("OnOpen"))) m_scriptObject.property(QLatin1String("OnOpen")).call(); } void Report::eventOnComplete() { - if (m_scriptObject.isObject()) + if (m_scriptObject.isObject() && m_scriptObject.hasProperty(QLatin1String("OnComlete"))) m_scriptObject.property(QLatin1String("OnComplete")).call(); } void Report::eventOnNewPage() { - if (m_scriptObject.isObject()) + if (m_scriptObject.isObject() && m_scriptObject.hasProperty(QLatin1String("OnNewPage"))) m_scriptObject.property(QLatin1String("OnNewPage")).call(); } } diff --git a/src/renderer/scripting/krscriptreport.h b/src/renderer/scripting/krscriptreport.h index 03fcce31..d16ba976 100644 --- a/src/renderer/scripting/krscriptreport.h +++ b/src/renderer/scripting/krscriptreport.h @@ -1,58 +1,58 @@ /* 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 . */ #ifndef SCRIPTINGKRSCRIPTREPORT_H #define SCRIPTINGKRSCRIPTREPORT_H #include #include class KoReportReportData; namespace Scripting { /** */ class Report : public QObject { Q_OBJECT public: explicit Report(KoReportReportData*); ~Report(); public Q_SLOTS: QString title(); QString name(); QString recordSource(); QObject* objectByName(const QString &); QObject* sectionByName(const QString &); - void initialize(QJSValue val); + void initialize(const QJSValue &val); void eventOnOpen(); void eventOnComplete(); void eventOnNewPage(); private: KoReportReportData *m_reportData; QJSValue m_scriptObject; }; } #endif diff --git a/src/renderer/scripting/krscriptsection.cpp b/src/renderer/scripting/krscriptsection.cpp index ba766c3a..3e29b289 100644 --- a/src/renderer/scripting/krscriptsection.cpp +++ b/src/renderer/scripting/krscriptsection.cpp @@ -1,108 +1,108 @@ /* 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 "krscriptsection.h" #include "krscriptline.h" #include "KoReportItemBase.h" #include "KoReportPluginManager.h" #include "KoReportPluginInterface.h" #include "KoReportItemLine.h" #include "kreport_debug.h" #include "krsectiondata.h" namespace Scripting { Section::Section(KRSectionData* sec) { m_section = sec; m_scriptObject = 0; } Section::~Section() { } QColor Section::backgroundColor() { return m_section->m_backgroundColor->value().value(); } void Section::setBackgroundColor(const QColor &c) { //kreportDebug() << c.name(); m_section->m_backgroundColor->setValue(c); } qreal Section::height() { return m_section->m_height->value().toDouble(); } void Section::setHeight(qreal h) { m_section->m_height->setValue(h); } QString Section::name() { return m_section->objectName(); } QObject* Section::objectByNumber(int i) { if (m_section->m_objects[i]->typeName() == QLatin1String("line")) { return new Scripting::Line(dynamic_cast(m_section->m_objects[i])); } else { KoReportPluginManager* manager = KoReportPluginManager::self(); KoReportPluginInterface *plugin = manager->plugin(m_section->m_objects[i]->typeName()); if (plugin) { QObject *obj = plugin->createScriptInstance(m_section->m_objects[i]); if (obj) { return obj; } } else { kreportWarning() << "Encountered unknown node while parsing section: " << m_section->m_objects[i]->typeName(); } } return new QObject(); } QObject* Section::objectByName(const QString& n) { for (int i = 0; i < m_section->objects().count(); ++i) { if (m_section->m_objects[i]->entityName() == n) { return objectByNumber(i); } } return 0; } -void Section::initialize(QJSValue s) +void Section::initialize(const QJSValue &s) { m_scriptObject = s; } void Section::eventOnRender() { - if (m_scriptObject.isObject()) + if (m_scriptObject.isObject() && m_scriptObject.hasProperty(QLatin1String("OnRender"))) m_scriptObject.property(QLatin1String("OnRender")).call(); } } diff --git a/src/renderer/scripting/krscriptsection.h b/src/renderer/scripting/krscriptsection.h index 6ec68d63..a72172e4 100644 --- a/src/renderer/scripting/krscriptsection.h +++ b/src/renderer/scripting/krscriptsection.h @@ -1,66 +1,66 @@ /* 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 . */ #ifndef KRSCRIPTSECTION_H #define KRSCRIPTSECTION_H #include #include class KRSectionData; /** */ namespace Scripting { class Section : public QObject { Q_OBJECT public: explicit Section(KRSectionData*); ~Section(); public Q_SLOTS: /**Returns the background color of the section*/ QColor backgroundColor(); /**Sets the background color of the section to the given color */ void setBackgroundColor(const QColor&); /**Returns the section height as a real number, in points*/ qreal height(); /**Sets the section height to the given value in points*/ void setHeight(qreal); /**Returns the name of the section*/ QString name(); /**Returns an object in the section, by number*/ QObject* objectByNumber(int); /**Returns an object in the section, by name*/ QObject* objectByName(const QString&); - void initialize(QJSValue s); + void initialize(const QJSValue &s); void eventOnRender(); private: KRSectionData *m_section; QJSValue m_scriptObject; }; } #endif diff --git a/src/wrtembed/KoReportDesigner.cpp b/src/wrtembed/KoReportDesigner.cpp index 5685575f..ccc8e648 100644 --- a/src/wrtembed/KoReportDesigner.cpp +++ b/src/wrtembed/KoReportDesigner.cpp @@ -1,1509 +1,1528 @@ /* 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 "KoReportDesigner.h" #include "reportsection.h" #include "reportscene.h" #include "reportsceneview.h" #include "reportsectiondetailgroup.h" #include "reportpropertiesbutton.h" #include "sectioneditor.h" #include "reportsectiondetail.h" #include "KoReportDesignerItemLine.h" #include "KReportRuler_p.h" #include "KReportZoomHandler.h" #include "common/KReportPageFormat.h" #include "KReportDpi.h" #include "common/krutils.h" #include "common/KoReportPluginInterface.h" #include "common/KoReportPluginManager.h" +#include "kreport_debug.h" #include #include #include #include #include #include #include #include #include #include #include #include -#include "kreport_debug.h" +#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 KoReportDesigner::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; } QGridLayout *grid; KReportRuler *hruler; KReportZoomHandler *zoom; QVBoxLayout *vboxlayout; ReportPropertiesButton *pageButton; QGraphicsScene *activeScene; ReportWriterSectionData *sectionData; ReportSection *reportHeader; ReportSection *pageHeaderFirst; ReportSection *pageHeaderOdd; ReportSection *pageHeaderEven; ReportSection *pageHeaderLast; ReportSection *pageHeaderAny; ReportSection *pageFooterFirst; ReportSection *pageFooterOdd; ReportSection *pageFooterEven; ReportSection *pageFooterLast; ReportSection *pageFooterAny; ReportSection *reportFooter; ReportSectionDetail *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 loadInterpreter; //Value of the script interpreter at load time + QString loadScript; //Value of the script at load time + KoReportData *kordata; }; KoReportDesigner::KoReportDesigner(QWidget * parent) : QWidget(parent), d(new Private()) { init(); } void KoReportDesigner::init() { 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 ReportPropertiesButton(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 ReportSectionDetail(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); } KoReportDesigner::~KoReportDesigner() { delete d; } ///The loading Code KoReportDesigner::KoReportDesigner(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")) { -//!TODO d->interpreter->setValue(it.toElement().attribute(QLatin1String("report:script-interpreter"))); - d->script->setValue(it.firstChild().nodeValue()); + d->loadInterpreter = it.toElement().attribute(QLatin1String("report:script-interpreter")); + d->loadScript = it.firstChild().nodeValue(); + d->script->setValue(d->loadScript); + + if (d->loadInterpreter != QLatin1String("javascript") || d->loadInterpreter != QLatin1String("qtscript")) { + QString msg = tr("This report is using a script type other than 'javascript'\n" + "To prevent data loss, the type of script will not be changed unless the script is changed.\n\n" + "Please be aware that the script will not work unless it is changed to a 'javascript' script."); + QMessageBox::warning(this, tr("Invalid Script Detected"), 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(KRSectionData::sectionTypeFromString(sectiontype)) == 0) { insertSection(KRSectionData::sectionTypeFromString(sectiontype)); section(KRSectionData::sectionTypeFromString(sectiontype))->initFromXML(sec); } } else if (sn == QLatin1String("report:detail")) { ReportSectionDetail * rsd = new ReportSectionDetail(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 KoReportDesigner::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() != d->loadScript || d->loadInterpreter == QLatin1String("qtscript")) { + //The script has changed so force interpreter to 'javascript'. Also set if was using qtscript + saveInterpreter = QLatin1String("javascript"); + } else { + saveInterpreter = d->loadInterpreter; + } + QDomElement scr = propertyToElement(&doc, d->script); - //KRUtils::addPropertyAsAttribute(&scr, d->interpreter); + scr.setAttribute(QLatin1String("report:interpreter"), saveInterpreter); content.appendChild(scr); #endif QDomElement grd = doc.createElement(QLatin1String("report:grid")); KRUtils::addPropertyAsAttribute(&grd, d->showGrid); KRUtils::addPropertyAsAttribute(&grd, d->gridDivisions); KRUtils::addPropertyAsAttribute(&grd, d->gridSnap); KRUtils::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"))); KRUtils::setAttribute(&pagestyle, QLatin1String("report:custom-page-width"), d->customWidth->value().toDouble()); KRUtils::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"))); KRUtils::addPropertyAsAttribute(&pagestyle, d->pageSize); //pagestyle.setAttribute("report:page-size", d->pageSize->value().toString()); } // -- orientation KRUtils::addPropertyAsAttribute(&pagestyle, d->orientation); // -- margins: save as points, and not localized KRUtils::setAttribute(&pagestyle, QLatin1String("fo:margin-top"), d->topMargin->value().toDouble()); KRUtils::setAttribute(&pagestyle, QLatin1String("fo:margin-bottom"), d->bottomMargin->value().toDouble()); KRUtils::setAttribute(&pagestyle, QLatin1String("fo:margin-right"), d->rightMargin->value().toDouble()); KRUtils::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 = KRSectionData::PageHeaderFirst; i <= KRSectionData::PageFooterAny; ++i) { ReportSection *sec = section((KRSectionData::Section)i); if (sec) { domsection = doc.createElement(QLatin1String("report:section")); domsection.setAttribute(QLatin1String("report:section-type"), KRSectionData::sectionTypeString(KRSectionData::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 KoReportDesigner::slotSectionEditor() { QPointer se = new SectionEditor(this); se->init(this); se->exec(); delete se; } void KoReportDesigner::setReportData(KoReportData* kodata) { //kreportDebug(); if (kodata) { d->kordata = kodata; slotPageButton_Pressed(); setModified(true); emit reportDataChanged(); } } ReportSection * KoReportDesigner::section(KRSectionData::Section s) const { ReportSection *sec; switch (s) { case KRSectionData::PageHeaderAny: sec = d->pageHeaderAny; break; case KRSectionData::PageHeaderEven: sec = d->pageHeaderEven; break; case KRSectionData::PageHeaderOdd: sec = d->pageHeaderOdd; break; case KRSectionData::PageHeaderFirst: sec = d->pageHeaderFirst; break; case KRSectionData::PageHeaderLast: sec = d->pageHeaderLast; break; case KRSectionData::PageFooterAny: sec = d->pageFooterAny; break; case KRSectionData::PageFooterEven: sec = d->pageFooterEven; break; case KRSectionData::PageFooterOdd: sec = d->pageFooterOdd; break; case KRSectionData::PageFooterFirst: sec = d->pageFooterFirst; break; case KRSectionData::PageFooterLast: sec = d->pageFooterLast; break; case KRSectionData::ReportHeader: sec = d->reportHeader; break; case KRSectionData::ReportFooter: sec = d->reportFooter; break; default: sec = 0; } return sec; } void KoReportDesigner::removeSection(KRSectionData::Section s) { ReportSection* sec = section(s); if (sec) { delete sec; switch (s) { case KRSectionData::PageHeaderAny: d->pageHeaderAny = 0; break; case KRSectionData::PageHeaderEven: sec = d->pageHeaderEven = 0; break; case KRSectionData::PageHeaderOdd: d->pageHeaderOdd = 0; break; case KRSectionData::PageHeaderFirst: d->pageHeaderFirst = 0; break; case KRSectionData::PageHeaderLast: d->pageHeaderLast = 0; break; case KRSectionData::PageFooterAny: d->pageFooterAny = 0; break; case KRSectionData::PageFooterEven: d->pageFooterEven = 0; break; case KRSectionData::PageFooterOdd: d->pageFooterOdd = 0; break; case KRSectionData::PageFooterFirst: d->pageFooterFirst = 0; break; case KRSectionData::PageFooterLast: d->pageFooterLast = 0; break; case KRSectionData::ReportHeader: d->reportHeader = 0; break; case KRSectionData::ReportFooter: d->reportFooter = 0; break; default: sec = 0; } setModified(true); adjustSize(); } } void KoReportDesigner::insertSection(KRSectionData::Section s) { ReportSection* sec = section(s); if (!sec) { int idx = 0; for (int i = 1; i <= s; ++i) { if (section((KRSectionData::Section)i)) idx++; } if (s > KRSectionData::ReportHeader) idx++; //kreportDebug() << idx; ReportSection *rs = new ReportSection(this); d->vboxlayout->insertWidget(idx, rs); switch (s) { case KRSectionData::PageHeaderAny: rs->setTitle(tr("Page Header (Any)")); d->pageHeaderAny = rs; break; case KRSectionData::PageHeaderEven: rs->setTitle(tr("Page Header (Even)")); d->pageHeaderEven = rs; break; case KRSectionData::PageHeaderOdd: rs->setTitle(tr("Page Header (Odd)")); d->pageHeaderOdd = rs; break; case KRSectionData::PageHeaderFirst: rs->setTitle(tr("Page Header (First)")); d->pageHeaderFirst = rs; break; case KRSectionData::PageHeaderLast: rs->setTitle(tr("Page Header (Last)")); d->pageHeaderLast = rs; break; case KRSectionData::PageFooterAny: rs->setTitle(tr("Page Footer (Any)")); d->pageFooterAny = rs; break; case KRSectionData::PageFooterEven: rs->setTitle(tr("Page Footer (Even)")); d->pageFooterEven = rs; break; case KRSectionData::PageFooterOdd: rs->setTitle(tr("Page Footer (Odd)")); d->pageFooterOdd = rs; break; case KRSectionData::PageFooterFirst: rs->setTitle(tr("Page Footer (First)")); d->pageFooterFirst = rs; break; case KRSectionData::PageFooterLast: rs->setTitle(tr("Page Footer (Last)")); d->pageFooterLast = rs; break; case KRSectionData::ReportHeader: rs->setTitle(tr("Report Header")); d->reportHeader = rs; break; case KRSectionData::ReportFooter: rs->setTitle(tr("Report Footer")); d->reportFooter = rs; break; //These sections cannot be inserted this way case KRSectionData::None: case KRSectionData::GroupHeader: case KRSectionData::GroupFooter: case KRSectionData::Detail: break; } rs->show(); setModified(true); adjustSize(); emit pagePropertyChanged(*d->set); } } void KoReportDesigner::setReportTitle(const QString & str) { if (reportTitle() != str) { d->title->setValue(str); setModified(true); } } KPropertySet * KoReportDesigner::propertySet() const { return d->set; } KPropertySet* KoReportDesigner::itemPropertySet() const { return d->itmset; } KoReportData *KoReportDesigner::reportData() const { return d->kordata; } ReportSectionDetail * KoReportDesigner::detailSection() const { return d->detail; } QString KoReportDesigner::reportTitle() const { return d->title->value().toString(); } bool KoReportDesigner::isModified() const { return d->modified; } void KoReportDesigner::setModified(bool mod) { d->modified = mod; if (d->modified) { emit dirty(); } } QStringList KoReportDesigner::fieldNames() const { QStringList qs; qs << QString(); if (d->kordata) qs << d->kordata->fieldNames(); return qs; } QStringList KoReportDesigner::fieldKeys() const { QStringList qs; qs << QString(); if (d->kordata) qs << d->kordata->fieldKeys(); return qs; } void KoReportDesigner::createProperties() { QStringList keys, strings; d->set = new KPropertySet(0, QLatin1String("Report")); 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 = KReportPageFormat::pageFormatNames(); strings = KReportPageFormat::localizedPageFormatNames(); QString defaultKey = KReportPageFormat::formatString(KReportPageFormat::defaultFormat()); 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 KoReportDesigner::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 KoReportDesigner::slotPageButton_Pressed() { - qDebug() << "page button pressed"; #ifdef KREPORT_SCRIPTING if (d->kordata) { QStringList sl = d->kordata->scriptList(); - sl.push_front(QLatin1String("")); + sl.prepend(QLatin1String("")); d->script->setListData(sl, sl); } changeSet(d->set); #endif } QSize KoReportDesigner::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 KoReportDesigner::pageWidthPx() const { int cw = 0; int ch = 0; int width = 0; KReportPageFormat::Format pf = KReportPageFormat::formatFromString(d->set->property("page-size").value().toString()); cw = POINT_TO_INCH(MM_TO_POINT(KReportPageFormat::width(pf, KReportPageFormat::Portrait))) * KReportDpi::dpiX(); ch = POINT_TO_INCH(MM_TO_POINT(KReportPageFormat::height(pf, KReportPageFormat::Portrait))) * KReportDpi::dpiY(); width = (d->set->property("print-orientation").value().toString() == QLatin1String("portrait") ? cw : ch); 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(); return width; } void KoReportDesigner::resizeEvent(QResizeEvent * event) { Q_UNUSED(event); //hruler->setRulerLength ( vboxlayout->geometry().width() ); d->hruler->setRulerLength(pageWidthPx()); } void KoReportDesigner::setDetail(ReportSectionDetail *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 KoReportDesigner::deleteDetail() { delete d->detail; d->detail = 0; } KReportUnit KoReportDesigner::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 KoReportDesigner::setGridOptions(bool vis, int div) { d->showGrid->setValue(QVariant(vis)); d->gridDivisions->setValue(div); } // // methods for the sectionMouse*Event() // void KoReportDesigner::sectionContextMenuEvent(ReportScene * 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 KoReportDesigner::sectionMousePressEvent(ReportSceneView * v, QMouseEvent * e) { Q_UNUSED(v); d->pressX = e->pos().x(); d->pressY = e->pos().y(); } void KoReportDesigner::sectionMouseReleaseEvent(ReportSceneView * 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; if (d->sectionData->insertItem == QLatin1String("org.kde.kreport.line")) { item = new KoReportDesignerItemLine(v->designer(), v->scene(), pos, end); } else { KoReportPluginManager* pluginManager = KoReportPluginManager::self(); KoReportPluginInterface *plug = pluginManager->plugin(d->sectionData->insertItem); if (plug) { QObject *obj = plug->createDesignerInstance(v->designer(), v->scene(), pos); if (obj) { item = dynamic_cast(obj); } } else { kreportWarning() << "attempted to insert an unknown item"; } } if (item) { item->setVisible(true); item->setSelected(true); KoReportItemBase* baseReportItem = dynamic_cast(item); if (baseReportItem) { changeSet(baseReportItem->propertySet()); 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 KoReportDesigner::selectionCount() const { if (activeScene()) return activeScene()->selectedItems().count(); else return 0; } void KoReportDesigner::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 KoReportDesigner::slotItem(const QString &entity) { kreportDebug() << entity; d->sectionData->mouseAction = ReportWriterSectionData::MA_Insert; d->sectionData->insertItem = entity; setSectionCursor(QCursor(Qt::CrossCursor)); } void KoReportDesigner::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 KoReportDesigner::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 KoReportDesigner::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 KoReportDesigner::slotEditPaste() { // call the editPaste function passing it a reportsection slotEditPaste(activeScene()); } void KoReportDesigner::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(KoReportDesignerItemBase *item, d->sectionData->copy_list) { KoReportItemBase *obj = dynamic_cast(item); const QString type = obj ? obj->typeName() : QLatin1String("object"); //kreportDebug() << type; KoReportDesignerItemBase *ent = item->clone(); KoReportItemBase *new_obj = dynamic_cast(ent); new_obj->setEntityName(suggestEntityName(type)); if (activeItem) { new_obj->position().setScenePos(QPointF(activeItem->x() + 10, activeItem->y() + 10)); } else { new_obj->position().setScenePos(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 KoReportDesigner::slotRaiseSelected() { dynamic_cast(activeScene())->raiseSelected(); } void KoReportDesigner::slotLowerSelected() { dynamic_cast(activeScene())->lowerSelected(); } QGraphicsScene* KoReportDesigner::activeScene() const { return d->activeScene; } void KoReportDesigner::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* KoReportDesigner::zoomHandler() const { return d->zoom; } QString KoReportDesigner::suggestEntityName(const QString &n) const { ReportSection *sec; int itemCount = 0; //Count items in the main sections for (int i = 1; i <= KRSectionData::PageFooterAny; i++) { sec = section((KRSectionData::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 KoReportDesigner::isEntityNameUnique(const QString &n, KoReportItemBase* ignore) const { ReportSection *sec; bool unique = true; //Check items in the main sections for (int i = 1; i <= KRSectionData::PageFooterAny; i++) { sec = section((KRSectionData::Section)i); if (sec) { const QGraphicsItemList l = sec->items(); for (QGraphicsItemList::const_iterator it = l.constBegin(); it != l.constEnd(); ++it) { KoReportItemBase* 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) { KoReportItemBase* 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) { KoReportItemBase* 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) { KoReportItemBase* itm = dynamic_cast(*it); if (itm && 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 KoReportDesigner::itemActions(QActionGroup* group) { KoReportPluginManager* manager = KoReportPluginManager::self(); QList actList = manager->actions(); QAction *act = new QAction(QIcon::fromTheme(QLatin1String("draw-line")), 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* > KoReportDesigner::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 KoReportDesigner::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 KoReportDesigner::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 KoReportDesigner::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 KoReportDesigner::countSelectionHeight() const { if (d->releaseY == -1 || d->pressY == -1) { return -1; } return qAbs(d->releaseY - d->pressY); } qreal KoReportDesigner::countSelectionWidth() const { if (d->releaseX == -1 || d->pressX == -1) { return -1; } return qAbs(d->releaseX - d->pressX); } qreal KoReportDesigner::getSelectionPressX() const { return d->pressX; } qreal KoReportDesigner::getSelectionPressY() const { return d->pressY; } QPointF KoReportDesigner::getPressPoint() const { return QPointF(d->pressX, d->pressY); } QPointF KoReportDesigner::getReleasePoint() const { return QPointF(d->releaseX, d->releaseY); } void KoReportDesigner::plugItemActions(const QList &actList) { foreach(QAction *a, actList) { connect(a, SIGNAL(triggered(bool)), this, SLOT(slotItemTriggered(bool))); } } void KoReportDesigner::slotItemTriggered(bool checked) { if (!checked) { return; } QObject *theSender = sender(); if (!theSender) { return; } slotItem(theSender->objectName()); }