diff --git a/3rdparty/wx-2015.vcxproj b/3rdparty/wx-2015.vcxproj index e055722f..a18bd6e1 100644 --- a/3rdparty/wx-2015.vcxproj +++ b/3rdparty/wx-2015.vcxproj @@ -174,6 +174,7 @@ + @@ -277,6 +278,7 @@ + diff --git a/3rdparty/wx-2015.vcxproj.filters b/3rdparty/wx-2015.vcxproj.filters index 03c96788..7a95e621 100644 --- a/3rdparty/wx-2015.vcxproj.filters +++ b/3rdparty/wx-2015.vcxproj.filters @@ -514,5 +514,11 @@ Source Files + + Source Files + + + Source Files + - + \ No newline at end of file diff --git a/3rdparty/wxWidgets_setup_h/wx/setup.h b/3rdparty/wxWidgets_setup_h/wx/setup.h index d0009aff..0f7f8ab8 100644 --- a/3rdparty/wxWidgets_setup_h/wx/setup.h +++ b/3rdparty/wxWidgets_setup_h/wx/setup.h @@ -881,7 +881,7 @@ #define wxUSE_CALENDARCTRL 0 // wxCalendarCtrl #define wxUSE_CHECKBOX 1 // wxCheckBox #define wxUSE_CHECKLISTBOX 0 // wxCheckListBox (requires wxUSE_OWNER_DRAWN) -#define wxUSE_CHOICE 0 // wxChoice +#define wxUSE_CHOICE 1 // wxChoice #define wxUSE_COLLPANE 0 // wxCollapsiblePane #define wxUSE_COLOURPICKERCTRL 0 // wxColourPickerCtrl #define wxUSE_COMBOBOX 0 // wxComboBox diff --git a/include/winsparkle.h b/include/winsparkle.h index 360cdd47..33f5f23e 100644 --- a/include/winsparkle.h +++ b/include/winsparkle.h @@ -292,6 +292,15 @@ WIN_SPARKLE_API int __cdecl win_sparkle_get_update_check_interval(); */ WIN_SPARKLE_API time_t __cdecl win_sparkle_get_last_check_time(); +/** +Sets the time for the last update check. + + @param time Set the time for the last update check. + + @since 2.4 - CE-specific version +*/ +WIN_SPARKLE_API void __cdecl win_sparkle_set_last_check_time(time_t time); + /// Callback type for win_sparkle_error_callback() typedef void (__cdecl *win_sparkle_error_callback_t)(); diff --git a/src/dll_api.cpp b/src/dll_api.cpp index 5ba98768..3e95c435 100644 --- a/src/dll_api.cpp +++ b/src/dll_api.cpp @@ -216,14 +216,13 @@ WIN_SPARKLE_API int __cdecl win_sparkle_get_automatic_check_for_updates() WIN_SPARKLE_API void __cdecl win_sparkle_set_update_check_interval(int interval) { - static const int MIN_CHECK_INTERVAL = 3600; // one hour - try { - if ( interval < MIN_CHECK_INTERVAL ) + // Remove this limitation so QA can easily test + if ( interval < Settings::MIN_CHECK_INTERVAL ) { - winsparkle::LogError("Invalid update interval (min: 3600 seconds)"); - interval = MIN_CHECK_INTERVAL; + winsparkle::LogError("Invalid update interval (min: 300 seconds)"); + interval = Settings::MIN_CHECK_INTERVAL; } Settings::WriteConfigValue("UpdateInterval", interval); @@ -261,6 +260,15 @@ WIN_SPARKLE_API time_t __cdecl win_sparkle_get_last_check_time() return DEFAULT_LAST_CHECK_TIME; } +WIN_SPARKLE_API void __cdecl win_sparkle_set_last_check_time(time_t lastCheckTime) +{ + try + { + Settings::WriteConfigValue("LastCheckTime", lastCheckTime); + } + CATCH_ALL_EXCEPTIONS +} + WIN_SPARKLE_API void __cdecl win_sparkle_set_error_callback(win_sparkle_error_callback_t callback) { try diff --git a/src/settings.cpp b/src/settings.cpp index bcd6c331..0318b8ea 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -169,9 +169,6 @@ std::string Settings::GetCustomResource(const char *name, const char *type) std::string Settings::GetDefaultRegistryPath() { std::string s("Software\\"); - std::wstring vendor = Settings::GetCompanyName(); - if ( !vendor.empty() ) - s += WideToAnsi(vendor) + "\\"; s += WideToAnsi(Settings::GetAppName()); s += "\\WinSparkle"; diff --git a/src/settings.h b/src/settings.h index 4dcea637..e1133f83 100644 --- a/src/settings.h +++ b/src/settings.h @@ -290,6 +290,8 @@ class Settings // Deletes value from registry. static void DeleteConfigValue(const char *name); + static const int MIN_CHECK_INTERVAL = 300; // 5 minutes + //@} private: diff --git a/src/ui.cpp b/src/ui.cpp index e16697ad..ea632ff5 100644 --- a/src/ui.cpp +++ b/src/ui.cpp @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -69,6 +70,11 @@ #define ERROR_RESOURCE_ENUM_USER_STOP 15106 #endif +const int DOWNLOAD_NOW = 0; +const int REMIND_ONE_HOUR = 1; +const int REMIND_ONE_DAY = 2; +const int REMIND_ONE_WEEK = 3; + namespace winsparkle { @@ -329,8 +335,6 @@ WinSparkleDialog::WinSparkleDialog() wxSize dpi = wxClientDC(this).GetPPI(); m_scaleFactor = dpi.y / 96.0; - SetIcon(LoadNamedIcon(UI::GetDllHINSTANCE(), L"UpdateAvailable", GetSystemMetrics(SM_CXSMICON))); - wxSizer *topSizer = new wxBoxSizer(wxHORIZONTAL); // Load the dialog box icon: the first 48x48 application icon will be loaded, if available, @@ -392,7 +396,6 @@ void WinSparkleDialog::SetHeadingFont(wxWindow *win) // 9pt is base font, 12pt is for "Main instructions". See // http://msdn.microsoft.com/en-us/library/aa511282%28v=MSDN.10%29.aspx f.SetPointSize(f.GetPointSize() + 3); - win->SetForegroundColour(wxColour(0x00, 0x33, 0x99)); } else // Windows XP/2000 { @@ -408,9 +411,8 @@ void WinSparkleDialog::SetHeadingFont(wxWindow *win) Window for communicating with the user *--------------------------------------------------------------------------*/ -const int ID_SKIP_VERSION = wxNewId(); -const int ID_REMIND_LATER = wxNewId(); -const int ID_INSTALL = wxNewId(); +const int ID_REMIND_OPTIONS = wxNewId(); +const int ID_DOWNLOAD = wxNewId(); const int ID_RUN_INSTALLER = wxNewId(); class UpdateDialog : public WinSparkleDialog @@ -439,9 +441,7 @@ class UpdateDialog : public WinSparkleDialog void OnCloseButton(wxCommandEvent& event); void OnClose(wxCloseEvent& event); - void OnSkipVersion(wxCommandEvent&); - void OnRemindLater(wxCommandEvent&); - void OnInstall(wxCommandEvent&); + void OnDownload(wxCommandEvent&); void OnRunInstaller(wxCommandEvent&); @@ -465,6 +465,7 @@ class UpdateDialog : public WinSparkleDialog wxSizer *m_updateButtonsSizer; wxSizer *m_releaseNotesSizer; wxPanel *m_browserParent; + wxChoice *m_remindChoiceList; wxAutoOleInterface m_webBrowser; @@ -474,7 +475,7 @@ class UpdateDialog : public WinSparkleDialog wxString m_updateFile; // space separated arguments to update file (only valid after StateUpdateDownloaded) std::string m_installerArguments; - // downloader (only valid between OnInstall and OnUpdateDownloaded) + // downloader (only valid between OnDownload and OnUpdateDownloaded) UpdateDownloader* m_downloader; // whether the update should be installed without prompting the user bool m_installAutomatically; @@ -533,21 +534,16 @@ UpdateDialog::UpdateDialog() m_buttonSizer = new wxBoxSizer(wxHORIZONTAL); + const wxString REMIND_OPTIONS[] = { L"Download now", L"Remind me in an hour", L"Remind me tomorrow", L"Remind me in a week" }; + m_remindChoiceList = new wxChoice(this, ID_REMIND_OPTIONS, wxDefaultPosition, wxDefaultSize, sizeof(REMIND_OPTIONS)/sizeof(REMIND_OPTIONS[0]), REMIND_OPTIONS); + m_remindChoiceList->SetSelection(DOWNLOAD_NOW); + m_updateButtonsSizer = new wxBoxSizer(wxHORIZONTAL); - m_updateButtonsSizer->Add - ( - new wxButton(this, ID_SKIP_VERSION, _("Skip this version")), - wxSizerFlags().Border(wxRIGHT, PX(20)) - ); m_updateButtonsSizer->AddStretchSpacer(1); + m_updateButtonsSizer->Add(m_remindChoiceList, wxSizerFlags().Border(wxRIGHT, PX(20))); m_updateButtonsSizer->Add ( - new wxButton(this, ID_REMIND_LATER, _("Remind me later")), - wxSizerFlags().Border(wxRIGHT, PX(10)) - ); - m_updateButtonsSizer->Add - ( - m_installButton = new wxButton(this, ID_INSTALL, _("Install update")), + m_installButton = new wxButton(this, ID_DOWNLOAD, _("OK")), wxSizerFlags() ); m_buttonSizer->Add(m_updateButtonsSizer, wxSizerFlags(1)); @@ -576,9 +572,7 @@ UpdateDialog::UpdateDialog() Bind(wxEVT_CLOSE_WINDOW, &UpdateDialog::OnClose, this); Bind(wxEVT_TIMER, &UpdateDialog::OnTimer, this); Bind(wxEVT_COMMAND_BUTTON_CLICKED, &UpdateDialog::OnCloseButton, this, wxID_CANCEL); - Bind(wxEVT_COMMAND_BUTTON_CLICKED, &UpdateDialog::OnSkipVersion, this, ID_SKIP_VERSION); - Bind(wxEVT_COMMAND_BUTTON_CLICKED, &UpdateDialog::OnRemindLater, this, ID_REMIND_LATER); - Bind(wxEVT_COMMAND_BUTTON_CLICKED, &UpdateDialog::OnInstall, this, ID_INSTALL); + Bind(wxEVT_COMMAND_BUTTON_CLICKED, &UpdateDialog::OnDownload, this, ID_DOWNLOAD); Bind(wxEVT_COMMAND_BUTTON_CLICKED, &UpdateDialog::OnRunInstaller, this, ID_RUN_INSTALLER); } @@ -633,36 +627,47 @@ void UpdateDialog::OnClose(wxCloseEvent&) } -void UpdateDialog::OnSkipVersion(wxCommandEvent&) +void UpdateDialog::OnDownload(wxCommandEvent&) { - Settings::WriteConfigValue("SkipThisVersion", m_appcast.Version); - Close(); -} - + static const int ONE_HOUR_IN_SECONDS = 3600; + static const int ONE_DAY_IN_SECONDS = 86400; + static const int ONE_WEEK_IN_SECONDS = 604800; + int currentSelection = m_remindChoiceList->GetCurrentSelection(); -void UpdateDialog::OnRemindLater(wxCommandEvent&) -{ - // Just abort the update. Next time it's scheduled to run, - // the user will be prompted. - Close(); -} - - -void UpdateDialog::OnInstall(wxCommandEvent&) -{ - if ( !m_appcast.HasDownload() ) - { - wxLaunchDefaultBrowser(m_appcast.WebBrowserURL, wxBROWSER_NEW_WINDOW); - Close(); - } - else if ( m_downloader == NULL ) + int updateInterval = ONE_DAY_IN_SECONDS; + switch (currentSelection) { - StateDownloading(); + case DOWNLOAD_NOW: + if (!m_appcast.HasDownload()) + { + wxLaunchDefaultBrowser(m_appcast.WebBrowserURL, wxBROWSER_NEW_WINDOW); + Close(); + } + else if (m_downloader == NULL) + { + StateDownloading(); - // Run the download in background. - m_downloader = new UpdateDownloader(m_appcast); - m_downloader->Start(); + // Run the download in background. + m_downloader = new UpdateDownloader(m_appcast); + m_downloader->Start(); + } + return; + case REMIND_ONE_HOUR: + updateInterval = ONE_HOUR_IN_SECONDS; + break; + case REMIND_ONE_DAY: + updateInterval = ONE_DAY_IN_SECONDS; + break; + case REMIND_ONE_WEEK: + updateInterval = ONE_WEEK_IN_SECONDS; + break; + default: + updateInterval = ONE_DAY_IN_SECONDS; + break; } + + Settings::WriteConfigValue("UpdateInterval", updateInterval); + Close(); } void UpdateDialog::OnRunInstaller(wxCommandEvent&) @@ -757,27 +762,12 @@ void UpdateDialog::StateNoUpdateFound(bool installAutomatically) LayoutChangesGuard guard(this); - m_heading->SetLabel(_("You're up to date!")); - - wxString msg; - try - { - msg = wxString::Format - ( - _("%s %s is currently the newest version available."), - Settings::GetAppName(), - Settings::GetAppVersion() - ); - } - catch ( std::exception& ) - { - // GetAppVersion() may fail - msg = "Error: Updates checking not properly configured."; - } + m_heading->SetLabel(_("You are up to date!")); + wxString msg = _("There are no new versions available at this time."); SetMessage(msg); - m_closeButton->SetLabel(_("Close")); + m_closeButton->SetLabel(_("OK")); m_closeButton->SetDefault(); EnablePulsing(false); @@ -812,7 +802,7 @@ void UpdateDialog::StateUpdateError(ErrorCode err) } SetMessage(msg); - m_closeButton->SetLabel(_("Cancel")); + m_closeButton->SetLabel(_("OK")); m_closeButton->SetDefault(); EnablePulsing(false); @@ -836,7 +826,7 @@ void UpdateDialog::StateUpdateAvailable(const Appcast& info, bool installAutomat if ( installAutomatically ) { wxCommandEvent nullEvent; - OnInstall(nullEvent); + OnDownload(nullEvent); return; } @@ -867,8 +857,8 @@ void UpdateDialog::StateUpdateAvailable(const Appcast& info, bool installAutomat ( wxString::Format ( - _("%s %s is now available (you have %s). Would you like to download it now?"), - appname, ver_new, ver_my + _("You are currently using %s version %s.\nWould you like to download our new version (%s) now?"), + appname, ver_my, ver_new ), showRelnotes ? RELNOTES_WIDTH : MESSAGE_AREA_WIDTH ); @@ -1030,10 +1020,14 @@ void UpdateDialog::ShowReleaseNotes(const Appcast& info) if( !info.ReleaseNotesURL.empty() ) { + VARIANT varFlags; + varFlags.vt = VT_I4; + varFlags.llVal = (navNoHistory | navNoReadFromCache | navNoWriteToCache); + m_webBrowser->Navigate ( wxBasicString(info.ReleaseNotesURL), - NULL, // Flags + &varFlags, // Flags NULL, // TargetFrameName NULL, // PostData NULL // Headers diff --git a/src/updatechecker.cpp b/src/updatechecker.cpp index 51ef4641..29fcf06c 100644 --- a/src/updatechecker.cpp +++ b/src/updatechecker.cpp @@ -286,9 +286,8 @@ void PeriodicUpdateChecker::Run() while (true) { - // time to wait for next iteration: either a reasonable default or - // time to next scheduled update check if checks are enabled - unsigned sleepTimeInSeconds = 60 * 60; // 1 hour + // time to wait for next iteration, set to a constant default so that on-the-fly changes are respected + const unsigned sleepTimeInSeconds = Settings::MIN_CHECK_INTERVAL; // 5 minutes bool checkUpdates; Settings::ReadConfigValue("CheckForUpdates", checkUpdates, false); @@ -299,17 +298,11 @@ void PeriodicUpdateChecker::Run() time_t lastCheck = 0; Settings::ReadConfigValue("LastCheckTime", lastCheck); - // Only check for updates in reasonable intervals: const int interval = win_sparkle_get_update_check_interval(); time_t nextCheck = lastCheck + interval; if (currentTime >= nextCheck) { PerformUpdateCheck(); - sleepTimeInSeconds = interval; - } - else - { - sleepTimeInSeconds = unsigned(nextCheck - currentTime); } }