Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 5 additions & 40 deletions src/dll_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,47 +69,12 @@ WIN_SPARKLE_API void __cdecl win_sparkle_init()
// first things first
UpdateDownloader::CleanLeftovers();

// check for updates
bool checkUpdates;
if ( Settings::ReadConfigValue("CheckForUpdates", checkUpdates) )
{
if ( checkUpdates )
{
static const time_t ONE_DAY = 60*60*24;

time_t lastCheck = 0;
Settings::ReadConfigValue("LastCheckTime", lastCheck);
const time_t currentTime = time(NULL);

// Only check for updates in reasonable intervals:
const int interval = win_sparkle_get_update_check_interval();
if ( currentTime - lastCheck >= interval )
{
// Run the check in background. Only show UI if updates
// are available.
UpdateChecker *check = new UpdateChecker();
check->Start();
}
}
}
else // not yet configured
{
bool didRunOnce;
Settings::ReadConfigValue("DidRunOnce", didRunOnce, false);
if ( !didRunOnce )
{
// Do nothing on the first execution of the app, for better
// first-time impression.
Settings::WriteConfigValue("DidRunOnce", true);
}
else
{
// Only when the app is launched for the second time, ask the
// user for their permission to check for updates.
UI::AskForPermission();
}
}
// Run the check in background. Only show UI if updates
// are available.
UpdateChecker *check = new UpdateChecker();
check->Start();
}

CATCH_ALL_EXCEPTIONS
}

Expand Down
84 changes: 36 additions & 48 deletions src/ui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -320,13 +320,11 @@ class WinSparkleDialog : public wxDialog
WinSparkleDialog::WinSparkleDialog()
: wxDialog(NULL, wxID_ANY, _("Software Update"),
wxDefaultPosition, wxDefaultSize,
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxDIALOG_NO_PARENT)
wxDEFAULT_DIALOG_STYLE | wxDIALOG_NO_PARENT)
{
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,
Expand Down Expand Up @@ -388,7 +386,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
{
Expand All @@ -404,9 +401,9 @@ 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_HOUR = wxNewId();
const int ID_REMIND_TOMORROW = wxNewId();
const int ID_DOWNLOAD = wxNewId();
const int ID_RUN_INSTALLER = wxNewId();

class UpdateDialog : public WinSparkleDialog
Expand Down Expand Up @@ -435,9 +432,9 @@ class UpdateDialog : public WinSparkleDialog
void OnCloseButton(wxCommandEvent& event);
void OnClose(wxCloseEvent& event);

void OnSkipVersion(wxCommandEvent&);
void OnRemindLater(wxCommandEvent&);
void OnInstall(wxCommandEvent&);
void OnRemindOneHour(wxCommandEvent&);
void OnRemindTomorrow(wxCommandEvent&);
void OnDownload(wxCommandEvent&);

void OnRunInstaller(wxCommandEvent&);

Expand Down Expand Up @@ -470,7 +467,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;
Expand Down Expand Up @@ -532,20 +529,21 @@ UpdateDialog::UpdateDialog()
m_updateButtonsSizer = new wxBoxSizer(wxHORIZONTAL);
m_updateButtonsSizer->Add
(
new wxButton(this, ID_SKIP_VERSION, _("Skip this version")),
new wxButton(this, ID_REMIND_HOUR, _("Remind me in an hour")),
wxSizerFlags().Border(wxRIGHT, PX(20))
);
m_updateButtonsSizer->AddStretchSpacer(1);
m_updateButtonsSizer->Add
(
new wxButton(this, ID_REMIND_LATER, _("Remind me later")),
new wxButton(this, ID_REMIND_TOMORROW, _("Remind me tomorrow")),
wxSizerFlags().Border(wxRIGHT, PX(10))
);
m_updateButtonsSizer->Add
m_updateButtonsSizer->AddStretchSpacer(1);
m_updateButtonsSizer->Add
(
m_installButton = new wxButton(this, ID_INSTALL, _("Install update")),
m_installButton = new wxButton(this, ID_DOWNLOAD, _("Download")),
wxSizerFlags()
);
m_installButton->SetFocus();
m_buttonSizer->Add(m_updateButtonsSizer, wxSizerFlags(1));

m_closeButtonSizer = new wxBoxSizer(wxHORIZONTAL);
Expand All @@ -572,9 +570,9 @@ 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::OnRemindOneHour, this, ID_REMIND_HOUR);
Bind(wxEVT_COMMAND_BUTTON_CLICKED, &UpdateDialog::OnRemindTomorrow, this, ID_REMIND_TOMORROW);
Bind(wxEVT_COMMAND_BUTTON_CLICKED, &UpdateDialog::OnDownload, this, ID_DOWNLOAD);
Bind(wxEVT_COMMAND_BUTTON_CLICKED, &UpdateDialog::OnRunInstaller, this, ID_RUN_INSTALLER);
}

Expand Down Expand Up @@ -629,22 +627,23 @@ void UpdateDialog::OnClose(wxCloseEvent&)
}


void UpdateDialog::OnSkipVersion(wxCommandEvent&)
void UpdateDialog::OnRemindOneHour(wxCommandEvent&)
{
Settings::WriteConfigValue("SkipThisVersion", m_appcast.Version);
static const int ONE_HOUR_IN_SECONDS = 3600;
Settings::WriteConfigValue("UpdateInterval", ONE_HOUR_IN_SECONDS);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a default for UpdateInterval? I.e. what happens when neither of the Remind buttons are pushed and the X (close window) is used instead?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default is what we set in our application when we initialize Winsparkle (24 hours).
Beyond that, if the user clicks on Remind in an hour, then the next clicks the Close button, the update interval will be 1 hour. I explained this behavior to Amber and she was OK with it.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am good with this as long as it is UX approved. 🖖

Close();
}


void UpdateDialog::OnRemindLater(wxCommandEvent&)
void UpdateDialog::OnRemindTomorrow(wxCommandEvent&)
{
// Just abort the update. Next time it's scheduled to run,
// the user will be prompted.
static const int ONE_DAY_IN_SECONDS = 86400;
Settings::WriteConfigValue("UpdateInterval", ONE_DAY_IN_SECONDS);
Close();
}


void UpdateDialog::OnInstall(wxCommandEvent&)
void UpdateDialog::OnDownload(wxCommandEvent&)
{
if ( !m_appcast.HasDownload() )
{
Expand Down Expand Up @@ -753,27 +752,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);

Expand Down Expand Up @@ -823,7 +807,7 @@ void UpdateDialog::StateUpdateAvailable(const Appcast& info, bool installAutomat
if ( installAutomatically )
{
wxCommandEvent nullEvent;
OnInstall(nullEvent);
OnDownload(nullEvent);
return;
}

Expand Down Expand Up @@ -854,8 +838,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
);
Expand Down Expand Up @@ -1003,10 +987,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
Expand Down Expand Up @@ -1071,7 +1059,7 @@ void UpdateDialog::ShowReleaseNotes(const Appcast& info)
}
}

SetWindowStyleFlag(wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER);
SetWindowStyleFlag(wxDEFAULT_DIALOG_STYLE);
}


Expand Down
38 changes: 36 additions & 2 deletions src/updatechecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include <vector>
#include <cstdlib>
#include <algorithm>
#include <winsparkle.h>

using namespace std;

Expand Down Expand Up @@ -219,9 +220,35 @@ UpdateChecker::UpdateChecker(): Thread("WinSparkle updates check")

void UpdateChecker::Run()
{
// no initialization to do, so signal readiness immediately
SignalReady();
while (1)
{
// no initialization to do, so signal readiness immediately
SignalReady();

bool checkUpdates;
if (Settings::ReadConfigValue("CheckForUpdates", checkUpdates))
{
if (checkUpdates)
{
time_t lastCheck = 0;
Settings::ReadConfigValue("LastCheckTime", lastCheck);
const time_t currentTime = time(NULL);

// Only check for updates in reasonable intervals:
const int interval = win_sparkle_get_update_check_interval();
if (currentTime - lastCheck >= interval)
{
UpdateCheckWorker();
}
}
}
// Check every 5 minutes
Sleep(win_sparkle_get_update_check_interval());
}
}

void UpdateChecker::UpdateCheckWorker()
{
try
{
const std::string url = Settings::GetAppcastURL();
Expand Down Expand Up @@ -302,4 +329,11 @@ bool ManualUpdateChecker::ShouldSkipUpdate(const Appcast&) const
return false;
}

void ManualUpdateChecker::Run()
{
// no initialization to do, so signal readiness immediately
SignalReady();

UpdateCheckWorker();
}
} // namespace winsparkle
2 changes: 2 additions & 0 deletions src/updatechecker.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ class UpdateChecker : public Thread

protected:
virtual void Run();
virtual void UpdateCheckWorker();
virtual bool IsJoinable() const { return false; }
};

Expand All @@ -87,6 +88,7 @@ class ManualUpdateChecker : public UpdateChecker
protected:
virtual int GetAppcastDownloadFlags() const;
virtual bool ShouldSkipUpdate(const Appcast& appcast) const;
void Run();
};


Expand Down