LCOV - code coverage report
Current view: top level - qtreportslib/converters - convertertoqwidget.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 200 245 81.6 %
Date: 2019-02-16 04:31:57 Functions: 19 19 100.0 %

          Line data    Source code
       1             : #include <QFrame>
       2             : #include <QLabel>
       3             : #include <QPainter>
       4             : #include "utils/replacer.hpp"
       5             : #include "convertertoqwidget.hpp"
       6             : #include <QDebug>
       7             : 
       8             : namespace qtreports
       9             : {
      10             :     namespace detail
      11             :     {
      12             : 
      13          13 :         ConverterToQWidget::ConverterToQWidget( const ReportPtr & report ) :
      14             :             m_report( report ),
      15             :             m_type( WidgetType::Report ),
      16          13 :             m_currentHeight( 0 )
      17          13 :         {}
      18             : 
      19          13 :         ConverterToQWidget::~ConverterToQWidget() {}
      20             : 
      21           6 :         bool    ConverterToQWidget::convert( WidgetType type )
      22             :         {
      23           6 :             m_type = type;
      24           6 :             return createQWidget( m_report );
      25             :         }
      26             : 
      27           9 :         bool    ConverterToQWidget::isReport() const
      28             :         {
      29           9 :             return m_type == WidgetType::Report;
      30             :         }
      31             : 
      32         594 :         bool    ConverterToQWidget::isLayout() const
      33             :         {
      34         594 :             return m_type == WidgetType::Layout;
      35             :         }
      36             : 
      37           3 :         ConverterToQWidget::WidgetType  ConverterToQWidget::getType() const
      38             :         {
      39           3 :             return m_type;
      40             :         }
      41             : 
      42           7 :         const QWidgetPtr    ConverterToQWidget::getQWidget() const
      43             :         {
      44           7 :             return m_qwidget;
      45             :         }
      46             : 
      47           3 :         const QWidgetPtr    ConverterToQWidget::getPage( int i ) const
      48             :         {
      49           3 :             return m_pages.value( i );
      50             :         }
      51             : 
      52           3 :         const QVector< QWidgetPtr >     ConverterToQWidget::getPages() const
      53             :         {
      54           3 :             return m_pages;
      55             :         }
      56             : 
      57           5 :         const QString       ConverterToQWidget::getLastError() const
      58             :         {
      59           5 :             return m_lastError;
      60             :         }
      61             : 
      62          21 :         QHBoxLayout * createLayout( QWidget * left, QWidget * center, QWidget * right )
      63             :         {
      64          21 :             auto layout = new QHBoxLayout();
      65          21 :             layout->setMargin( 0 );
      66          21 :             layout->setSpacing( 0 );
      67             : 
      68          21 :             layout->addWidget( left );
      69          21 :             layout->addWidget( center );
      70          21 :             layout->addWidget( right );
      71             : 
      72          21 :             return layout;
      73             :         }
      74             : 
      75          12 :         void    ConverterToQWidget::addVerticalBorder( QBoxLayout * parent, const QMargins & margins, int height )
      76             :         {
      77          12 :             auto leftFrame = new QFrame();
      78          12 :             leftFrame->setFixedWidth( margins.left() );
      79          12 :             leftFrame->setFixedHeight( height );
      80             : 
      81          12 :             auto centerFrame = new QFrame();
      82          12 :             centerFrame->setFixedHeight( height );
      83             : 
      84          12 :             auto rightFrame = new QFrame();
      85          12 :             rightFrame->setFixedWidth( margins.right() );
      86          12 :             rightFrame->setFixedHeight( height );
      87             : 
      88          12 :             if( isLayout() )
      89             :             {
      90           8 :                 QString style = "border: 1px solid gray; ";
      91           4 :                 leftFrame->setStyleSheet( style + "border-width: 0px 1px 0px 0px; " );
      92           4 :                 rightFrame->setStyleSheet( style + "border-width: 0px 0px 0px 1px; " );
      93             :             }
      94             : 
      95          12 :             auto layout = createLayout( leftFrame, centerFrame, rightFrame );
      96          12 :             parent->addLayout( layout );
      97          12 :         }
      98             : 
      99           6 :         void    ConverterToQWidget::addEmptySection( QBoxLayout * parent, const QMargins & margins )
     100             :         {
     101           6 :             auto leftFrame = new QFrame();
     102           6 :             leftFrame->setFixedWidth( margins.left() );
     103             : 
     104           6 :             auto centerFrame = new QFrame();
     105             : 
     106           6 :             auto rightFrame = new QFrame();
     107           6 :             rightFrame->setFixedWidth( margins.right() );
     108             : 
     109           6 :             if( isLayout() )
     110             :             {
     111           4 :                 QString style = "border: 1px solid gray; ";
     112           2 :                 leftFrame->setStyleSheet( style + "border-width: 1px 1px 1px 0px; " );
     113           2 :                 centerFrame->setObjectName( "frame" );
     114           2 :                 centerFrame->setStyleSheet( "#frame{" + style + "border-width: 1px 0px 1px 0px; }" );
     115           2 :                 rightFrame->setStyleSheet( style + "border-width: 1px 0px 1px 1px; " );
     116             :             }
     117             : 
     118           6 :             auto layout = createLayout( leftFrame, centerFrame, rightFrame );
     119           6 :             parent->addLayout( layout );
     120           6 :         }
     121             : 
     122           3 :         QFrame *    ConverterToQWidget::addSectionLayout( QBoxLayout * parent, const QMargins & margins, int height )
     123             :         {
     124           3 :             auto leftFrame = new QFrame();
     125           3 :             leftFrame->setFixedHeight( height );
     126           3 :             leftFrame->setFixedWidth( margins.left() );
     127             : 
     128           3 :             auto centerFrame = new QFrame();
     129           3 :             centerFrame->setFixedHeight( height );
     130             : 
     131             : 
     132             : 
     133           3 :             auto rightFrame = new QFrame();
     134           3 :             rightFrame->setFixedHeight( height );
     135           3 :             rightFrame->setFixedWidth( margins.right() );
     136             : 
     137           3 :             if( isLayout() )
     138             :             {
     139           6 :                 QString style = "border: 1px solid gray; ";
     140           3 :                 leftFrame->setStyleSheet( style + "border-width: 1px 1px 0px 0px; " );
     141           3 :                 centerFrame->setObjectName( "frame" );
     142           3 :                 centerFrame->setStyleSheet( "#frame{" + style + "border-width: 1px 0px 0px 0px; }" );
     143           3 :                 rightFrame->setStyleSheet( style + "border-width: 1px 0px 0px 1px; " );
     144             :             }
     145             : 
     146           3 :             auto layout = createLayout( leftFrame, centerFrame, rightFrame );
     147           3 :             parent->addLayout( layout );
     148             : 
     149           3 :             return centerFrame;
     150             :         }
     151             : 
     152          41 :         void    ConverterToQWidget::addPage()
     153             :         {
     154          82 :             QWidgetPtr widget( new QWidget() );
     155          41 :             widget->resize( m_report->getSize() );
     156          41 :             widget->setStyleSheet( "background-color: white; " );
     157          41 :             m_pages.append( widget );
     158          41 :         }
     159             : 
     160           6 :         bool    ConverterToQWidget::createQWidget( const ReportPtr & report )
     161             :         {
     162           6 :             if( report.isNull() )
     163             :             {
     164           0 :                 m_lastError = "Report is empty";
     165           0 :                 return false;
     166             :             }
     167             : 
     168          12 :             auto detail = report->getDetail();
     169           6 :             if( detail.isNull() )
     170             :             {
     171           0 :                 m_lastError = "Report->Detail is empty";
     172           0 :                 return false;
     173             :             }
     174             : 
     175           6 :             m_qwidget = QWidgetPtr( new QWidget() );
     176           6 :             m_qwidget->setStyleSheet( "background-color: white; " );//border: 1px solid gray; 
     177             :             //m_qwidget->setContentsMargins( m_report->getMargins() );
     178             : 
     179           6 :             addPage();
     180             : 
     181           6 :             auto layout = new QVBoxLayout( m_qwidget.data() );
     182           6 :             layout->setMargin( 0 );
     183           6 :             layout->setSpacing( 0 );
     184           6 :             addVerticalBorder( layout, report->getMargins(), report->getTopMargin() );
     185             : 
     186          12 :             auto title = report->getTitle();
     187           6 :             if( !title.isNull() )
     188             :             {
     189           3 :                 QWidget * sectionWidget = isLayout() ? addSectionLayout( layout, report->getMargins(), title->getHeight() ) : nullptr;
     190           3 :                 if( !createSection( sectionWidget, title, 0 ) )
     191             :                 {
     192           0 :                     return false;
     193             :                 }
     194             :             }
     195             : 
     196           6 :             if(!addGroupsIntoReport(report, detail, layout))
     197           0 :                 return false;
     198             : 
     199           6 :             addEmptySection( layout, report->getMargins() );
     200           6 :             addVerticalBorder( layout, report->getMargins(), report->getBottomMargin() );
     201           6 :             return true;
     202             :         }
     203             : 
     204           6 :         bool ConverterToQWidget::addGroupsIntoReport(const ReportPtr & report, const DetailPtr & detail, QVBoxLayout* layout)
     205             :         {
     206          12 :             detail::Replacer replacer;
     207             : 
     208          12 :             QList<GroupPtr> groups = report->getGroups().values();
     209          12 :             QList<QString> groupNames;
     210             :             //Сюда помещаем конкретные имена по которым группируем
     211           6 :                         QString *particularNames = new QString[groups.length()];
     212           6 :             for (int i = 0; i<groups.length(); i++)
     213             :             {
     214           0 :                 groupNames.append(groups[i]
     215           0 :                     ->getHeader()
     216           0 :                     ->getBand(0)
     217           0 :                     ->getTextField(0)
     218           0 :                     ->getOriginalText());
     219           0 :                 particularNames[i] = replacer.replaceField(groupNames[i], report, 0);
     220             :             }
     221             :             //Открываем хедеры групп
     222           6 :             for (int i = 0; i<groups.length(); i++)
     223             :             {
     224           0 :                 auto header = groups[i]->getHeader();
     225           0 :                 if (!header.isNull())
     226             :                 {
     227           0 :                     QWidget * sectionWidget = isLayout() ? addSectionLayout(layout, report->getMargins(), header->getHeight()) : nullptr;
     228           0 :                     if (!createSection(sectionWidget, header, 0))
     229             :                     {
     230           0 :                         return false;
     231             :                     }
     232             :                 }
     233             :             }
     234             : 
     235           6 :             int rowCount = isReport()? report->getRowCount() : 1;
     236          38 :             for(int i = 0; i < rowCount; i++)
     237             :             {
     238          32 :                 QWidget * sectionWidget = isLayout() ? sectionWidget = addSectionLayout(layout, report->getMargins(), detail->getHeight()) : nullptr;
     239             : 
     240             :                 //Закрываем футеры, если группа закончилась
     241          32 :                 for(int j = groups.length() - 1; j >= 0; j--)
     242             :                 {
     243             :                     //сверяем поле в заголовке и текущее поле
     244           0 :                     if(particularNames[j] != replacer.replaceField(groupNames[j], report, i))
     245             :                     {
     246           0 :                         auto footer = report->getGroupByIndex(j)->getFooter();
     247           0 :                         if (!footer.isNull())
     248             :                         {
     249           0 :                             QWidget * sectionWidgetFooter = isLayout() ? addSectionLayout(layout, report->getMargins(), footer->getHeight()) : nullptr;
     250           0 :                             if (!createSection(sectionWidgetFooter, footer, i - 1))
     251             :                             {
     252           0 :                                 return false;
     253             :                             }
     254             :                         }
     255             :                     }
     256             :                 }
     257             :                 //Аналогично открываем хедеры
     258          32 :                 for(int j = 0; j < groupNames.length(); j++)
     259             :                 {                    
     260             :                     //сверяем поле в заголовке и текущее поле
     261           0 :                     if(particularNames[j] != replacer.replaceField(groupNames[j], report, i))
     262             :                     {
     263           0 :                         auto header = report->getGroupByIndex(j)->getHeader();
     264           0 :                         if (!header.isNull())
     265             :                         {
     266           0 :                             QWidget * sectionWidgetHeader = isLayout() ? addSectionLayout(layout, report->getMargins(), header->getHeight()) : nullptr;
     267           0 :                             if (!createSection(sectionWidgetHeader, header, i))
     268             :                             {
     269           0 :                                 return false;
     270             :                             }
     271             :                         }
     272             :                     }
     273             :                 }
     274             :                 //Переписываем имена для сравнения
     275          32 :                 for(int j = 0; j < groupNames.length(); j++)
     276             :                 {
     277           0 :                     particularNames[j] = replacer.replaceField(groupNames[j], report, i);
     278             :                 }
     279             :                 //Выводим поле
     280          32 :                 if (!createSection(sectionWidget, detail, i))
     281             :                 {
     282           0 :                     return false;
     283             :                 }
     284             :             }
     285             :             //Закрываем хедеры групп
     286           6 :             for(int i = groups.length() - 1; i >= 0; i--)
     287             :             {
     288           0 :                 auto footer = groups[i]->getFooter();
     289           0 :                             if (!footer.isNull())
     290             :                             {
     291           0 :                                 QWidget * sectionWidget = isLayout() ? addSectionLayout(layout, report->getMargins(), footer->getHeight()) : nullptr;
     292           0 :                                 if (!createSection(sectionWidget, footer, (rowCount - 1)))
     293             :                                 {
     294           0 :                                     return false;
     295             :                                 }
     296             :                             }
     297             :             }
     298           6 :             return true;
     299             :         }
     300             : 
     301             : 
     302          35 :         bool    ConverterToQWidget::createSection( QWidget * parent, const SectionPtr & section, int i )
     303             :         {
     304          35 :             if( isLayout() )
     305             :             {
     306           3 :                 auto label = new QLabel( parent );
     307           3 :                 label->setText( section->getTagName() );
     308           3 :                 label->setStyleSheet( "font-size: 26px; color: gray" );
     309           3 :                 label->setAlignment( Qt::AlignCenter );
     310           3 :                 label->setAttribute( Qt::WA_TranslucentBackground );
     311           3 :                 label->resize( parent->size() );
     312             :             }
     313             :             else
     314             :             {
     315          64 :                 detail::Replacer replacer;
     316          32 :                 if( !replacer.replace( section, m_report, i ) )
     317             :                 {
     318           0 :                     m_lastError = "Error in replacing process: " + replacer.getLastError();
     319           0 :                     return false;
     320             :                 }
     321             :             }
     322             : 
     323          35 :             if( !createBands( parent, section ) )
     324             :             {
     325           0 :                 return false;
     326             :             }
     327             : 
     328          35 :             return true;
     329             :         }
     330             : 
     331          35 :         bool    ConverterToQWidget::createBands( QWidget * parent, const SectionPtr & section )
     332             :         {
     333          35 :             auto dy = 0;
     334         116 :             for( auto && band : section->getBands() )
     335             :             {
     336          81 :                 if( m_currentHeight + band->getHeight() > m_report->getHeight() )
     337             :                 {
     338          35 :                     addPage();
     339          35 :                     m_currentHeight = 0;
     340             :                 }
     341             : 
     342          81 :                 auto frame = new QFrame( isLayout() ? parent : m_pages.last().data() );
     343          81 :                 frame->setStyleSheet( "background-color: transparent; " );
     344          81 :                 frame->move( frame->x(), isLayout() ? dy : m_currentHeight );
     345             : 
     346          81 :                 m_currentHeight += band->getHeight();
     347          81 :                 dy += band->getHeight();
     348             : 
     349         224 :                 for( auto && textWidget : band->getTextWidgets() )
     350             :                 {
     351         143 :                     auto label = new QLabel( frame );
     352         286 :                     QString style = "";
     353         143 :                     if( textWidget->isBold() )
     354             :                     {
     355          98 :                         style += "font-weight: bold; ";
     356             :                     }
     357         143 :                     if( isLayout() )
     358             :                     {
     359          11 :                         style += "border: 1px solid gray; ";
     360             :                     }
     361         143 :                     label->setStyleSheet( "background-color: transparent; " + style );
     362         143 :                     label->setGeometry( textWidget->getRect() );
     363         143 :                     label->setAlignment( textWidget->getAlignment() );
     364         286 :                     auto text = isLayout() ? textWidget->getOriginalText() : textWidget->getText();
     365         143 :                     label->setText( text );
     366             :                 }
     367         107 :                 for( auto && line : band->getLines() )
     368             :                 {
     369          26 :                     auto label = new QLabel( frame );
     370          52 :                     QString style = "";
     371          26 :                     if( line->isBold() )
     372             :                     {
     373          26 :                         style += "font-weight: bold; ";
     374             :                     }
     375             :                     //if( isLayout() )
     376             :                     {
     377          26 :                         style += "border: 1px solid gray; ";
     378             :                     }
     379          26 :                     label->setStyleSheet( "background-color: transparent; " + style );
     380          26 :                     label->setGeometry( line->getRect() );
     381          26 :                     label->setAlignment( line->getAlignment() );
     382             :                     //label->setText( "----------------------" );
     383             :                 }
     384         107 :                 for( auto && imageWidget : band->getImages() )
     385             :                 {
     386          26 :                     if( imageWidget->getRect().isEmpty() )
     387             :                     {
     388           0 :                         m_lastError = "Ellipse \"" + imageWidget->getName() + "\" rect is empty";
     389           0 :                         return false;
     390             :                     }
     391             : 
     392          26 :                     auto label = new QLabel( frame );
     393          52 :                     QString style = "";
     394          26 :                     if( isLayout() )
     395             :                     {
     396           2 :                         style += "border: 1px solid gray; ";
     397             :                     }
     398          26 :                     label->setStyleSheet( "background-color: transparent; " + style );
     399          26 :                     label->setGeometry( imageWidget->getRect() );
     400          26 :                     label->setAlignment( imageWidget->getAlignment() );
     401          26 :                     label->setPixmap( QPixmap::fromImage( imageWidget->getImage() ) );
     402             :                 }
     403         107 :                 for( auto && rect : band->getRects() )
     404             :                 {
     405          26 :                     if( rect->getRect().isEmpty() )
     406             :                     {
     407           0 :                         m_lastError = "Rect \"" + rect->getName() + "\" rect is empty";
     408           0 :                         return false;
     409             :                     }
     410             : 
     411          26 :                     auto label = new QLabel( frame );
     412          52 :                     QString style = "";
     413          26 :                     if( rect->isBold() )
     414             :                     {
     415          26 :                         style += "font-weight: bold; ";
     416             :                     }
     417             :                     //if( isLayout() )
     418             :                     {
     419          26 :                         style += "border: 1px solid gray; ";
     420             :                     }
     421          26 :                     label->setStyleSheet( "background-color: transparent; " + style );
     422          26 :                     label->setGeometry( rect->getRect() );
     423          26 :                     label->setAlignment( rect->getAlignment() );
     424             :                     //label->setText( "----------------------" );
     425             :                 }
     426         107 :                 for( auto && ellipse : band->getEllipses() )
     427             :                 {
     428          26 :                     if( ellipse->getSize().isEmpty() )
     429             :                     {
     430           0 :                         m_lastError = "Ellipse \"" + ellipse->getName() + "\" size is empty";
     431           0 :                         return false;
     432             :                     }
     433             : 
     434          26 :                     auto label = new QLabel( frame );
     435          52 :                     QString style = "";
     436          26 :                     if( isLayout() )
     437             :                     {
     438           2 :                         style += "border: 1px solid gray; ";
     439             :                     }
     440             : 
     441          52 :                     QPixmap pixmap( ellipse->getSize() );
     442          26 :                     pixmap.fill( Qt::GlobalColor::transparent );
     443             : 
     444          52 :                     QPainter painter( &pixmap );
     445          26 :                     painter.setRenderHint( QPainter::Antialiasing );
     446          26 :                     painter.drawEllipse( ellipse->getRect() );
     447          26 :                     painter.end();
     448          26 :                     label->setPixmap( pixmap );
     449             : 
     450          26 :                     label->setStyleSheet( "background-color: transparent; " + style );
     451          26 :                     label->setGeometry( ellipse->getRect() );
     452          26 :                     label->setAlignment( ellipse->getAlignment() );
     453             :                 }
     454             :             }
     455             : 
     456          35 :             return true;
     457             :         }
     458             : 
     459             :     }
     460             : }

Generated by: LCOV version 1.13-24-g0433563