Line data Source code
1 : #include <QPainter> 2 : #include <QPrintDialog> 3 : #include <QPrintPreviewWidget> 4 : #include <QPrintPreviewDialog> 5 : #include "parsers/parserfromxml.hpp" 6 : #include "converters/convertertopdf.hpp" 7 : #include "converters/convertertohtml.hpp" 8 : #include "engine.hpp" 9 : #include <QDebug> 10 : 11 : namespace qtreports 12 : { 13 : 14 22 : Engine::Engine( QObject * parent ) : 15 : QObject( parent ), 16 22 : m_isOpened( false ) 17 22 : {} 18 : 19 3 : Engine::Engine( const QString & path, QObject * parent ) : 20 3 : Engine( parent ) 21 : { 22 3 : open( path ); 23 3 : } 24 : 25 22 : Engine::~Engine() {} 26 : 27 24 : bool Engine::open( const QString & path ) 28 : { 29 24 : if( isOpened() ) 30 : { 31 2 : close(); 32 : } 33 : 34 48 : detail::ParserFromXML parser; 35 24 : if( !parser.parse( path ) ) 36 : { 37 3 : m_lastError = "Parsing error: " + parser.getLastError(); 38 3 : return false; 39 : } 40 : 41 21 : m_isOpened = true; 42 21 : m_compiledPath = path; 43 21 : m_report = parser.getReport(); 44 : 45 : //fillColumnsFromReport(); //MB as ProcessedDB::createColumns( ReportPtr ) 46 : 47 21 : return true; 48 : } 49 : 50 3 : void Engine::close() 51 : { 52 3 : m_isOpened = false; 53 3 : m_compiledPath.clear(); 54 3 : m_report.clear(); 55 3 : } 56 : 57 5 : bool Engine::setParameters( const QMap< QString, QVariant > & parameters ) 58 : { 59 5 : if( m_report.isNull() ) 60 : { 61 1 : m_lastError = "Report is empty. Please open report file"; 62 1 : return false; 63 : } 64 : 65 4 : m_report->setParameters( parameters ); 66 : 67 4 : return true; 68 : } 69 : 70 13 : bool Engine::setConnection( const QSqlDatabase & connection ) 71 : { 72 13 : if( !connection.isOpen() ) 73 : { 74 2 : m_lastError = "Connection not open"; 75 2 : return false; 76 : } 77 : 78 11 : if( m_report.isNull() ) 79 : { 80 0 : m_lastError = "Report is empty. Please open report file"; 81 0 : return false; 82 : } 83 : 84 11 : m_dbConnection = connection; 85 : 86 11 : if( !prepareDB() ) 87 : { 88 0 : m_lastError = "Error in prepare db process: " + m_lastError; 89 0 : return false; 90 : } 91 : 92 : //m_report->setRowCount( db.getMaxRowCount() ); 93 : /* 94 : for( auto && field : m_report->getFields() ) 95 : { 96 : auto name = field->getName(); 97 : auto value = db.getColumn( name ); 98 : m_report->setFieldData( name, value ); 99 : } 100 : 101 : db.setParameters( m_report->getParameters() ); 102 : */ 103 11 : return true; 104 : } 105 : 106 1 : bool Engine::setDataSource( const QMap< QString, QVector< QVariant > > & source ) 107 : { 108 : //Need check parameters 109 : //m_dataSource = columnsSet; 110 : 111 : //detail::ProcessedDB db; 112 1 : if( !prepareDataSource( source ) ) 113 : { 114 0 : m_lastError = "Error in prepare data source: " + m_lastError; 115 0 : return false; 116 : } 117 : 118 : //m_report->setRowCount( db.getMaxRowCount() ); 119 : /* 120 : for( auto && field : m_report->getFields() ) 121 : { 122 : auto name = field->getName(); 123 : auto value = db.getColumn( name ); 124 : m_report->setFieldData( name, value ); 125 : } 126 : */ 127 1 : return true; 128 : } 129 : 130 12 : bool Engine::setQuery( const QString & query ) 131 : { 132 : //Need check parameters 133 : 134 24 : QStringList queries = query.split( ";", QString::SkipEmptyParts ); 135 24 : QMap< QString, QVariant > param = m_report->getParameters(); 136 : 137 27 : for (int i = 0; i < queries.size(); i++) { 138 21 : for (auto it = param.begin(); it != param.end(); it++) { 139 : 140 12 : QString find = "$P{" + it.key() + "}"; 141 12 : QString to = "'" + it.value().toString() + "'"; 142 6 : if(queries[i].indexOf(find)!=-1) 143 0 : queries[i] = queries[i].replace(find, to); 144 : } 145 : } 146 : 147 24 : return executeQueries(queries); 148 : } 149 : 150 1 : bool Engine::addScript( const QString & script ) 151 : { 152 : //Need check parameters 153 1 : m_scripts.append( script ); 154 : 155 1 : return true; 156 : } 157 : 158 1 : bool Engine::setDataModel( const QAbstractItemModel & model ) 159 : { 160 : //Need check parameters 161 : Q_UNUSED( model ); 162 1 : return true; 163 : } 164 : 165 2 : bool Engine::createPDF( const QString & path ) 166 : { 167 2 : if( m_report.isNull() ) 168 : { 169 1 : m_lastError = "Report is empty. Please open report file"; 170 1 : return false; 171 : } 172 : 173 2 : detail::ConverterToPDF converter( m_report ); 174 1 : auto result = converter.convert( path ); 175 1 : if( !result ) 176 : { 177 0 : m_lastError = converter.getLastError(); 178 0 : return false; 179 : } 180 : 181 1 : return true; 182 : } 183 : 184 2 : bool Engine::createHTML( const QString & path ) 185 : { 186 2 : if( m_report.isNull() ) 187 : { 188 1 : m_lastError = "Report is empty. Please open report file"; 189 1 : return false; 190 : } 191 : 192 2 : detail::ConverterToHTML converter( m_report ); 193 1 : auto result = converter.convert( path ); 194 1 : if( !result ) 195 : { 196 0 : m_lastError = converter.getLastError(); 197 0 : return false; 198 : } 199 : 200 1 : return true; 201 : } 202 : 203 2 : QWidgetPtr Engine::createWidget() 204 : { 205 2 : if( m_report.isNull() ) 206 : { 207 1 : m_lastError = "Report is empty. Please open report file"; 208 1 : return QWidgetPtr(); 209 : } 210 : 211 2 : detail::ConverterToQWidget converter( m_report ); 212 1 : auto result = converter.convert( detail::ConverterToQWidget::WidgetType::Report ); 213 1 : if( !result ) 214 : { 215 0 : m_lastError = converter.getLastError(); 216 0 : return QWidgetPtr(); 217 : } 218 : 219 1 : return converter.getQWidget(); 220 : } 221 : 222 2 : QWidgetPtr Engine::createLayout() 223 : { 224 2 : if( m_report.isNull() ) 225 : { 226 1 : m_lastError = "Report is empty. Please open report file"; 227 1 : return QWidgetPtr(); 228 : } 229 : 230 2 : detail::ConverterToQWidget converter( m_report ); 231 1 : auto result = converter.convert( detail::ConverterToQWidget::WidgetType::Layout ); 232 1 : if( !result ) 233 : { 234 0 : m_lastError = converter.getLastError(); 235 0 : return QWidgetPtr(); 236 : } 237 : 238 1 : return converter.getQWidget(); 239 : } 240 : 241 1 : bool Engine::print() 242 : { 243 1 : if( m_report.isNull() ) 244 : { 245 1 : m_lastError = "Report is empty. Please open report file"; 246 1 : return false; 247 : } 248 : 249 0 : if (!prepareDB()) 250 0 : return false; 251 : 252 0 : QPrinter printer; 253 0 : QPrintPreviewDialog preview( &printer ); 254 : connect( 255 : &preview, &QPrintPreviewDialog::paintRequested, 256 : this, &Engine::drawPreview 257 0 : ); 258 0 : preview.exec(); 259 : 260 0 : return true; 261 : } 262 : 263 0 : void Engine::drawPreview( QPrinter * printer ) 264 : { 265 0 : auto temp = m_report->getOrientation(); 266 0 : m_report->setOrientation( printer->orientation() ); 267 0 : detail::ConverterToQWidget converter( m_report ); 268 0 : auto result = converter.convert( detail::ConverterToQWidget::WidgetType::Report ); 269 0 : m_report->setOrientation( temp ); 270 0 : if( !result ) 271 : { 272 0 : m_lastError = converter.getLastError(); 273 0 : return; 274 : } 275 : 276 0 : auto widgets = converter.getPages(); 277 0 : if( widgets.isEmpty() ) 278 : { 279 0 : m_lastError = "Cannot print widget: all pages is empty"; 280 0 : return; 281 : } 282 : 283 0 : auto widget = widgets.value( 0 ); 284 : 285 0 : QRectF rect = printer->pageRect(); 286 0 : QPainter painter( printer ); 287 0 : qreal scale = rect.width() / widget->width(); 288 : 289 0 : widget->resize( widget->width(), rect.height() / scale ); 290 0 : painter.scale( scale, scale ); 291 : 292 0 : for( int i = 0; i < widgets.size(); ++i ) 293 : { 294 0 : i != 0 ? printer->newPage() : 0; 295 0 : widget = widgets.value( i ); 296 0 : if( widget.isNull() ) 297 : { 298 0 : m_lastError = "Error in print process: printed widget is empty"; 299 0 : return; 300 : } 301 : 302 : //Magic 303 0 : widget->show(); 304 0 : widget->hide(); 305 0 : widget->render( &painter ); 306 : } 307 : } 308 : 309 11 : bool Engine::prepareDB() 310 : { 311 11 : return setQuery( m_report->getQuery() ); 312 : } 313 : 314 13 : bool Engine::prepareDataSource( const QMap< QString, QVector< QVariant > > & source ) 315 : { 316 26 : QMapIterator< QString, QVector< QVariant > > iterator( source ); 317 13 : if (!iterator.hasNext()) 318 : { 319 0 : m_lastError = "Query has not rerurned result"; 320 0 : return false; 321 : } 322 : 323 95 : while( iterator.hasNext() ) 324 : { 325 41 : iterator.next(); 326 82 : auto field = m_report->getField( iterator.key() ); 327 41 : if( field.isNull() ) 328 : { 329 0 : m_lastError = "Report not have column: " + iterator.key(); 330 0 : return false; 331 : } 332 : 333 41 : field->setData( iterator.value() ); 334 : } 335 : 336 13 : return true; 337 : } 338 : 339 : //void Engine::fillColumnsFromReport() 340 : //{ 341 : // for( auto && field : m_report->getFields() ) 342 : // { 343 : // db.addEmptyColumn( field->getName() ); 344 : // } 345 : //} 346 : 347 12 : bool Engine::executeQueries( const QStringList & queries ) 348 : { 349 24 : QMap< QString, QVector< QVariant > > data; 350 24 : QSqlQueryModel model; 351 27 : for( auto && query : queries ) 352 : { 353 15 : model.setQuery( query, m_dbConnection ); 354 : 355 90 : for( int row = 0; row < model.rowCount(); row++ ) 356 : { 357 150 : QSqlRecord rec = model.record( row ); 358 300 : for( int col = 0; col < rec.count(); col++ ) 359 : { 360 450 : auto columnName = rec.fieldName( col ); 361 450 : auto fieldValue = rec.field( col ).value(); 362 : //db.appendColumnData( columnName, fieldValue ); 363 225 : data[ columnName ].append( fieldValue ); 364 : } 365 : } 366 : } 367 : 368 24 : return prepareDataSource( data ); 369 : } 370 : 371 31 : bool Engine::isOpened() const 372 : { 373 31 : return m_isOpened; 374 : } 375 : 376 5 : detail::ReportPtr Engine::getReport() const 377 : { 378 5 : return m_report; 379 : } 380 : 381 46 : const QString Engine::getLastError() const 382 : { 383 46 : return m_lastError; 384 : } 385 : 386 : }