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