1 /*
2 * Copyright (C) 2015-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9 #include "ProgressJob.h"
10
11 #include "ServiceBroker.h"
12 #include "dialogs/GUIDialogExtendedProgressBar.h"
13 #include "dialogs/GUIDialogProgress.h"
14 #include "guilib/GUIComponent.h"
15 #include "guilib/GUIWindowManager.h"
16 #include "utils/Variant.h"
17
18 #include <math.h>
19
CProgressJob()20 CProgressJob::CProgressJob()
21 : m_progress(NULL),
22 m_progressDialog(NULL)
23 { }
24
CProgressJob(CGUIDialogProgressBarHandle * progressBar)25 CProgressJob::CProgressJob(CGUIDialogProgressBarHandle* progressBar)
26 : m_progress(progressBar),
27 m_progressDialog(NULL)
28 { }
29
~CProgressJob()30 CProgressJob::~CProgressJob()
31 {
32 MarkFinished();
33
34 m_progress = NULL;
35 m_progressDialog = NULL;
36 }
37
ShouldCancel(unsigned int progress,unsigned int total) const38 bool CProgressJob::ShouldCancel(unsigned int progress, unsigned int total) const
39 {
40 if (IsCancelled())
41 return true;
42
43 SetProgress(progress, total);
44
45 return CJob::ShouldCancel(progress, total);
46 }
47
DoModal()48 bool CProgressJob::DoModal()
49 {
50 m_progress = NULL;
51
52 // get a progress dialog if we don't already have one
53 if (m_progressDialog == NULL)
54 {
55 m_progressDialog = CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogProgress>(WINDOW_DIALOG_PROGRESS);
56
57 if (m_progressDialog == NULL)
58 return false;
59 }
60
61 m_modal = true;
62
63 // do the work
64 bool result = DoWork();
65
66 // mark the progress dialog as finished (will close it)
67 MarkFinished();
68 m_modal = false;
69
70 return result;
71 }
72
SetProgressIndicators(CGUIDialogProgressBarHandle * progressBar,CGUIDialogProgress * progressDialog,bool updateProgress,bool updateInformation)73 void CProgressJob::SetProgressIndicators(CGUIDialogProgressBarHandle* progressBar, CGUIDialogProgress* progressDialog, bool updateProgress /* = true */, bool updateInformation /* = true */)
74 {
75 SetProgressBar(progressBar);
76 SetProgressDialog(progressDialog);
77 SetUpdateProgress(updateProgress);
78 SetUpdateInformation(updateInformation);
79
80 // disable auto-closing
81 SetAutoClose(false);
82 }
83
ShowProgressDialog() const84 void CProgressJob::ShowProgressDialog() const
85 {
86 if (!IsModal() || m_progressDialog == NULL ||
87 m_progressDialog->IsDialogRunning())
88 return;
89
90 // show the progress dialog as a modal dialog with a progress bar
91 m_progressDialog->Open();
92 m_progressDialog->ShowProgressBar(true);
93 }
94
SetTitle(const std::string & title)95 void CProgressJob::SetTitle(const std::string &title)
96 {
97 if (!m_updateInformation)
98 return;
99
100 if (m_progress != NULL)
101 m_progress->SetTitle(title);
102 else if (m_progressDialog != NULL)
103 {
104 m_progressDialog->SetHeading(CVariant{title});
105
106 ShowProgressDialog();
107 }
108 }
109
SetText(const std::string & text)110 void CProgressJob::SetText(const std::string &text)
111 {
112 if (!m_updateInformation)
113 return;
114
115 if (m_progress != NULL)
116 m_progress->SetText(text);
117 else if (m_progressDialog != NULL)
118 {
119 m_progressDialog->SetText(CVariant{text});
120
121 ShowProgressDialog();
122 }
123 }
124
SetProgress(float percentage) const125 void CProgressJob::SetProgress(float percentage) const
126 {
127 if (!m_updateProgress)
128 return;
129
130 if (m_progress != NULL)
131 m_progress->SetPercentage(percentage);
132 else if (m_progressDialog != NULL)
133 {
134 ShowProgressDialog();
135
136 int iPercentage = static_cast<int>(ceil(percentage));
137 // only change and update the progress bar if its percentage value changed
138 // (this can have a huge impact on performance if it's called a lot)
139 if (iPercentage != m_progressDialog->GetPercentage())
140 {
141 m_progressDialog->SetPercentage(iPercentage);
142 m_progressDialog->Progress();
143 }
144 }
145 }
146
SetProgress(int currentStep,int totalSteps) const147 void CProgressJob::SetProgress(int currentStep, int totalSteps) const
148 {
149 if (!m_updateProgress)
150 return;
151
152 if (m_progress != NULL)
153 m_progress->SetProgress(currentStep, totalSteps);
154 else if (m_progressDialog != NULL)
155 SetProgress((static_cast<float>(currentStep) * 100.0f) / totalSteps);
156 }
157
MarkFinished()158 void CProgressJob::MarkFinished()
159 {
160 if (m_progress != NULL)
161 {
162 if (m_updateProgress)
163 {
164 m_progress->MarkFinished();
165 // We don't own this pointer and it will be deleted after it's marked finished
166 // just set it to nullptr so we don't try to use it again
167 m_progress = nullptr;
168 }
169 }
170 else if (m_progressDialog != NULL && m_autoClose)
171 m_progressDialog->Close();
172 }
173
IsCancelled() const174 bool CProgressJob::IsCancelled() const
175 {
176 if (m_progressDialog != NULL)
177 return m_progressDialog->IsCanceled();
178
179 return false;
180 }
181
HasProgressIndicator() const182 bool CProgressJob::HasProgressIndicator() const
183 {
184 return m_progress != nullptr || m_progressDialog != nullptr;
185 }
186