/*************************************************************************** * This file is part of the Lime Report project * * Copyright (C) 2015 by Alexander Arin * * arin_a@bk.ru * * * ** GNU General Public License Usage ** * * * This library is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * * * ** GNU Lesser General Public License ** * * * 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 3 of the * * License, or (at your option) any later version. * * You should have received a copy of the GNU Lesser General Public * * License along with this library. * * If not, see . * * * * 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 General Public License for more details. * ****************************************************************************/ #include "lrreportdesignwidget.h" #include "serializators/lrxmlreader.h" #include "serializators/lrxmlwriter.h" #include "lrreportengine_p.h" #include "lrbasedesignintf.h" #include "lrsettingdialog.h" #include "dialogdesigner/lrdialogdesigner.h" #include #include #include #include #include #include #include #include #include namespace LimeReport { // ReportDesignIntf ReportDesignWidget::ReportDesignWidget(ReportEngine *report, QMainWindow *mainWindow, QWidget *parent) : QWidget(parent), #ifdef HAVE_QTDESIGNER_INTEGRATION m_dialogDesignerManager(new DialogDesignerManager(this)), #endif m_mainWindow(mainWindow), m_verticalGridStep(10), m_horizontalGridStep(10), m_useGrid(false), m_dialogChanged(false) { m_tabWidget = new QTabWidget(this); m_tabWidget->setTabPosition(QTabWidget::South); QVBoxLayout* mainLayout = new QVBoxLayout(this); mainLayout->addWidget(m_tabWidget); setLayout(mainLayout); if (!report) { m_report=new ReportEnginePrivate(this); m_report->setObjectName("report"); m_report->appendPage("page1"); } else { m_report=report->d_ptr; if (!m_report->pageCount()) m_report->appendPage("page1"); } createTabs(); connect(m_report,SIGNAL(pagesLoadFinished()),this,SLOT(slotPagesLoadFinished())); connect(m_report,SIGNAL(cleared()),this,SIGNAL(cleared())); connect(m_tabWidget, SIGNAL(currentChanged(int)), this, SLOT(slotCurrentTabChanged(int))); #ifdef HAVE_UI_LOADER connect(m_report->scriptContext(), SIGNAL(dialogDeleted(QString)), this, SLOT(slotDialogDeleted(QString))); #endif //m_instance=this; m_scriptEditor->setPlainText(m_report->scriptContext()->initScript()); m_zoomer = new GraphicsViewZoomer(activeView()); #ifdef Q_OS_WIN m_defaultFont = QFont("Arial",10); #endif #ifdef HAVE_QTDESIGNER_INTEGRATION connect(m_dialogDesignerManager, SIGNAL(dialogChanged(QString)), this, SLOT(slotDialogChanged(QString))); connect(m_dialogDesignerManager, SIGNAL(dialogNameChanged(QString,QString)), this, SLOT(slotDialogNameChanged(QString,QString))); #endif } #ifdef HAVE_QTDESIGNER_INTEGRATION DialogDesignerManager *ReportDesignWidget::dialogDesignerManager() const { return m_dialogDesignerManager; } QString ReportDesignWidget::activeDialogName() { if (activeDialogPage()) return activeDialogPage()->dialogName(); return ""; } QWidget *ReportDesignWidget::toolWindow(ReportDesignWidget::ToolWindowType windowType) { switch (windowType) { case WidgetBox: return dialogDesignerManager()->widgetBox(); case PropertyEditor: return dialogDesignerManager()->propertyEditor(); case ObjectInspector: return dialogDesignerManager()->objectInspector(); case ActionEditor: return dialogDesignerManager()->actionEditor(); case ResourceEditor: return dialogDesignerManager()->resourcesEditor(); case SignalSlotEditor: return dialogDesignerManager()->signalSlotEditor(); default: return 0; } } #endif ReportDesignWidget::EditorTabType ReportDesignWidget::activeTabType() { QString tabType = m_tabWidget->tabWhatsThis(m_tabWidget->currentIndex()); if ( tabType.compare("dialog") == 0) return Dialog; if ( tabType.compare("script") == 0) return Script; return Page; } #ifdef HAVE_QTDESIGNER_INTEGRATION void ReportDesignWidget::initDialogDesignerToolBar(QToolBar *toolBar) { m_dialogDesignerManager->initToolBar(toolBar); } void ReportDesignWidget::updateDialogs() { for ( int i = 0; icount(); ++i ){ if (m_tabWidget->tabWhatsThis(i).compare("dialog") == 0){ m_report->scriptContext()->changeDialog(m_tabWidget->tabText(i), m_dialogDesignerManager->getDialogDescription(m_tabWidget->widget(i))); } } } #endif bool ReportDesignWidget::useMagnet() const { return m_useMagnet; } void ReportDesignWidget::setUseMagnet(bool useMagnet) { m_useMagnet = useMagnet; for (int i=0;ipageCount();++i){ m_report->pageAt(i)->setMagneticMovement(useMagnet); } } void ReportDesignWidget::saveState(QSettings* settings) { settings->beginGroup("DesignerWidget"); settings->setValue("hGridStep",m_horizontalGridStep); settings->setValue("vGridStep",m_verticalGridStep); settings->setValue("defaultFont",m_defaultFont); settings->setValue("useGrid",m_useGrid); settings->endGroup(); } void ReportDesignWidget::applySettings() { for (int i=0;ipageCount();++i){ m_report->pageAt(i)->pageItem()->setFont(m_defaultFont); } applyUseGrid(); } void ReportDesignWidget::loadState(QSettings* settings) { settings->beginGroup("DesignerWidget"); QVariant v = settings->value("hGridStep"); if (v.isValid()){ m_horizontalGridStep = v.toInt(); } v = settings->value("vGridStep"); if (v.isValid()){ m_verticalGridStep = v.toInt(); } v = settings->value("defaultFont"); if (v.isValid()){ m_defaultFont = v.value(); } v = settings->value("useGrid"); if (v.isValid()){ m_useGrid = v.toBool(); } settings->endGroup(); applySettings(); } void ReportDesignWidget::createTabs(){ int pageIndex = -1; for (int i = 0; ipageCount();++i){ QGraphicsView* view = new QGraphicsView(qobject_cast(this)); view->setBackgroundBrush(QBrush(Qt::gray)); view->setFrameShape(QFrame::NoFrame); view->setScene(m_report->pageAt(i)); foreach(QGraphicsItem* item, m_report->pageAt(i)->selectedItems()){ item->setSelected(false); } view->centerOn(0,0); view->scale(0.5,0.5); connectPage(m_report->pageAt(i)); pageIndex = m_tabWidget->addTab(view,QIcon(),m_report->pageAt(i)->pageItem()->objectName()); m_tabWidget->setTabWhatsThis(pageIndex, "page"); } m_scriptEditor = new QTextEdit(this); pageIndex = m_tabWidget->addTab(m_scriptEditor,QIcon(),tr("Script")); m_tabWidget->setTabWhatsThis(pageIndex,"script"); m_tabWidget->setCurrentIndex(0); #ifdef HAVE_QTDESIGNER_INTEGRATION QWidget* dialogDesigner; foreach(DialogDescriber::Ptr dialogDesc, m_report->scriptContext()->dialogDescribers()){ dialogDesigner = m_dialogDesignerManager->createFormEditor(dialogDesc->description()); pageIndex = m_tabWidget->addTab(dialogDesigner,QIcon(),dialogDesc->name()); m_tabWidget->setTabWhatsThis(pageIndex,"dialog"); } #endif } #ifdef HAVE_QTDESIGNER_INTEGRATION void ReportDesignWidget::createNewDialogTab(const QString& dialogName, const QByteArray& description) { QWidget* dialogDesigner = m_dialogDesignerManager->createFormEditor(description); int pageIndex = m_tabWidget->addTab(dialogDesigner,QIcon(),dialogName); m_tabWidget->setTabWhatsThis(pageIndex,"dialog"); m_tabWidget->setCurrentIndex(pageIndex); } DialogDesigner*ReportDesignWidget::activeDialogPage() { return dynamic_cast(m_tabWidget->currentWidget()); } #endif ReportDesignWidget::~ReportDesignWidget() { delete m_zoomer; } QGraphicsView* ReportDesignWidget::activeView(){ return dynamic_cast(m_tabWidget->currentWidget()); } void ReportDesignWidget::connectPage(PageDesignIntf *page) { connect(page,SIGNAL(itemInserted(LimeReport::PageDesignIntf*,QPointF,QString)),this,SIGNAL(itemInserted(LimeReport::PageDesignIntf*,QPointF,QString))); connect(page,SIGNAL(itemInsertCanceled(QString)),this,SIGNAL(itemInsertCanceled(QString))); connect(page,SIGNAL(itemPropertyChanged(QString,QString,QVariant,QVariant)),this,SIGNAL(itemPropertyChanged(QString,QString,QVariant,QVariant))); connect(page,SIGNAL(selectionChanged()),this,SLOT(slotSelectionChanged())); connect(page,SIGNAL(insertModeStarted()),this,SIGNAL(insertModeStarted())); connect(page,SIGNAL(commandHistoryChanged()),this,SIGNAL(commandHistoryChanged())); connect(page,SIGNAL(sceneRectChanged(QRectF)),this,SLOT(slotSceneRectChanged(QRectF))); connect(page,SIGNAL(itemAdded(LimeReport::PageDesignIntf*,LimeReport::BaseDesignIntf*)), this, SIGNAL(itemAdded(LimeReport::PageDesignIntf*,LimeReport::BaseDesignIntf*))); connect(page,SIGNAL(itemRemoved(LimeReport::PageDesignIntf*,LimeReport::BaseDesignIntf*)), this,SIGNAL(itemDeleted(LimeReport::PageDesignIntf*,LimeReport::BaseDesignIntf*))); connect(page,SIGNAL(bandAdded(LimeReport::PageDesignIntf*,LimeReport::BandDesignIntf*)), this, SIGNAL(bandAdded(LimeReport::PageDesignIntf*,LimeReport::BandDesignIntf*))); connect(page, SIGNAL(bandRemoved(LimeReport::PageDesignIntf*,LimeReport::BandDesignIntf*)), this, SIGNAL(bandDeleted(LimeReport::PageDesignIntf*,LimeReport::BandDesignIntf*))); connect(page, SIGNAL(pageUpdateFinished(LimeReport::PageDesignIntf*)), this, SIGNAL(activePageUpdated(LimeReport::PageDesignIntf*))); emit activePageChanged(); } void ReportDesignWidget::createStartPage() { m_report->appendPage("page1"); createTabs(); } void ReportDesignWidget::removeDatasource(const QString &datasourceName) { if (m_report->dataManager()) m_report->dataManager()->removeDatasource(datasourceName); } void ReportDesignWidget::addBand(const QString &bandType) { if (activePage()) activePage()->addBand(bandType); } void ReportDesignWidget::addBand(BandDesignIntf::BandsType bandType) { if (activePage()) activePage()->addBand(bandType); } void ReportDesignWidget::startInsertMode(const QString &itemType) { if (activePage()) activePage()->startInsertMode(itemType); } void ReportDesignWidget::startEditMode() { if (activePage()) activePage()->startEditMode(); } PageDesignIntf * ReportDesignWidget::activePage() { if (activeView()) return qobject_cast(activeView()->scene()); return 0; } QList ReportDesignWidget::selectedItems(){ return activePage()->selectedItems(); } void ReportDesignWidget::deleteItem(QGraphicsItem *item){ activePage()->removeReportItem(dynamic_cast(item)); } void ReportDesignWidget::deleteSelectedItems(){ activePage()->deleteSelected(); } QStringList ReportDesignWidget::datasourcesNames(){ return m_report->dataManager()->dataSourceNames(); } void ReportDesignWidget::slotItemSelected(BaseDesignIntf *item){ emit itemSelected(item); } bool ReportDesignWidget::saveToFile(const QString &fileName){ bool result = false; m_report->scriptContext()->setInitScript(m_scriptEditor->toPlainText()); #ifdef HAVE_QTDESIGNER_INTEGRATION updateDialogs(); #endif if (m_report->saveToFile(fileName)) { m_report->emitSaveFinished(); result = true; } #ifdef HAVE_QTDESIGNER_INTEGRATION if (result){ m_dialogChanged = false; m_dialogDesignerManager->setDirty(false); } #endif return result; } bool ReportDesignWidget::save() { m_report->scriptContext()->setInitScript(m_scriptEditor->toPlainText()); #ifdef HAVE_QTDESIGNER_INTEGRATION updateDialogs(); #endif bool result = false; if (!m_report->reportFileName().isEmpty()){ if (m_report->saveToFile()){ m_report->emitSaveFinished(); result = true; } } else { m_report->emitSaveReport(); if (m_report->isSaved()) { m_report->emitSaveFinished(); result = true; } else if (m_report->saveToFile(QFileDialog::getSaveFileName(this,tr("Report file name"),"","Report files (*.lrxml);; All files (*)"))){ m_report->emitSaveFinished(); result = true; }; } #ifdef HAVE_QTDESIGNER_INTEGRATION if (result){ m_dialogChanged = false; m_dialogDesignerManager->setDirty(false); } #endif return result; } bool ReportDesignWidget::loadFromFile(const QString &fileName) { if (m_report->loadFromFile(fileName,false)){ createTabs(); //connectPage(m_report->pageAt(0)); m_scriptEditor->setPlainText(m_report->scriptContext()->initScript()); emit loaded(); m_dialogChanged = false; return true; } else { QMessageBox::critical(this,tr("Error"),tr("Wrong file format")); return false; } } void ReportDesignWidget::scale(qreal sx, qreal sy) { //m_view->scale(sx,sy); if (activeView()) activeView()->scale(sx,sy); } QString ReportDesignWidget::reportFileName() { if (m_report) return m_report->reportFileName(); return QString(); } bool ReportDesignWidget::isNeedToSave() { if(m_report) return (m_report->isNeedToSave() || m_dialogChanged); return false; } bool ReportDesignWidget::emitLoadReport() { return m_report->emitLoadReport(); } void ReportDesignWidget::updateSize() { if (activePage()) activePage()->slotUpdateItemSize(); } void ReportDesignWidget::undo() { if (activePage()) activePage()->undo(); #ifdef HAVE_QTDESIGNER_INTEGRATION if (activeDialogPage()) activeDialogPage()->undo(); #endif } void ReportDesignWidget::redo() { if (activePage()) activePage()->redo(); #ifdef HAVE_QTDESIGNER_INTEGRATION if (activeDialogPage()) activeDialogPage()->redo(); #endif } void ReportDesignWidget::copy() { if (activePage()) activePage()->copy(); } void ReportDesignWidget::paste() { if (activePage()) activePage()->paste(); } void ReportDesignWidget::cut() { if (activePage()) activePage()->cut(); } void ReportDesignWidget::brinToFront() { if (activePage()) activePage()->bringToFront(); } void ReportDesignWidget::sendToBack() { if (activePage()) activePage()->sendToBack(); } void ReportDesignWidget::alignToLeft() { if (activePage()) activePage()->alignToLeft(); } void ReportDesignWidget::alignToRight() { if (activePage()) activePage()->alignToRigth(); } void ReportDesignWidget::alignToVCenter() { if (activePage()) activePage()->alignToVCenter(); } void ReportDesignWidget::alignToTop() { if (activePage()) activePage()->alignToTop(); } void ReportDesignWidget::alignToBottom() { if (activePage()) activePage()->alignToBottom(); } void ReportDesignWidget::alignToHCenter() { if (activePage()) activePage()->alignToHCenter(); } void ReportDesignWidget::sameHeight() { if (activePage()) activePage()->sameHeight(); } void ReportDesignWidget::sameWidth() { if (activePage()) activePage()->sameWidth(); } void ReportDesignWidget::editLayoutMode(bool value) { if (value ){ activePage()->pageItem()->setItemMode(activePage()->pageItem()->itemMode() | LayoutEditMode); } else if (activePage()->pageItem()->itemMode() & LayoutEditMode){ activePage()->pageItem()->setItemMode(activePage()->pageItem()->itemMode() ^ LayoutEditMode); } } void ReportDesignWidget::addHLayout() { if (activePage()) activePage()->addHLayout(); } void ReportDesignWidget::setFont(const QFont& font) { if (activePage()) activePage()->setFont(font); } void ReportDesignWidget::setTextAlign(const bool& horizontalAlign, const Qt::AlignmentFlag& alignment) { if (activePage()) activePage()->changeSelectedGrpoupTextAlignPropperty(horizontalAlign, alignment); } void ReportDesignWidget::setBorders(const BaseDesignIntf::BorderLines& borders) { if (activePage()) activePage()->setBorders(borders); } void ReportDesignWidget::previewReport() { report()->scriptContext()->setInitScript(m_scriptEditor->toPlainText()); #ifdef HAVE_QTDESIGNER_INTEGRATION updateDialogs(); #endif report()->previewReport(); } void ReportDesignWidget::printReport() { report()->scriptContext()->setInitScript(m_scriptEditor->toPlainText()); #ifdef HAVE_QTDESIGNER_INTEGRATION updateDialogs(); #endif setCursor(Qt::WaitCursor); report()->printReport(); setCursor(Qt::ArrowCursor); } void ReportDesignWidget::addPage() { QGraphicsView* view = new QGraphicsView(qobject_cast(this)); view->setBackgroundBrush(QBrush(Qt::gray)); view->setFrameShape(QFrame::NoFrame); PageDesignIntf* page = m_report->appendPage("page"+QString::number(m_report->pageCount()+1)); view->setScene(page); int index = m_report->pageCount()-1; m_tabWidget->insertTab(index,view,QIcon(),tr("Page")+QString::number(m_report->pageCount())); m_tabWidget->setCurrentIndex(index); connectPage(page); view->scale(0.5,0.5); view->centerOn(0,0); applyUseGrid(); emit pageAdded(page); } void ReportDesignWidget::deleteCurrentPage() { if (m_report->pageCount()>1){ QGraphicsView* view = dynamic_cast(m_tabWidget->currentWidget()); if (view){ PageDesignIntf* page = dynamic_cast(view->scene()); if (page){ if (m_report->deletePage(page)){ int index = m_tabWidget->currentIndex(); m_tabWidget->removeTab(m_tabWidget->currentIndex()); if (index>0) m_tabWidget->setCurrentIndex(index-1); emit pageDeleted(); } } } } } void ReportDesignWidget::editSetting() { SettingDialog setting(this); setting.setVerticalGridStep(m_verticalGridStep); setting.setHorizontalGridStep(m_horizontalGridStep); setting.setDefaultFont(m_defaultFont); setting.setSuppressAbsentFieldsAndVarsWarnings(m_report->suppressFieldAndVarError()); if (setting.exec()){ m_horizontalGridStep = setting.horizontalGridStep(); m_verticalGridStep = setting.verticalGridStep(); m_defaultFont = setting.defaultFont(); m_report->setSuppressFieldAndVarError(setting.suppressAbsentFieldsAndVarsWarnings()); applySettings(); } } void ReportDesignWidget::applyUseGrid() { int hGridStep = m_useGrid?m_horizontalGridStep:2; int vGridStep = m_useGrid?m_verticalGridStep:2; for(int i=0;ipageCount();++i){ m_report->pageAt(i)->setVerticalGridStep(hGridStep); m_report->pageAt(i)->setHorizontalGridStep(vGridStep); } } void ReportDesignWidget::setUseGrid(bool value) { m_useGrid = value; applyUseGrid(); } bool ReportDesignWidget::isCanUndo() { if (activePage()) return activePage()->isCanUndo(); return false; } bool ReportDesignWidget::isCanRedo() { if (activePage()) return activePage()->isCanRedo(); return false; } void ReportDesignWidget::slotSelectionChanged() { QGraphicsScene* page=dynamic_cast(sender()); if (page){ if (page->selectedItems().count()==1){ BaseDesignIntf* item = dynamic_cast(page->selectedItems().at(0)); if (item) emit (itemSelected(item)); } else if (page->selectedItems().count()>1){ emit (multiItemSelected()); } } } DataSourceManager* ReportDesignWidget::dataManager() { return m_report->dataManager(); } ScriptEngineManager* ReportDesignWidget::scriptManager() { return m_report->scriptManager(); } ScriptEngineContext*ReportDesignWidget::scriptContext() { return m_report->scriptContext(); } void ReportDesignWidget::slotPagesLoadFinished() { applySettings(); //setActivePage(m_report->pageAt(0)); emit loaded(); } void ReportDesignWidget::slotDialogDeleted(QString dialogName) { for (int i = 0; icount(); ++i ){ if (m_tabWidget->tabText(i).compare(dialogName) == 0){ delete m_tabWidget->widget(i); break; } } } void ReportDesignWidget::slotDatasourceCollectionLoaded(const QString & /*collectionName*/) { } void ReportDesignWidget::slotSceneRectChanged(QRectF) { if (activeView()) activeView()->centerOn(0,0); } void ReportDesignWidget::slotCurrentTabChanged(int index) { QGraphicsView* view = dynamic_cast(m_tabWidget->widget(index)); if (view) { if (view->scene()){ foreach (QGraphicsItem* item, view->scene()->selectedItems()) item->setSelected(false); } m_zoomer->setView(view); } #ifdef HAVE_QTDESIGNER_INTEGRATION if (activeTabType() == Dialog){ m_dialogDesignerManager->setActiveEditor(m_tabWidget->widget(index)); } updateDialogs(); #endif emit activePageChanged(); } #ifdef HAVE_QTDESIGNER_INTEGRATION void ReportDesignWidget::addNewDialog() { QFile templateUi(":/templates/templates/Dialog.ui"); templateUi.open(QIODevice::ReadOnly|QIODevice::Text); QString templateStr = templateUi.readAll(); QString dialogName = m_report->scriptContext()->getNewDialogName(); templateStr.replace("$ClassName$", dialogName); m_report->scriptContext()->addDialog(dialogName,templateStr.toUtf8()); createNewDialogTab(dialogName, templateStr.toUtf8()); } void ReportDesignWidget::slotDialogChanged(QString ) { m_dialogChanged = true; } void ReportDesignWidget::slotDialogNameChanged(QString oldName, QString newName) { for (int i = 0; i < m_tabWidget->count(); ++i){ if (m_tabWidget->tabText(i).compare(oldName) == 0) m_tabWidget->setTabText(i, newName); } m_report->scriptContext()->changeDialogName(oldName, newName); } #endif bool ReportDesignWidget::eventFilter(QObject *target, QEvent *event) { if (event->type() == QEvent::Wheel){ QWheelEvent* we = dynamic_cast(event); if (QApplication::keyboardModifiers()==Qt::ControlModifier){ if(we->delta()<0) scale(1.2,1.2); else scale(1/1.2,1/1.2); } } return QWidget::eventFilter(target,event); } void ReportDesignWidget::clear() { m_report->clearReport(); m_tabWidget->clear(); m_report->setReportFileName(""); m_report->scriptContext()->setInitScript(""); m_scriptEditor->setPlainText(""); } }