source: filezilla/trunk/fuentes/src/interface/update_dialog.cpp @ 130

Last change on this file since 130 was 130, checked in by jrpelegrina, 3 years ago

First release to xenial

File size: 7.2 KB
Line 
1#include <filezilla.h>
2
3#if FZ_MANUALUPDATECHECK
4
5#include "buildinfo.h"
6#include "filezillaapp.h"
7#include "file_utils.h"
8#include "update_dialog.h"
9#include "themeprovider.h"
10
11#include <wx/animate.h>
12#include <wx/hyperlink.h>
13
14BEGIN_EVENT_TABLE(CUpdateDialog, wxDialogEx)
15EVT_BUTTON(XRCID("ID_INSTALL"), CUpdateDialog::OnInstall)
16EVT_TIMER(wxID_ANY, CUpdateDialog::OnTimer)
17EVT_HYPERLINK(XRCID("ID_SHOW_DETAILS"), CUpdateDialog::ShowDetails)
18EVT_HYPERLINK(XRCID("ID_RETRY"), CUpdateDialog::Retry)
19EVT_HYPERLINK(XRCID("ID_DOWNLOAD_RETRY"), CUpdateDialog::Retry)
20EVT_BUTTON(XRCID("ID_DEBUGLOG"), CUpdateDialog::OnDebugLog)
21END_EVENT_TABLE()
22
23namespace pagenames {
24enum type {
25        checking,
26        failed,
27        newversion,
28        latest
29};
30}
31
32static int refcount = 0;
33
34CUpdateDialog::CUpdateDialog(wxWindow* parent, CUpdater& updater)
35        : parent_(parent)
36        , updater_(updater)
37{
38        timer_.SetOwner(this);
39        ++refcount;
40}
41
42CUpdateDialog::~CUpdateDialog()
43{
44        --refcount;
45}
46
47bool CUpdateDialog::IsRunning()
48{
49        return refcount != 0;
50}
51
52int CUpdateDialog::ShowModal()
53{
54        wxString version(PACKAGE_VERSION, wxConvLocal);
55        if (version.empty() || version[0] < '0' || version[0] > '9')
56        {
57                wxMessageBoxEx(_("Executable contains no version info, cannot check for updates."), _("Check for updates failed"), wxICON_ERROR, parent_);
58                return wxID_CANCEL;
59        }
60
61        if (!Load(parent_, _T("ID_UPDATE_DIALOG")))
62                return wxID_CANCEL;
63
64        LoadPanel(_T("ID_CHECKING_PANEL"));
65        LoadPanel(_T("ID_FAILURE_PANEL"));
66        LoadPanel(_T("ID_NEWVERSION_PANEL"));
67        LoadPanel(_T("ID_LATEST_PANEL"));
68        if( panels_.size() != 4 ) {
69                return wxID_CANCEL;
70        }
71
72        wxAnimation a = CThemeProvider::Get()->CreateAnimation(_T("ART_THROBBER"), wxSize(16,16));
73        XRCCTRL(*this, "ID_WAIT_CHECK", wxAnimationCtrl)->SetMinSize(a.GetSize());
74        XRCCTRL(*this, "ID_WAIT_CHECK", wxAnimationCtrl)->SetAnimation(a);
75        XRCCTRL(*this, "ID_WAIT_CHECK", wxAnimationCtrl)->Play();
76        XRCCTRL(*this, "ID_WAIT_DOWNLOAD", wxAnimationCtrl)->SetMinSize(a.GetSize());
77        XRCCTRL(*this, "ID_WAIT_DOWNLOAD", wxAnimationCtrl)->SetAnimation(a);
78        XRCCTRL(*this, "ID_WAIT_DOWNLOAD", wxAnimationCtrl)->Play();
79
80        Wrap();
81
82        XRCCTRL(*this, "ID_DETAILS", wxTextCtrl)->Hide();
83
84        UpdaterState s = updater_.GetState();
85        UpdaterStateChanged( s, updater_.AvailableBuild() );
86
87        updater_.AddHandler(*this);
88
89        updater_.RunIfNeeded();
90
91        int ret = wxDialogEx::ShowModal();
92        updater_.RemoveHandler(*this);
93
94        return ret;
95}
96
97void CUpdateDialog::Wrap()
98{
99        wxPanel* parentPanel = XRCCTRL(*this, "ID_CONTENT", wxPanel);
100        wxSize canvas;
101        canvas.x = GetSize().x - parentPanel->GetSize().x;
102        canvas.y = GetSize().y - parentPanel->GetSize().y;
103
104        // Wrap pages nicely
105        std::vector<wxWindow*> pages;
106        for (auto const& panel : panels_) {
107                pages.push_back(panel);
108        }
109        wxGetApp().GetWrapEngine()->WrapRecursive(pages, 1.33, "Update", canvas);
110
111        // Keep track of maximum page size
112        wxSize size = GetSizer()->GetMinSize();
113        for (auto const& panel : panels_) {
114                size.IncTo(panel->GetSizer()->GetMinSize());
115        }
116
117        wxSize panelSize = size;
118#ifdef __WXGTK__
119        panelSize.x += 1;
120#endif
121        parentPanel->SetInitialSize(panelSize);
122
123        // Adjust pages sizes according to maximum size
124        for (auto const& panel : panels_) {
125                panel->GetSizer()->SetMinSize(size);
126                panel->GetSizer()->Fit(panel);
127                panel->GetSizer()->SetSizeHints(panel);
128                if (GetLayoutDirection() == wxLayout_RightToLeft) {
129                        panel->Move(wxPoint(0, 0));
130                }
131        }
132
133        GetSizer()->Fit(this);
134        GetSizer()->SetSizeHints(this);
135
136#ifdef __WXGTK__
137        // Pre-show dialog under GTK, else panels won't get initialized properly
138        Show();
139#endif
140
141        for (auto const& panel : panels_) {
142                panel->Hide();
143        }
144        panels_[0]->Show();
145}
146
147void CUpdateDialog::LoadPanel(wxString const& name)
148{
149        wxPanel* p = new wxPanel();
150        if (!wxXmlResource::Get()->LoadPanel(p, XRCCTRL(*this, "ID_CONTENT", wxPanel), name)) {
151                delete p;
152                return;
153        }
154
155        panels_.push_back(p);
156}
157
158
159void CUpdateDialog::UpdaterStateChanged( UpdaterState s, build const& v )
160{
161        timer_.Stop();
162        for (auto const& panel : panels_) {
163                panel->Hide();
164        }
165        if( s == UpdaterState::idle ) {
166                panels_[pagenames::latest]->Show();
167        }
168        else if( s == UpdaterState::failed ) {
169                XRCCTRL(*this, "ID_DETAILS", wxTextCtrl)->ChangeValue(updater_.GetLog());
170                panels_[pagenames::failed]->Show();
171        }
172        else if( s == UpdaterState::checking ) {
173                panels_[pagenames::checking]->Show();
174        }
175        else if( s == UpdaterState::newversion || s == UpdaterState::newversion_ready || s == UpdaterState::newversion_downloading ) {
176                XRCCTRL(*this, "ID_VERSION", wxStaticText)->SetLabel(v.version_);
177
178                wxString news = updater_.GetChangelog();
179
180                auto pos = news.find(v.version_ + _T(" (2"));
181                if (pos != wxString::npos) {
182                        news = news.Mid(pos);
183                }
184
185                XRCCTRL(*this, "ID_NEWS_LABEL", wxStaticText)->Show(!news.empty());
186                XRCCTRL(*this, "ID_NEWS", wxTextCtrl)->Show(!news.empty());
187                if( news != XRCCTRL(*this, "ID_NEWS", wxTextCtrl)->GetValue() ) {
188                        XRCCTRL(*this, "ID_NEWS", wxTextCtrl)->ChangeValue(news);
189                }
190                bool downloading = s == UpdaterState::newversion_downloading;
191                XRCCTRL(*this, "ID_DOWNLOAD_LABEL", wxStaticText)->Show(downloading);
192                XRCCTRL(*this, "ID_WAIT_DOWNLOAD", wxAnimationCtrl)->Show(downloading);
193                XRCCTRL(*this, "ID_DOWNLOAD_PROGRESS", wxStaticText)->Show(downloading);
194                if( downloading ) {
195                        timer_.Start(500);
196                        wxTimerEvent ev;
197                        OnTimer(ev);
198                }
199
200                bool ready = s == UpdaterState::newversion_ready;
201                XRCCTRL(*this, "ID_DOWNLOADED", wxStaticText)->Show(ready);
202                XRCCTRL(*this, "ID_INSTALL", wxButton)->Show(ready);
203
204                bool manual = s == UpdaterState::newversion;
205                bool dlfail = s == UpdaterState::newversion && !v.url_.empty();
206                XRCCTRL(*this, "ID_DOWNLOAD_FAIL", wxStaticText)->Show(dlfail);
207                XRCCTRL(*this, "ID_DOWNLOAD_RETRY", wxHyperlinkCtrl)->Show(dlfail);
208
209                XRCCTRL(*this, "ID_NEWVERSION_WEBSITE_TEXT", wxStaticText)->Show(manual && !dlfail);
210                XRCCTRL(*this, "ID_NEWVERSION_WEBSITE_TEXT_DLFAIL", wxStaticText)->Show(manual && dlfail);
211                XRCCTRL(*this, "ID_NEWVERSION_WEBSITE_LINK", wxHyperlinkCtrl)->Show(manual);
212
213                panels_[pagenames::newversion]->Show();
214                panels_[pagenames::newversion]->Layout();
215        }
216}
217
218void CUpdateDialog::OnInstall(wxCommandEvent&)
219{
220        wxString f = updater_.DownloadedFile();
221        if( f.empty() ) {
222                return;
223        }
224#ifdef __WXMSW__
225        wxExecute(_T("\"") + f +  _T("\" /update"));
226        wxWindow* p = parent_;
227        while( p->GetParent() ) {
228                p = p->GetParent();
229        }
230        p->Close();
231#else
232        bool program_exists = false;
233        wxString cmd = GetSystemOpenCommand(f, program_exists);
234        if( program_exists && !cmd.empty() ) {
235                if (wxExecute(cmd))
236                        return;
237        }
238
239        wxFileName fn(f);
240        OpenInFileManager(fn.GetPath());
241#endif
242}
243
244void CUpdateDialog::OnTimer(wxTimerEvent&)
245{
246        int64_t size = updater_.AvailableBuild().size_;
247        int64_t downloaded = updater_.BytesDownloaded();
248
249        unsigned int percent = 0;
250        if (size > 0 && downloaded >= 0) {
251                percent = static_cast<unsigned int>((downloaded * 100) / size);
252        }
253
254        XRCCTRL(*this, "ID_DOWNLOAD_PROGRESS", wxStaticText)->SetLabel(wxString::Format(_("(%u%% downloaded)"), percent));
255}
256
257void CUpdateDialog::ShowDetails(wxHyperlinkEvent&)
258{
259        XRCCTRL(*this, "ID_SHOW_DETAILS", wxHyperlinkCtrl)->Hide();
260        XRCCTRL(*this, "ID_DETAILS", wxTextCtrl)->Show();
261
262        panels_[pagenames::failed]->Layout();
263}
264
265void CUpdateDialog::Retry(wxHyperlinkEvent&)
266{
267        updater_.RunIfNeeded();
268}
269
270void CUpdateDialog::OnDebugLog(wxCommandEvent&)
271{
272        wxMessageBoxEx(updater_.GetLog());
273}
274
275#endif
Note: See TracBrowser for help on using the repository browser.