KiCad PCB EDA Suite
dialog_pcm_progress.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2021 Andrew Lutsenko, anlutsenko at gmail dot com
5 * Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include "dialog_pcm_progress.h"
22#include <wx/msgdlg.h>
23
24
25#define GAUGE_RANGE 1000
26
27DIALOG_PCM_PROGRESS::DIALOG_PCM_PROGRESS( wxWindow* parent, bool aShowDownloadSection ) :
30 m_downloaded( 0 ),
31 m_downloadTotal( 0 ),
32 m_currentProgress( 0 ),
33 m_currentProgressTotal( 0 ),
34 m_finished( false ),
35 m_disabler( this )
36#if wxCHECK_VERSION( 3, 1, 0 )
37 ,
38 m_appProgressIndicator( parent->GetParent(), GAUGE_RANGE )
39#endif
40{
41#if wxCHECK_VERSION( 3, 1, 0 )
42 m_appProgressIndicator.Pulse();
43#endif
44
46 m_downloadGauge->SetRange( GAUGE_RANGE );
47 m_overallGauge->SetRange( GAUGE_RANGE );
48
49 if( !aShowDownloadSection )
50 m_panelDownload->Hide();
51}
52
53
54void DIALOG_PCM_PROGRESS::OnCancelClicked( wxCommandEvent& event )
55{
56 SetNumPhases( 1 );
57 SetPackageProgress( 1, 1 );
58 m_reporter->Report( _( "Aborting remaining tasks." ) );
59
60 m_cancelled.store( true );
61 m_finished.store( true );
62}
63
64
65void DIALOG_PCM_PROGRESS::OnCloseClicked( wxCommandEvent& event )
66{
68}
69
70
71void DIALOG_PCM_PROGRESS::PCMReport( const wxString& aText, SEVERITY aSeverity )
72{
73 std::lock_guard<std::mutex> guard( m_mutex );
74 m_reports.push_back( std::make_pair( aText, aSeverity ) );
75}
76
77
78void DIALOG_PCM_PROGRESS::SetDownloadProgress( uint64_t aDownloaded, uint64_t aTotal )
79{
80 m_downloaded.store( std::min( aDownloaded, aTotal ) );
81 m_downloadTotal.store( aTotal );
82}
83
84
85uint64_t DIALOG_PCM_PROGRESS::toKb( uint64_t aValue )
86{
87 return ( aValue + 999 ) / 1000;
88}
89
90
91void DIALOG_PCM_PROGRESS::SetPackageProgress( uint64_t aProgress, uint64_t aTotal )
92{
93 m_currentProgress.store( std::min( aProgress, aTotal ) );
94 m_currentProgressTotal.store( aTotal );
95}
96
97
99{
101 m_currentProgress.store( 0 );
102}
103
104
106{
107 m_finished.store( true );
108}
109
110
112{
113 bool finished = m_finished.load();
114 int phase = m_phase.load();
115 int phases = m_numPhases.load();
116 long cp = m_currentProgress.load();
117 long total = m_currentProgressTotal.load();
118 double current = ( total > 0 ) ? ( double( cp ) / double( total ) ) : 0;
119
120 if( phases > 0 )
121 current = ( phase + current ) / phases;
122
123 if( current > 1.0 || finished )
124 current = 1.0;
125
126 m_overallGauge->SetValue( current * GAUGE_RANGE );
127#if wxCHECK_VERSION( 3, 1, 0 )
128 m_appProgressIndicator.SetValue( current * GAUGE_RANGE );
129#endif
130
131 if( m_downloadTotal.load() == 0 )
132 {
133 m_downloadText->SetLabel( wxEmptyString );
134 m_downloadGauge->SetValue( 0 );
135 }
136 else
137 {
138 m_downloadText->SetLabel( wxString::Format( _( "Downloaded %lld/%lld kB" ),
139 toKb( m_downloaded.load() ),
140 toKb( m_downloadTotal.load() ) ) );
141
142 current = m_downloaded.load() / (double) m_downloadTotal.load();
143
144 if( current > 1.0 || finished )
145 current = 1.0;
146
147 m_downloadGauge->SetValue( current * GAUGE_RANGE );
148 }
149
150 std::lock_guard<std::mutex> guard( m_mutex );
151
152 for( const std::pair<wxString, SEVERITY>& pair : m_reports )
153 m_reporter->Report( pair.first, pair.second );
154
155 m_reports.clear();
156
157 if( finished )
158 {
159 m_buttonCancel->Disable();
160 m_buttonClose->Enable();
161 }
162
163 wxYield();
164
165 return true;
166}
167
168
Class DIALOG_PCM_PROGRESS_BASE.
std::atomic_int64_t m_currentProgressTotal
std::atomic_int64_t m_currentProgress
void OnCloseClicked(wxCommandEvent &event) override
std::atomic_bool m_finished
void OnCancelClicked(wxCommandEvent &event) override
void AdvancePhase() override
Safe to call from non-UI thread. Disables cancel button, enables close button.
void SetDownloadProgress(uint64_t aDownloaded, uint64_t aTotal)
Safe to call from non-UI thread. Sets the download prgress of the current package.
void SetPackageProgress(uint64_t aProgress, uint64_t aTotal)
Safe to call from non-UI thread. Advances to the next package.
std::vector< std::pair< wxString, SEVERITY > > m_reports
void PCMReport(const wxString &aText, SEVERITY aSeverity)
Safe to call from non-UI thread. Sets the download progress of the current zip entry.
static uint64_t toKb(uint64_t aValue)
DIALOG_PCM_PROGRESS(wxWindow *parent, bool aShowDownloadSection=true)
Constructor.
std::atomic_int64_t m_downloadTotal
std::atomic_int64_t m_downloaded
This implements all the tricky bits for thread safety, but the GUI is left to derived classes.
virtual void AdvancePhase() override
Use the next available virtual zone of the dialog progress bar.
void SetNumPhases(int aNumPhases) override
Set the number of phases.
void SetImmediateMode()
In immediate mode, messages are flushed as they are added.
REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) override
Report a string with a given severity.
#define GAUGE_RANGE
#define _(s)
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
SEVERITY