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 24 : 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 12 : auto queries = query.split( ";", QString::SkipEmptyParts );
134 12 : return executeQueries( queries );
135 :
136 : //m_lastError = query;
137 : //return true;
138 : }
139 :
140 1 : bool Engine::addScript( const QString & script )
141 : {
142 : //Need check parameters
143 1 : m_scripts.append( script );
144 :
145 1 : return true;
146 : }
147 :
148 1 : bool Engine::setDataModel( const QAbstractItemModel & model )
149 : {
150 : //Need check parameters
151 : Q_UNUSED( model );
152 1 : return true;
153 : }
154 :
155 2 : bool Engine::createPDF( const QString & path )
156 : {
157 2 : if( m_report.isNull() )
158 : {
159 1 : m_lastError = "Report is empty. Please open report file";
160 1 : return false;
161 : }
162 :
163 1 : detail::ConverterToPDF converter( m_report );
164 1 : auto result = converter.convert( path );
165 1 : if( !result )
166 : {
167 0 : m_lastError = converter.getLastError();
168 0 : return false;
169 : }
170 :
171 1 : return true;
172 : }
173 :
174 2 : bool Engine::createHTML( const QString & path )
175 : {
176 2 : if( m_report.isNull() )
177 : {
178 1 : m_lastError = "Report is empty. Please open report file";
179 1 : return false;
180 : }
181 :
182 1 : detail::ConverterToHTML converter( m_report );
183 1 : auto result = converter.convert( path );
184 1 : if( !result )
185 : {
186 0 : m_lastError = converter.getLastError();
187 0 : return false;
188 : }
189 :
190 1 : return true;
191 : }
192 :
193 2 : QWidgetPtr Engine::createWidget()
194 : {
195 2 : if( m_report.isNull() )
196 : {
197 1 : m_lastError = "Report is empty. Please open report file";
198 1 : return QWidgetPtr();
199 : }
200 :
201 1 : detail::ConverterToQWidget converter( m_report );
202 1 : auto result = converter.convert( detail::ConverterToQWidget::WidgetType::Report );
203 1 : if( !result )
204 : {
205 0 : m_lastError = converter.getLastError();
206 0 : return QWidgetPtr();
207 : }
208 :
209 1 : return converter.getQWidget();
210 : }
211 :
212 2 : QWidgetPtr Engine::createLayout()
213 : {
214 2 : if( m_report.isNull() )
215 : {
216 1 : m_lastError = "Report is empty. Please open report file";
217 1 : return QWidgetPtr();
218 : }
219 :
220 1 : detail::ConverterToQWidget converter( m_report );
221 1 : auto result = converter.convert( detail::ConverterToQWidget::WidgetType::Layout );
222 1 : if( !result )
223 : {
224 0 : m_lastError = converter.getLastError();
225 0 : return QWidgetPtr();
226 : }
227 :
228 1 : return converter.getQWidget();
229 : }
230 :
231 1 : bool Engine::print()
232 : {
233 1 : if( m_report.isNull() )
234 : {
235 1 : m_lastError = "Report is empty. Please open report file";
236 1 : return false;
237 : }
238 :
239 0 : if (!prepareDB())
240 0 : return false;
241 :
242 0 : QPrinter printer;
243 0 : QPrintPreviewDialog preview( &printer );
244 : connect(
245 : &preview, &QPrintPreviewDialog::paintRequested,
246 : this, &Engine::drawPreview
247 0 : );
248 0 : preview.exec();
249 :
250 0 : return true;
251 : }
252 :
253 0 : void Engine::drawPreview( QPrinter * printer )
254 : {
255 0 : auto temp = m_report->getOrientation();
256 0 : m_report->setOrientation( printer->orientation() );
257 0 : detail::ConverterToQWidget converter( m_report );
258 0 : auto result = converter.convert( detail::ConverterToQWidget::WidgetType::Report );
259 0 : m_report->setOrientation( temp );
260 0 : if( !result )
261 : {
262 0 : m_lastError = converter.getLastError();
263 0 : return;
264 : }
265 :
266 0 : auto widgets = converter.getPages();
267 0 : if( widgets.isEmpty() )
268 : {
269 0 : m_lastError = "Cannot print widget: all pages is empty";
270 0 : return;
271 : }
272 :
273 0 : auto widget = widgets.value( 0 );
274 :
275 0 : QRectF rect = printer->pageRect();
276 0 : QPainter painter( printer );
277 0 : qreal scale = rect.width() / widget->width();
278 :
279 0 : widget->resize( widget->width(), rect.height() / scale );
280 0 : painter.scale( scale, scale );
281 :
282 0 : for( int i = 0; i < widgets.size(); ++i )
283 : {
284 0 : i != 0 ? printer->newPage() : 0;
285 0 : widget = widgets.value( i );
286 0 : if( widget.isNull() )
287 : {
288 0 : m_lastError = "Error in print process: printed widget is empty";
289 0 : return;
290 : }
291 :
292 : //Magic
293 0 : widget->show();
294 0 : widget->hide();
295 0 : widget->render( &painter );
296 0 : }
297 : }
298 :
299 11 : bool Engine::prepareDB()
300 : {
301 11 : return setQuery( m_report->getQuery() );
302 : }
303 :
304 13 : bool Engine::prepareDataSource( const QMap< QString, QVector< QVariant > > & source )
305 : {
306 13 : QMapIterator< QString, QVector< QVariant > > iterator( source );
307 13 : if (!iterator.hasNext())
308 : {
309 0 : m_lastError = "Query has not rerurned result";
310 0 : return false;
311 : }
312 :
313 67 : while( iterator.hasNext() )
314 : {
315 41 : iterator.next();
316 41 : auto field = m_report->getField( iterator.key() );
317 41 : if( field.isNull() )
318 : {
319 0 : m_lastError = "Report not have column: " + iterator.key();
320 0 : return false;
321 : }
322 :
323 41 : field->setData( iterator.value() );
324 41 : }
325 :
326 13 : return true;
327 : }
328 :
329 : //void Engine::fillColumnsFromReport()
330 : //{
331 : // for( auto && field : m_report->getFields() )
332 : // {
333 : // db.addEmptyColumn( field->getName() );
334 : // }
335 : //}
336 :
337 12 : bool Engine::executeQueries( const QStringList & queries )
338 : {
339 12 : QMap< QString, QVector< QVariant > > data;
340 24 : QSqlQueryModel model;
341 27 : for( auto && query : queries )
342 : {
343 15 : model.setQuery( query, m_dbConnection );
344 :
345 90 : for( int row = 0; row < model.rowCount(); row++ )
346 : {
347 75 : QSqlRecord rec = model.record( row );
348 300 : for( int col = 0; col < rec.count(); col++ )
349 : {
350 225 : auto columnName = rec.fieldName( col );
351 450 : auto fieldValue = rec.field( col ).value();
352 : //db.appendColumnData( columnName, fieldValue );
353 225 : data[ columnName ].append( fieldValue );
354 225 : }
355 75 : }
356 : }
357 :
358 24 : return prepareDataSource( data );
359 : }
360 :
361 31 : bool Engine::isOpened() const
362 : {
363 31 : return m_isOpened;
364 : }
365 :
366 5 : detail::ReportPtr Engine::getReport() const
367 : {
368 5 : return m_report;
369 : }
370 :
371 46 : const QString Engine::getLastError() const
372 : {
373 46 : return m_lastError;
374 : }
375 :
376 : }
|