Index: common/versionNumber.h =================================================================== --- common/versionNumber.h (revision 15514) +++ common/versionNumber.h (working copy) @@ -18,6 +18,6 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 30 #define VER_MINOR 00 -#define VER_MINORMINOR 47 +#define VER_MINORMINOR 46 OPENMPT_NAMESPACE_END Index: mptrack/Mainbar.cpp =================================================================== --- mptrack/Mainbar.cpp (revision 15514) +++ mptrack/Mainbar.cpp (working copy) @@ -132,7 +132,7 @@ // Play Command #define PLAYCMD_INDEX 10 #define TOOLBAR_IMAGE_PAUSE 8 -#define TOOLBAR_IMAGE_PLAY 12 +#define TOOLBAR_IMAGE_PLAY 13 // Base octave #define EDITOCTAVE_INDEX 13 #define EDITOCTAVE_WIDTH SCALEWIDTH(55) @@ -177,7 +177,7 @@ #define SPINRPB_WIDTH SCALEWIDTH(16) #define SPINRPB_HEIGHT (EDITRPB_HEIGHT) // VU Meters -#define VUMETER_INDEX (SPINRPB_INDEX+5) +#define VUMETER_INDEX (SPINRPB_INDEX+6) #define VUMETER_WIDTH SCALEWIDTH(255) #define VUMETER_HEIGHT SCALEHEIGHT(19) @@ -215,6 +215,7 @@ ID_SEPARATOR, ID_VIEW_OPTIONS, ID_PANIC, + ID_INTERNETUPDATE, ID_SEPARATOR, ID_SEPARATOR, // VU Meter }; @@ -339,6 +340,9 @@ SetBaseOctave(4); SetCurrentSong(nullptr); EnableDocking(CBRS_ALIGN_ANY); + + GetToolBarCtrl().SetState(ID_INTERNETUPDATE, TBSTATE_HIDDEN); + return TRUE; } @@ -454,8 +458,110 @@ } + +BEGIN_MESSAGE_MAP(UpdateToolTip, CToolTipCtrl) + ON_WM_LBUTTONUP() + ON_NOTIFY_REFLECT(TTN_POP, &UpdateToolTip::OnPop) + ON_NOTIFY_REFLECT(TTN_SHOW, &UpdateToolTip::OnShow) + ON_NOTIFY_REFLECT(TTN_LINKCLICK, &UpdateToolTip::OnLinkClick) +END_MESSAGE_MAP() + + +bool UpdateToolTip::ShowUpdate(CWnd &parent, const CString &newVersion, const CRect rectClient, const CPoint ptScreen, const int buttonID) +{ + if(m_hWnd) + DestroyWindow(); + Create(&parent, TTS_NOPREFIX | TTS_BALLOON | TTS_CLOSE | TTS_NOFADE); + + CString message = MPT_CFORMAT("OpenMPT {} has been released.\nClick here to see what's new.")(newVersion); + TOOLINFO ti{}; + ti.cbSize = TTTOOLINFO_V1_SIZE; + ti.uFlags = TTF_TRACK | TTF_PARSELINKS; + ti.hwnd = parent; + ti.lpszText = message.GetBuffer(); + ti.uId = buttonID; + ti.rect = rectClient; + if(!SendMessage(TTM_ADDTOOL, 0, reinterpret_cast(&ti))) + return false; + + SetTitle(TTI_INFO, _T("Update Available")); + SendMessage(TTM_TRACKPOSITION, 0, static_cast(MAKELONG(ptScreen.x, ptScreen.y))); + SendMessage(TTM_TRACKACTIVATE, TRUE, reinterpret_cast(&ti)); + return true; +} + + +void UpdateToolTip::SetResult(PopAction action) +{ + m_popAction = action; + SendMessage(TTM_TRACKACTIVATE, FALSE, 0); + if(action != PopAction::CloseButton && action != PopAction::Undetermined) + CMainFrame::GetMainFrame()->SendMessage(WM_MOD_UPDATENOTIFY, static_cast(action)); +} + + +void UpdateToolTip::OnLButtonUp(UINT nFlags, CPoint point) +{ + CToolTipCtrl::OnLButtonUp(nFlags, point); + if(m_popAction == PopAction::Undetermined) + { + SetResult(m_popAction); + } +} + + +void UpdateToolTip::OnPop(NMHDR *pNMHDR, LRESULT *) +{ + if(pNMHDR->idFrom == UINT_PTR(-1)) + SetResult(PopAction::CloseButton); +} + + +void UpdateToolTip::OnShow(NMHDR *, LRESULT *) +{ + m_popAction = PopAction::Undetermined; +} + + +void UpdateToolTip::OnLinkClick(NMHDR *, LRESULT *) +{ + SetResult(PopAction::ClickLink); +} + + +bool CMainToolBar::ShowUpdateInfo(const CString &newVersion) +{ + GetToolBarCtrl().SetState(ID_INTERNETUPDATE, TBSTATE_ENABLED); + if(m_bVertical) + SetVertical(); + else + SetHorizontal(); + + CRect rect; + GetToolBarCtrl().GetRect(ID_INTERNETUPDATE, &rect); + CPoint pt = rect.CenterPoint(); + ClientToScreen(&pt); + CMainFrame::GetMainFrame()->GetWindowRect(rect); + LimitMax(pt.x, rect.right); + + if(IsVisible()) + { + return m_tooltip.ShowUpdate(*this, newVersion, rect, pt, ID_INTERNETUPDATE); + } else + { + return false; + } +} + + BOOL CMainToolBar::SetCurrentSong(CSoundFile *pSndFile) { + static CSoundFile *sndFile = nullptr; + if(pSndFile != sndFile) + { + sndFile = pSndFile; + } + // Update Info if(pSndFile) { @@ -699,6 +805,7 @@ case ID_PLAYER_PLAYFROMSTART: s = _T("Play From Start"); cmd = kcPlaySongFromStart; break; case ID_VIEW_OPTIONS: s = _T("Setup"); cmd = kcViewOptions; break; case ID_PANIC: s = _T("Stop all hanging VSTi and sample voices"); cmd = kcPanic; break; + case ID_INTERNETUPDATE: s = _T("A new update is available."); break; } if(s == nullptr) Index: mptrack/Mainbar.h =================================================================== --- mptrack/Mainbar.h (revision 15514) +++ mptrack/Mainbar.h (working copy) @@ -48,6 +48,32 @@ class CModTree; class CMainFrame; +class UpdateToolTip : public CToolTipCtrl +{ +public: + enum class PopAction + { + Undetermined, + CloseButton, + ClickLink, + ClickBubble, + }; +protected: + PopAction m_popAction = PopAction::Undetermined; + +public: + bool ShowUpdate(CWnd &parent, const CString &newVersion, const CRect rectClient, const CPoint ptScreen, const int buttonID); + +protected: + void SetResult(PopAction action); + + afx_msg void OnLButtonUp(UINT nFlags, CPoint point); + afx_msg void OnPop(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnShow(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnLinkClick(NMHDR *pNMHDR, LRESULT *pResult); + DECLARE_MESSAGE_MAP() +}; + class CToolBarEx: public CToolBar { protected: @@ -74,6 +100,7 @@ class CMainToolBar: public CToolBarEx { protected: + UpdateToolTip m_tooltip; CImageListEx m_ImageList, m_ImageListDisabled; CStatic m_EditTempo, m_EditSpeed, m_EditOctave, m_EditRowsPerBeat; CStatic m_StaticTempo, m_StaticSpeed, m_StaticRowsPerBeat; @@ -110,6 +137,8 @@ BOOL SetBaseOctave(UINT nOctave); BOOL SetCurrentSong(CSoundFile *pModDoc); + bool ShowUpdateInfo(const CString &newVersion); + protected: //{{AFX_MSG(CMainToolBar) afx_msg void OnVScroll(UINT, UINT, CScrollBar *); Index: mptrack/MainFrm.cpp =================================================================== --- mptrack/MainFrm.cpp (revision 15514) +++ mptrack/MainFrm.cpp (working copy) @@ -104,6 +104,7 @@ ON_MESSAGE(WM_MOD_MIDIMAPPING, &CMainFrame::OnViewMIDIMapping) ON_MESSAGE(WM_MOD_UPDATEVIEWS, &CMainFrame::OnUpdateViews) ON_MESSAGE(WM_MOD_SETMODIFIED, &CMainFrame::OnSetModified) + ON_MESSAGE(WM_MOD_UPDATENOTIFY, &CMainFrame::OnToolbarUpdateIndicatorClick) ON_COMMAND(ID_INTERNETUPDATE, &CMainFrame::OnInternetUpdate) ON_COMMAND(ID_HELP_SHOWSETTINGSFOLDER, &CMainFrame::OnShowSettingsFolder) #if defined(MPT_ENABLE_UPDATE) @@ -2605,13 +2606,22 @@ #if defined(MPT_ENABLE_UPDATE) +bool CMainFrame::ShowUpdateIndicator(const CString &releaseVersion, const CString &releaseDate, const CString &releaseURL) +{ + return m_wndToolBar.ShowUpdateInfo(releaseVersion); +} + + LRESULT CMainFrame::OnUpdateCheckStart(WPARAM wparam, LPARAM lparam) { - bool isAutoUpdate = CUpdateCheck::IsAutoUpdateFromMessage(wparam, lparam); + const bool isAutoUpdate = CUpdateCheck::IsAutoUpdateFromMessage(wparam, lparam); CString updateText = _T("Checking for updates..."); if(isAutoUpdate) { - SetHelpText(updateText); + if(!CanShowUpdateIndicator()) + { + SetHelpText(updateText); + } } else if(m_UpdateOptionsDialog) { m_UpdateOptionsDialog->SetDlgItemText(IDC_LASTUPDATE, updateText); @@ -2642,7 +2652,10 @@ CString updateText = MPT_CFORMAT("Checking for updates... {}%")(lparam); if(isAutoUpdate) { - SetHelpText(updateText); + if(!CanShowUpdateIndicator()) + { + SetHelpText(updateText); + } } else if(m_UpdateOptionsDialog) { m_UpdateOptionsDialog->SetDlgItemText(IDC_LASTUPDATE, updateText); @@ -2667,7 +2680,10 @@ CString updateText = _T("Checking for updates... Canceled."); if(isAutoUpdate) { - SetHelpText(updateText); + if(!CanShowUpdateIndicator()) + { + SetHelpText(updateText); + } } else if(m_UpdateOptionsDialog) { m_UpdateOptionsDialog->SetDlgItemText(IDC_LASTUPDATE, updateText); @@ -2682,7 +2698,10 @@ } if(isAutoUpdate) { - SetHelpText(_T("")); + if(!CanShowUpdateIndicator()) + { + SetHelpText(_T("")); + } } else if(m_UpdateOptionsDialog) { // nothing @@ -2696,11 +2715,15 @@ LRESULT CMainFrame::OnUpdateCheckFailure(WPARAM wparam, LPARAM lparam) { - bool isAutoUpdate = CUpdateCheck::IsAutoUpdateFromMessage(wparam, lparam); - CString updateText = MPT_CFORMAT("Checking for updates failed: {}")(CUpdateCheck::GetFailureMessage(wparam, lparam)); + const bool isAutoUpdate = CUpdateCheck::IsAutoUpdateFromMessage(wparam, lparam); + const CUpdateCheck::Error &error = CUpdateCheck::MessageAsError(wparam, lparam); + CString updateText = MPT_CFORMAT("Checking for updates failed: {}")(mpt::get_exception_text(error)); if(isAutoUpdate) { - SetHelpText(updateText); + if(!CanShowUpdateIndicator()) + { + SetHelpText(updateText); + } } else if(m_UpdateOptionsDialog) { m_UpdateOptionsDialog->SetDlgItemText(IDC_LASTUPDATE, updateText); @@ -2713,10 +2736,13 @@ g_UpdateCheckProgressDialog = nullptr; } } - CUpdateCheck::ShowFailureGUI(wparam, lparam); + CUpdateCheck::ShowFailureGUI(isAutoUpdate, error); if(isAutoUpdate) { - SetHelpText(_T("")); + if(!CanShowUpdateIndicator()) + { + SetHelpText(_T("")); + } } else if(m_UpdateOptionsDialog) { // nothing @@ -2730,14 +2756,16 @@ LRESULT CMainFrame::OnUpdateCheckSuccess(WPARAM wparam, LPARAM lparam) { - CUpdateCheck::AcknowledgeSuccess(wparam, lparam); - bool isAutoUpdate = CUpdateCheck::IsAutoUpdateFromMessage(wparam, lparam); + const bool isAutoUpdate = CUpdateCheck::IsAutoUpdateFromMessage(wparam, lparam); + const CUpdateCheck::Result & result = CUpdateCheck::MessageAsResult(wparam, lparam); + CUpdateCheck::AcknowledgeSuccess(result); CString updateText = _T("Checking for updates... Done."); - // TODO: - // UpdateToolbarUpdateIndicator(CUpdateCheck::ResultFromMessage(wparam, lparam)); if(isAutoUpdate) { - SetHelpText(updateText); + if(!CanShowUpdateIndicator()) + { + SetHelpText(updateText); + } } else if(m_UpdateOptionsDialog) { m_UpdateOptionsDialog->SetDlgItemText(IDC_LASTUPDATE, updateText); @@ -2750,25 +2778,28 @@ g_UpdateCheckProgressDialog = nullptr; } } - CUpdateCheck::ShowSuccessGUI(wparam, lparam); + CUpdateCheck::ShowSuccessGUI(isAutoUpdate, result); if(isAutoUpdate) { - SetHelpText(_T("")); + if(!CanShowUpdateIndicator()) + { + SetHelpText(_T("")); + } } else if(m_UpdateOptionsDialog) { // nothing } else { - // nothing + SetHelpText(_T("")); } return TRUE; } -void CMainFrame::OnToolbarUpdateIndicatorClick() +LPARAM CMainFrame::OnToolbarUpdateIndicatorClick(WPARAM, LPARAM) { - // TODO CUpdateCheck::DoManualUpdateCheck(); + return 0; } Index: mptrack/Mainfrm.h =================================================================== --- mptrack/Mainfrm.h (revision 15514) +++ mptrack/Mainfrm.h (working copy) @@ -61,6 +61,7 @@ WM_MOD_SETMODIFIED, WM_MOD_MDIACTIVATE, WM_MOD_MDIDEACTIVATE, + WM_MOD_UPDATENOTIFY, }; enum @@ -402,6 +403,11 @@ static CInputHandler* GetInputHandler() { return m_InputHandler; } void SetElapsedTime(double t) { m_dwTimeSec = static_cast(t); } +#if defined(MPT_ENABLE_UPDATE) + bool CanShowUpdateIndicator() const { return m_wndToolBar.IsVisible(); } + bool ShowUpdateIndicator(const CString &releaseVersion, const CString &releaseDate, const CString &releaseURL); +#endif // MPT_ENABLE_UPDATE + CModTree *GetUpperTreeview() { return m_wndTree.m_pModTree; } CModTree *GetLowerTreeview() { return m_wndTree.m_pModTreeData; } bool SetTreeSoundfile(FileReader &file) { return m_wndTree.SetTreeSoundfile(file); } @@ -546,7 +552,7 @@ afx_msg LRESULT OnUpdateCheckCanceled(WPARAM wparam, LPARAM lparam); afx_msg LRESULT OnUpdateCheckFailure(WPARAM wparam, LPARAM lparam); afx_msg LRESULT OnUpdateCheckSuccess(WPARAM wparam, LPARAM lparam); - afx_msg void OnToolbarUpdateIndicatorClick(); + afx_msg LRESULT OnToolbarUpdateIndicatorClick(WPARAM wparam, LPARAM lparam); #endif // MPT_ENABLE_UPDATE afx_msg void OnHelp(); afx_msg BOOL OnDeviceChange(UINT nEventType, DWORD_PTR dwData); Index: mptrack/res/main_toolbar.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = image/png Index: mptrack/UpdateCheck.cpp =================================================================== --- mptrack/UpdateCheck.cpp (revision 15514) +++ mptrack/UpdateCheck.cpp (working copy) @@ -1000,17 +1000,15 @@ } -CUpdateCheck::Result CUpdateCheck::ResultFromMessage(WPARAM /*wparam*/ , LPARAM lparam) +const CUpdateCheck::Result &CUpdateCheck::MessageAsResult(WPARAM /* wparam */ , LPARAM lparam) { - const CUpdateCheck::Result &result = *reinterpret_cast(lparam); - return result; + return *reinterpret_cast(lparam); } -CUpdateCheck::Error CUpdateCheck::ErrorFromMessage(WPARAM /*wparam*/ , LPARAM lparam) +const CUpdateCheck::Error &CUpdateCheck::MessageAsError(WPARAM /* wparam */ , LPARAM lparam) { - const CUpdateCheck::Error &error = *reinterpret_cast(lparam); - return error; + return *reinterpret_cast(lparam); } @@ -1471,10 +1469,8 @@ }; -void CUpdateCheck::AcknowledgeSuccess(WPARAM wparam, LPARAM lparam) +void CUpdateCheck::AcknowledgeSuccess(const CUpdateCheck::Result &result) { - MPT_UNREFERENCED_PARAMETER(wparam); - const CUpdateCheck::Result& result = *reinterpret_cast(lparam); if(result.CheckTime != time_t{}) { TrackerSettings::Instance().UpdateLastUpdateCheck = mpt::Date::Unix(result.CheckTime); @@ -1482,11 +1478,10 @@ } -void CUpdateCheck::ShowSuccessGUI(WPARAM wparam, LPARAM lparam) +void CUpdateCheck::ShowSuccessGUI(const bool &autoUpdate, const CUpdateCheck::Result &result) { - const CUpdateCheck::Result &result = *reinterpret_cast(lparam); - bool autoUpdate = wparam != 0; + bool modal = !autoUpdate || !CMainFrame::GetMainFrame()->CanShowUpdateIndicator(); #if MPT_UPDATE_LEGACY @@ -1494,14 +1489,24 @@ { if(result.UpdateAvailable && (!autoUpdate || result.Version != TrackerSettings::Instance().UpdateIgnoreVersion)) { - UpdateDialog dlg(result.Version, result.Date, result.URL); - if(dlg.DoModal() == IDOK) + if(!CMainFrame::GetMainFrame()->ShowUpdateIndicator(result.Version, result.Date, result.URL)) { - CTrackApp::OpenURL(result.URL); + modal = true; } + if(modal) + { + UpdateDialog dlg(result.Version, result.Date, result.URL); + if(dlg.DoModal() == IDOK) + { + CTrackApp::OpenURL(result.URL); + } + } } else if(!result.UpdateAvailable && !autoUpdate) { - Reporting::Information(U_("You already have the latest version of OpenMPT installed."), U_("OpenMPT Internet Update")); + if(modal) + { + Reporting::Information(U_("You already have the latest version of OpenMPT installed."), U_("OpenMPT Internet Update")); + } } return; } @@ -1515,7 +1520,10 @@ { if(!autoUpdate) { - Reporting::Information(U_("You already have the latest version of OpenMPT installed."), U_("OpenMPT Update")); + if(modal) + { + Reporting::Information(U_("You already have the latest version of OpenMPT installed."), U_("OpenMPT Update")); + } } return; } @@ -1537,6 +1545,7 @@ } else { + const TCHAR *action = _T("&View Announcement"); const bool canInstall = !updateInfo.download.empty() && versionInfo.downloads[updateInfo.download].can_autoupdate && (Version::Current() >= Version::Parse(versionInfo.downloads[updateInfo.download].autoupdate_minversion)); const bool canDownload = !canInstall && !updateInfo.download.empty() && !versionInfo.downloads[updateInfo.download].download_url.empty(); @@ -1548,6 +1557,20 @@ action = _T("&Download Now"); } + if(!CMainFrame::GetMainFrame()->ShowUpdateIndicator( + mpt::ToCString(versionInfo.version), + mpt::ToCString(versionInfo.date), + mpt::ToCString(versionInfo.changelog_url))) + { + // on failure to show tooltip, continue and show modal dialog + modal = true; + } + + if(!modal) + { + return; + } + UpdateDialog dlg( mpt::ToCString(versionInfo.version), mpt::ToCString(versionInfo.date), @@ -1576,19 +1599,8 @@ } -mpt::ustring CUpdateCheck::GetFailureMessage(WPARAM wparam, LPARAM lparam) +void CUpdateCheck::ShowFailureGUI(const bool &autoUpdate, const CUpdateCheck::Error &error) { - MPT_UNREFERENCED_PARAMETER(wparam); - const CUpdateCheck::Error &error = *reinterpret_cast(lparam); - return mpt::get_exception_text(error); -} - - - -void CUpdateCheck::ShowFailureGUI(WPARAM wparam, LPARAM lparam) -{ - const CUpdateCheck::Error &error = *reinterpret_cast(lparam); - bool autoUpdate = wparam != 0; if(!autoUpdate) { Reporting::Error(mpt::get_exception_text(error), U_("OpenMPT Update Error")); Index: mptrack/UpdateCheck.h =================================================================== --- mptrack/UpdateCheck.h (revision 15514) +++ mptrack/UpdateCheck.h (working copy) @@ -128,16 +128,14 @@ static bool IsAutoUpdateFromMessage(WPARAM wparam, LPARAM lparam); - static CUpdateCheck::Result ResultFromMessage(WPARAM wparam, LPARAM lparam); - static CUpdateCheck::Error ErrorFromMessage(WPARAM wparam, LPARAM lparam); + static const CUpdateCheck::Result &MessageAsResult(WPARAM wparam, LPARAM lparam); + static const CUpdateCheck::Error &MessageAsError(WPARAM wparam, LPARAM lparam); - static void AcknowledgeSuccess(WPARAM wparam, LPARAM lparam); + static void AcknowledgeSuccess(const CUpdateCheck::Result &result); - static void ShowSuccessGUI(WPARAM wparam, LPARAM lparam); - static void ShowFailureGUI(WPARAM wparam, LPARAM lparam); + static void ShowSuccessGUI(const bool &autoUpdate, const CUpdateCheck::Result &result); + static void ShowFailureGUI(const bool &autoUpdate, const CUpdateCheck::Error &error); - static mpt::ustring GetFailureMessage(WPARAM wparam, LPARAM lparam); - public: #if MPT_UPDATE_LEGACY