1 /***************************************************************************
2  *   This file is part of the Lime Report project                          *
3  *   Copyright (C) 2015 by Alexander Arin                                  *
4  *   arin_a@bk.ru                                                          *
5  *                                                                         *
6  **                   GNU General Public License Usage                    **
7  *                                                                         *
8  *   This library is free software: you can redistribute it and/or modify  *
9  *   it under the terms of the GNU General Public License as published by  *
10  *   the Free Software Foundation, either version 3 of the License, or     *
11  *   (at your option) any later version.                                   *
12  *   You should have received a copy of the GNU General Public License     *
13  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
14  *                                                                         *
15  **                  GNU Lesser General Public License                    **
16  *                                                                         *
17  *   This library is free software: you can redistribute it and/or modify  *
18  *   it under the terms of the GNU Lesser General Public License as        *
19  *   published by the Free Software Foundation, either version 3 of the    *
20  *   License, or (at your option) any later version.                       *
21  *   You should have received a copy of the GNU Lesser General Public      *
22  *   License along with this library.                                      *
23  *   If not, see <http://www.gnu.org/licenses/>.                           *
24  *                                                                         *
25  *   This library is distributed in the hope that it will be useful,       *
26  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
27  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
28  *   GNU General Public License for more details.                          *
29  ****************************************************************************/
30 #include "lrpreviewreportwindow.h"
31 #include "ui_lrpreviewreportwindow.h"
32 #include "serializators/lrxmlreader.h"
33 #include "serializators/lrxmlwriter.h"
34 #include "lrreportengine_p.h"
35 #include "lrpreviewreportwidget.h"
36 #include "lrpreviewreportwidget_p.h"
37 #include "items/editors/lrfonteditorwidget.h"
38 #include "items/editors/lrtextalignmenteditorwidget.h"
39 
40 #include <QPrinter>
41 #include <QPrintDialog>
42 #include <QFileDialog>
43 #include <QScrollBar>
44 #include <QDesktopWidget>
45 #include <QLabel>
46 #include <QMessageBox>
47 #include <QToolButton>
48 
49 namespace LimeReport{
50 
PreviewReportWindow(ReportEngine * report,QWidget * parent,QSettings * settings,Qt::WindowFlags flags)51 PreviewReportWindow::PreviewReportWindow(ReportEngine *report, QWidget *parent, QSettings *settings, Qt::WindowFlags flags) :
52     QMainWindow(parent,flags),
53     ui(new Ui::PreviewReportWindow), m_settings(settings), m_ownedSettings(false),
54     m_scalePercentChanging(false)
55 {
56     ui->setupUi(this);
57 
58     m_progressWidget = new QWidget(ui->statusbar);
59     QHBoxLayout* progressLayout = new QHBoxLayout();
60     progressLayout->setMargin(0);
61     progressLayout->addWidget(new QLabel(tr("Printing")));
62     m_progressBar = new QProgressBar(ui->statusbar);
63     m_progressBar->setMaximumWidth(100);
64     m_progressBar->setMaximumHeight(ui->statusbar->fontMetrics().height());
65     progressLayout->addWidget(m_progressBar);
66     QToolButton* tbCancel = new QToolButton();
67     tbCancel->setIcon(QIcon(":/report/images/closebox"));
68     tbCancel->setAutoRaise(true);
69     connect(tbCancel, SIGNAL(clicked(bool)), this, SLOT(slotCancelPrinting(bool)));
70     progressLayout->addWidget(tbCancel);
71     progressLayout->setSizeConstraint(QLayout::SetFixedSize);
72     m_progressWidget->setLayout(progressLayout);
73     m_progressWidget->setVisible(false);
74     ui->statusbar->addPermanentWidget(m_progressWidget);
75 
76     setWindowTitle("Lime Report Preview");
77     m_pagesNavigator = new QSpinBox(this);
78     m_pagesNavigator->setMaximum(10000000);
79     m_pagesNavigator->setPrefix(tr("Page: "));
80     m_pagesNavigator->setMinimumWidth(120);
81     ui->toolBar->insertWidget(ui->actionNextPage,m_pagesNavigator);
82     ui->editModeTools->hide();
83     ui->actionShowMessages->setVisible(false);
84 
85     connect(m_pagesNavigator,SIGNAL(valueChanged(int)),this,SLOT(slotPageNavigatorChanged(int)));
86     m_previewReportWidget = new PreviewReportWidget(report,this);
87     setCentralWidget(m_previewReportWidget);
88     layout()->setContentsMargins(1,1,1,1);
89     connect(m_previewReportWidget, SIGNAL(pageChanged(int)),
90             this, SLOT(slotPageChanged(int)) );
91     connect(m_previewReportWidget->d_ptr->m_previewPage, SIGNAL(selectionChanged()),
92             this, SLOT(slotSelectionChanged()));
93     connect(m_pagesNavigator, SIGNAL(valueChanged(int)),
94             this, SLOT(slotPageNavigatorChanged(int)));
95     connect(m_previewReportWidget, SIGNAL(onSave(bool&, LimeReport::IPreparedPages*)),
96             this, SIGNAL(onSave(bool&, LimeReport::IPreparedPages*)));
97 
98     connect(m_previewReportWidget->d_ptr->m_report, SIGNAL(printingStarted(int)), this, SLOT(slotPrintingStarted(int)));
99     connect(m_previewReportWidget->d_ptr->m_report, SIGNAL(pagePrintingFinished(int)), this, SLOT(slotPagePrintingFinished(int)));
100     connect(m_previewReportWidget->d_ptr->m_report, SIGNAL(printingFinished()), this, SLOT(slotPrintingFinished()));
101 
102     m_fontEditor = new FontEditorWidgetForPage(m_previewReportWidget->d_ptr->m_previewPage,tr("Font"),this);
103     m_fontEditor->setObjectName("fontTools");
104     m_fontEditor->setIconSize(ui->toolBar->iconSize());
105     m_textAlignmentEditor = new TextAlignmentEditorWidgetForPage(m_previewReportWidget->d_ptr->m_previewPage,tr("Text align"),this);
106     m_textAlignmentEditor->setObjectName("textAlignmentTools");
107     m_textAlignmentEditor->setIconSize(ui->toolBar->iconSize());
108     addToolBar(Qt::TopToolBarArea,m_fontEditor);
109     addToolBar(Qt::TopToolBarArea,m_textAlignmentEditor);
110 
111     m_scalePercent = new QComboBox(this);
112     m_scalePercent->setEditable(true);
113     ui->toolBar->insertWidget(ui->actionZoomOut, m_scalePercent);
114     initPercentCombobox();
115 
116     connect(ui->actionShowMessages, SIGNAL(triggered()), this, SLOT(slotShowErrors()));
117     connect(m_previewReportWidget, SIGNAL(scalePercentChanged(int)), this, SLOT(slotScalePercentChanged(int)));
118     connect(m_scalePercent, SIGNAL(currentIndexChanged(QString)), this, SLOT(scaleComboboxChanged(QString)));
119     connect(m_previewReportWidget, SIGNAL(pageChanged(int)), this, SLOT(slotCurrentPageChanged(int)));
120     connect(m_previewReportWidget, SIGNAL(itemInserted(LimeReport::PageDesignIntf*, QPointF, QString)),
121             this, SLOT(slotItemInserted(LimeReport::PageDesignIntf*, QPointF, QString)));
122 
123     restoreSetting();
124     selectStateIcon();
125 }
126 
writeSetting()127 void PreviewReportWindow::writeSetting()
128 {
129     settings()->beginGroup("PreviewWindow");
130     settings()->setValue("Geometry",saveGeometry());
131     settings()->setValue("State",saveState());
132     settings()->endGroup();
133 }
134 
restoreSetting()135 void PreviewReportWindow::restoreSetting()
136 {
137     settings()->beginGroup("PreviewWindow");
138     QVariant v = settings()->value("Geometry");
139     if (v.isValid()){
140         restoreGeometry(v.toByteArray());
141     } else {
142         QDesktopWidget *desktop = QApplication::desktop();
143 
144         int screenWidth = desktop->screenGeometry().width();
145         int screenHeight = desktop->screenGeometry().height();
146 
147         int x = static_cast<int>(screenWidth*0.1);
148         int y = static_cast<int>(screenHeight*0.1);
149 
150         resize(
151             static_cast<int>(screenWidth*0.8),
152             static_cast<int>(screenHeight*0.8)
153         );
154         move(x, y);
155     }
156     v = settings()->value("State");
157     if (v.isValid()){
158         restoreState(v.toByteArray());
159     }
160     settings()->endGroup();
161 }
162 
163 
~PreviewReportWindow()164 PreviewReportWindow::~PreviewReportWindow()
165 {
166     if (m_ownedSettings)
167         delete m_settings;
168     //delete m_previewPage;
169     delete ui;
170 }
171 
initPreview(int pagesCount)172 void PreviewReportWindow::initPreview(int pagesCount)
173 {
174     m_pagesNavigator->setSuffix(tr(" of %1").arg(pagesCount));
175     m_pagesNavigator->setMinimum(1);
176     m_pagesNavigator->setMaximum(pagesCount);
177     m_pagesNavigator->setValue(1);
178 }
179 
reloadPreview()180 void PreviewReportWindow::reloadPreview()
181 {
182    m_previewReportWidget->refreshPages();
183 }
184 
setSettings(QSettings * value)185 void PreviewReportWindow::setSettings(QSettings* value)
186 {
187     if (m_ownedSettings)
188         delete m_settings;
189     m_settings=value;
190     m_ownedSettings=false;
191     restoreSetting();
192 }
193 
setErrorMessages(const QStringList & value)194 void PreviewReportWindow::setErrorMessages(const QStringList &value){
195     ui->actionShowMessages->setVisible(true);
196     m_previewReportWidget->setErrorMessages(value);
197 }
198 
setToolBarVisible(bool value)199 void PreviewReportWindow::setToolBarVisible(bool value)
200 {
201     ui->toolBar->setHidden(value);
202     selectStateIcon();
203 }
204 
setStatusBarVisible(bool value)205 void PreviewReportWindow::setStatusBarVisible(bool value)
206 {
207     ui->statusbar->setVisible(value);
208 }
209 
setMenuVisible(bool value)210 void PreviewReportWindow::setMenuVisible(bool value)
211 {
212     ui->menubar->setVisible(value);
213 }
214 
setHideResultEditButton(bool value)215 void PreviewReportWindow::setHideResultEditButton(bool value)
216 {
217     ui->actionEdit_Mode->setVisible(value);
218     if (!value && ui->editModeTools) {
219         delete ui->editModeTools;
220         ui->editModeTools = 0;
221     }
222 }
223 
setHidePrintButton(bool value)224 void PreviewReportWindow::setHidePrintButton(bool value)
225 {
226     ui->actionPrint->setVisible(value);
227 }
228 
setHideSaveToFileButton(bool value)229 void PreviewReportWindow::setHideSaveToFileButton(bool value)
230 {
231     ui->actionSaveToFile->setVisible(value);
232 }
233 
setHidePrintToPdfButton(bool value)234 void PreviewReportWindow::setHidePrintToPdfButton(bool value)
235 {
236     ui->actionPrint_To_PDF->setVisible(value);
237 }
238 
setEnablePrintMenu(bool value)239 void PreviewReportWindow::setEnablePrintMenu(bool value)
240 {
241     ui->menuReport->setEnabled(value);
242 }
243 
settings()244 QSettings*PreviewReportWindow::settings()
245 {
246     if (m_settings){
247         return m_settings;
248     } else {
249         m_settings = new QSettings("LimeReport",QCoreApplication::applicationName());
250         m_ownedSettings = true;
251         return m_settings;
252     }
253 }
254 
setReportReader(ItemsReaderIntf::Ptr)255 void PreviewReportWindow::setReportReader(ItemsReaderIntf::Ptr /*reader*/)
256 {
257 //    m_reader=reader;
258 //    if (!reader.isNull()){
259 //        if (reader->first()) reader->readItem(m_previewPage->pageItem());
260 //        int pagesCount = reader->firstLevelItemsCount();
261 //        m_previewPage->pageItem()->setItemMode(PreviewMode);
262 //        initPreview(pagesCount);
263 //    }
264 }
265 
setPages(ReportPages pages)266 void PreviewReportWindow::setPages(ReportPages pages)
267 {
268     m_previewReportWidget->d_ptr->setPages(pages);
269     if (!pages.isEmpty()){
270         initPreview(pages.count());
271     }
272 }
273 
setDefaultPrinter(QPrinter * printer)274 void PreviewReportWindow::setDefaultPrinter(QPrinter *printer)
275 {
276     m_previewReportWidget->setDefaultPrinter(printer);
277 }
278 
exec()279 void PreviewReportWindow::exec()
280 {
281     bool deleteOnClose = testAttribute(Qt::WA_DeleteOnClose);
282     setAttribute(Qt::WA_DeleteOnClose,false);
283     setAttribute(Qt::WA_ShowModal,true);
284     show();
285     m_eventLoop.exec();
286     if (deleteOnClose) delete this;
287 }
288 
closeEvent(QCloseEvent * e)289 void PreviewReportWindow::closeEvent(QCloseEvent* e)
290 {
291     if (m_progressBar->isVisible()){
292         QMessageBox::critical(this, tr("Attention"), tr("The printing is in process"));
293         e->setAccepted(false);
294     }
295 #ifdef Q_OS_WIN
296     writeSetting();
297 #endif
298 #ifdef Q_OS_MAC
299     writeSetting();
300 #endif
301     m_eventLoop.exit();
302 }
303 
resizeEvent(QResizeEvent * e)304 void PreviewReportWindow::resizeEvent(QResizeEvent* e)
305 {
306 #ifdef Q_OS_UNIX
307     if (e->oldSize()!=e->size()){
308         writeSetting();
309     }
310 #else
311     Q_UNUSED(e)
312 #endif
313 }
314 
moveEvent(QMoveEvent * e)315 void PreviewReportWindow::moveEvent(QMoveEvent* e)
316 {
317 #ifdef Q_OS_UNIX
318     if (e->oldPos()!=e->pos()){
319         writeSetting();
320     }
321 #else
322     Q_UNUSED(e)
323 #endif
324 }
325 
showEvent(QShowEvent *)326 void PreviewReportWindow::showEvent(QShowEvent *)
327 {
328     m_fontEditor->setVisible(ui->actionEdit_Mode->isChecked());
329     if (ui->editModeTools)
330         ui->editModeTools->setVisible(false);
331     m_textAlignmentEditor->setVisible(ui->actionEdit_Mode->isChecked());
332     switch (m_previewScaleType) {
333     case FitWidth:
334         m_previewReportWidget->fitWidth();
335         break;
336     case FitPage:
337         m_previewReportWidget->fitPage();
338         break;
339     case OneToOne:
340         m_previewReportWidget->setScalePercent(100);
341         break;
342     case Percents:
343         m_previewReportWidget->setScalePercent(m_previewScalePercent);
344 
345     }
346 }
347 
selectStateIcon()348 void PreviewReportWindow::selectStateIcon()
349 {
350     if (ui->toolBar->isHidden()){
351         ui->actionShow_Toolbar->setIcon(QIcon(":/report/images/not_checked.png"));
352     } else {
353         ui->actionShow_Toolbar->setIcon(QIcon(":/report/images/checked.png"));
354     }
355 }
356 
slotPrint()357 void PreviewReportWindow::slotPrint()
358 {
359     m_previewReportWidget->print();
360 }
361 
slotPriorPage()362 void PreviewReportWindow::slotPriorPage()
363 {
364     m_previewReportWidget->priorPage();
365 }
366 
slotNextPage()367 void PreviewReportWindow::slotNextPage()
368 {
369     m_previewReportWidget->nextPage();
370 }
371 
slotZoomIn()372 void PreviewReportWindow::slotZoomIn()
373 {
374     m_previewReportWidget->zoomIn();
375 }
376 
slotZoomOut()377 void PreviewReportWindow::slotZoomOut()
378 {
379     m_previewReportWidget->zoomOut();
380 }
381 
slotPageNavigatorChanged(int value)382 void PreviewReportWindow::slotPageNavigatorChanged(int value)
383 {
384     m_previewReportWidget->pageNavigatorChanged(value);
385 }
386 
slotShowErrors()387 void PreviewReportWindow::slotShowErrors()
388 {
389     m_previewReportWidget->setErrorsMesagesVisible(ui->actionShowMessages->isChecked());
390 }
391 
on_actionEdit_Mode_triggered(bool checked)392 void PreviewReportWindow::on_actionEdit_Mode_triggered(bool checked)
393 {
394     m_previewReportWidget->d_ptr->m_previewPage->setItemMode((checked)?ItemModes(DesignMode):PreviewMode);
395     m_textAlignmentEditor->setVisible(checked);
396     m_fontEditor->setVisible(checked);
397     if (checked)
398         ui->editModeTools->show();
399     else ui->editModeTools->hide();
400 }
401 
slotSelectionChanged()402 void PreviewReportWindow::slotSelectionChanged()
403 {
404     QGraphicsScene* page=dynamic_cast<QGraphicsScene*>(sender());
405     if (page){
406         if (page->selectedItems().count()==1){
407             BaseDesignIntf* item = dynamic_cast<BaseDesignIntf*>(page->selectedItems().at(0));
408             if (item) {
409                 m_fontEditor->setItem(item);
410                 m_textAlignmentEditor->setItem(item);
411             }
412         }
413     }
414 }
415 
reader()416 ItemsReaderIntf *PreviewReportWindow::reader()
417 {
418     return m_reader.data();
419 }
420 
initPercentCombobox()421 void PreviewReportWindow::initPercentCombobox()
422 {
423     for (int i = 10; i<310; i+=10){
424         m_scalePercent->addItem(QString("%1%").arg(i));
425     }
426     m_scalePercent->setCurrentIndex(4);
427 }
428 
previewScaleType() const429 ScaleType PreviewReportWindow::previewScaleType() const
430 {
431     return m_previewScaleType;
432 }
433 
setPreviewScaleType(const ScaleType & previewScaleType,int percent)434 void PreviewReportWindow::setPreviewScaleType(const ScaleType &previewScaleType, int percent)
435 {
436     m_previewScaleType = previewScaleType;
437     m_previewScalePercent = percent;
438     m_previewReportWidget->setScaleType(previewScaleType, percent);
439 }
440 
previewPageBackgroundColor()441 QColor PreviewReportWindow::previewPageBackgroundColor()
442 {
443     return m_previewReportWidget->previewPageBackgroundColor();
444 }
445 
setPreviewPageBackgroundColor(QColor color)446 void PreviewReportWindow::setPreviewPageBackgroundColor(QColor color)
447 {
448     m_previewReportWidget->setPreviewPageBackgroundColor(color);
449 }
450 
on_actionSaveToFile_triggered()451 void PreviewReportWindow::on_actionSaveToFile_triggered()
452 {
453     m_previewReportWidget->saveToFile();
454 }
455 
slotFirstPage()456 void PreviewReportWindow::slotFirstPage()
457 {
458     m_previewReportWidget->firstPage();
459 }
460 
slotLastPage()461 void PreviewReportWindow::slotLastPage()
462 {
463     m_previewReportWidget->lastPage();
464 }
465 
slotPrintToPDF()466 void PreviewReportWindow::slotPrintToPDF()
467 {
468     m_previewReportWidget->printToPDF();
469 }
470 
slotPageChanged(int pageIndex)471 void PreviewReportWindow::slotPageChanged(int pageIndex)
472 {
473     m_pagesNavigator->setValue(pageIndex);
474 }
475 
slotInsertNewTextItem()476 void PreviewReportWindow::slotInsertNewTextItem()
477 {
478     m_previewReportWidget->startInsertTextItem();
479     ui->actionSelection_Mode->setChecked(false);
480 }
481 
slotActivateItemSelectionMode()482 void PreviewReportWindow::slotActivateItemSelectionMode()
483 {
484     m_previewReportWidget->activateItemSelectionMode();
485     ui->actionSelection_Mode->setChecked(true);
486     ui->actionInsertTextItem->setChecked(false);
487 }
488 
slotDeleteSelectedItems()489 void PreviewReportWindow::slotDeleteSelectedItems()
490 {
491     m_previewReportWidget->deleteSelectedItems();
492 }
493 
on_actionFit_page_width_triggered()494 void PreviewReportWindow::on_actionFit_page_width_triggered()
495 {
496     m_previewReportWidget->fitWidth();
497 }
498 
on_actionFit_page_triggered()499 void PreviewReportWindow::on_actionFit_page_triggered()
500 {
501     m_previewReportWidget->fitPage();
502 }
503 
on_actionOne_to_one_triggered()504 void PreviewReportWindow::on_actionOne_to_one_triggered()
505 {
506     m_previewReportWidget->setScalePercent(100);
507 }
508 
scaleComboboxChanged(QString text)509 void PreviewReportWindow::scaleComboboxChanged(QString text)
510 {
511     if (m_scalePercentChanging) return;
512     m_scalePercentChanging = true;
513     m_previewReportWidget->setScalePercent(text.remove(text.count()-1,1).toInt());
514     m_scalePercentChanging = false;
515 }
516 
slotScalePercentChanged(int percent)517 void PreviewReportWindow::slotScalePercentChanged(int percent)
518 {
519     if (m_scalePercentChanging) return;
520     m_scalePercentChanging = true;
521     if (m_scalePercent->findText(QString("%1%").arg(percent)) == -1)
522         m_scalePercent->setCurrentIndex(-1);
523     m_scalePercent->setEditText(QString("%1%").arg(percent));
524     m_scalePercentChanging = false;
525 }
526 
on_actionShowMessages_toggled(bool value)527 void PreviewReportWindow::on_actionShowMessages_toggled(bool value)
528 {
529    m_previewReportWidget->setErrorsMesagesVisible(value);
530 }
531 
on_actionShow_Toolbar_triggered()532 void PreviewReportWindow::on_actionShow_Toolbar_triggered()
533 {
534     setToolBarVisible(!ui->toolBar->isHidden());
535     writeSetting();
536 }
537 
slotCurrentPageChanged(int)538 void PreviewReportWindow::slotCurrentPageChanged(int /*page*/)
539 {
540     slotActivateItemSelectionMode();
541 }
542 
slotItemInserted(PageDesignIntf *,QPointF,const QString &)543 void PreviewReportWindow::slotItemInserted(PageDesignIntf *, QPointF, const QString&)
544 {
545     slotActivateItemSelectionMode();
546 }
547 
slotPrintingStarted(int pageCount)548 void PreviewReportWindow::slotPrintingStarted(int pageCount)
549 {
550     m_progressBar->setMinimum(1);
551     m_progressBar->setMaximum(pageCount);
552     m_progressWidget->setVisible(true);
553 }
554 
slotPagePrintingFinished(int pageIndex)555 void PreviewReportWindow::slotPagePrintingFinished(int pageIndex)
556 {
557     m_progressBar->setValue(pageIndex);
558 }
559 
slotPrintingFinished()560 void PreviewReportWindow::slotPrintingFinished()
561 {
562     m_progressWidget->setVisible(false);
563 }
564 
slotCancelPrinting(bool)565 void PreviewReportWindow::slotCancelPrinting(bool)
566 {
567     m_previewReportWidget->d_ptr->m_report->cancelPrinting();
568 }
569 
570 }// namespace LimeReport
571 
572