1 /**********************************************************************************************
2     Copyright (C) 2014-2015 Oliver Eichler <oliver.eichler@gmx.de>
3 
4     This program is free software: you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation, either version 3 of the License, or
7     (at your option) any later version.
8 
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13 
14     You should have received a copy of the GNU General Public License
15     along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 
17 **********************************************************************************************/
18 
19 #include "canvas/CCanvas.h"
20 #include "CMainWindow.h"
21 #include "helpers/CProgressDialog.h"
22 #include "units/IUnit.h"
23 
24 #include <QtWidgets>
25 
26 QStack<CProgressDialog*> CProgressDialog::stackSelf;
27 
28 #define DELAY 1000
29 
CProgressDialog(const QString text,int min,int max,QWidget * parent)30 CProgressDialog::CProgressDialog(const QString text, int min, int max, QWidget* parent)
31     : QDialog(parent)
32 {
33     stackSelf.push(this);
34     int oldTopIndex = stackSelf.length() - 2;
35 
36     setupUi(this);
37     setWindowModality(Qt::ApplicationModal);
38 
39     label->setText(text);
40     progressBar->setMinimum(min);
41     progressBar->setMaximum(max);
42     progressBar->setValue(0);
43 
44     time.start();
45     labelTime->setText(tr("Elapsed time: %1").arg(time.elapsed() / 1000));
46 
47     if(max == NOINT)
48     {
49         progressBar->hide();
50         // add a timer to update the elapsed time
51         QTimer* t = new QTimer(this);
52         t->start(DELAY);
53         connect(t, &QTimer::timeout, this, [this] {
54             setValue(0);
55         });
56     }
57 
58     QDialog::hide();
59     timer = new QTimer(this);
60     timer->setSingleShot(true);
61     connect(timer, &QTimer::timeout, this, [this, oldTopIndex] {
62         if(oldTopIndex > 0)
63         {
64             stackSelf[oldTopIndex]->pause();
65         }
66         show();
67     });
68     timer->start(DELAY);
69 }
70 
self()71 CProgressDialog* CProgressDialog::self()
72 {
73     if(stackSelf.isEmpty())
74     {
75         return nullptr;
76     }
77     return stackSelf.top();
78 }
79 
~CProgressDialog()80 CProgressDialog::~CProgressDialog()
81 {
82     stackSelf.pop();
83     if(!stackSelf.isEmpty())
84     {
85         stackSelf.top()->goOn();
86     }
87 }
88 
pause()89 void CProgressDialog::pause()
90 {
91     hide();
92     timer->stop();
93     timeElapsed = time.elapsed();
94 }
95 
goOn()96 void CProgressDialog::goOn()
97 {
98     //if goOn() is called from the dtor of another progress bar this progress bar was not necessarily paused.
99     //Also, it the second of waiting might not have elapsed. Thus, if the timer is still running, we do nothing
100     if(timer->isActive())
101     {
102         return;
103     }
104     if(timeElapsed <= DELAY)
105     {
106         timer->start(DELAY - timeElapsed);
107     }
108     else
109     {
110         show();
111     }
112 }
113 
114 
setAllVisible(bool yes)115 void CProgressDialog::setAllVisible(bool yes)
116 {
117     if(stackSelf.isEmpty())
118     {
119         return;
120     }
121 
122     yes ? stackSelf.top()->goOn() : stackSelf.top()->pause();
123 }
124 
enableCancel(bool yes)125 void CProgressDialog::enableCancel(bool yes)
126 {
127     buttonBox->setEnabled(yes);
128 }
129 
reject()130 void CProgressDialog::reject()
131 {
132     setResult(QMessageBox::Abort);
133     emit rejected();
134 }
135 
setValue(int val)136 void CProgressDialog::setValue(int val)
137 {
138     if(time.elapsed() > DELAY)
139     {
140         QApplication::processEvents();
141     }
142     progressBar->setValue(val);
143     labelTime->setText(tr("Elapsed time: %1 seconds.").arg(time.elapsed() / 1000.0, 0, 'f', 0));
144 }
145 
wasCanceled()146 bool CProgressDialog::wasCanceled()
147 {
148     return result() == QMessageBox::Abort;
149 }
150 
showEvent(QShowEvent *)151 void CProgressDialog::showEvent(QShowEvent*)
152 {
153     // that is a workaround for canvas loosing mousetracking caused by CProgressDialog being modal:
154     CCanvas* canvas = CMainWindow::self().getVisibleCanvas();
155     if (canvas != nullptr)
156     {
157         canvas->mouseTrackingLost();
158     }
159 }
160