diff --git a/win-linux/defaults.pri b/win-linux/defaults.pri index 7d4309038..f337418c6 100644 --- a/win-linux/defaults.pri +++ b/win-linux/defaults.pri @@ -241,13 +241,18 @@ core_windows { $$PWD/src/windows/platform_win/csnap.h \ $$PWD/src/windows/platform_win/caption.h \ $$PWD/src/platform_win/singleapplication.h \ - $$PWD/src/platform_win/filechooser.h + $$PWD/src/platform_win/filechooser.h \ + $$PWD/src/platform_win/resource.h SOURCES += $$PWD/src/windows/platform_win/cwindowplatform.cpp \ $$PWD/src/windows/platform_win/csnap.cpp \ $$PWD/src/platform_win/singleapplication.cpp \ $$PWD/src/platform_win/filechooser.cpp + updmodule { + HEADERS += $$PWD/src/platform_win/updatedialog.h + SOURCES += $$PWD/src/platform_win/updatedialog.cpp + } LIBS += -lwininet \ -ldnsapi \ diff --git a/win-linux/src/cascapplicationmanagerwrapper.cpp b/win-linux/src/cascapplicationmanagerwrapper.cpp index f9698363a..7b2df4ada 100644 --- a/win-linux/src/cascapplicationmanagerwrapper.cpp +++ b/win-linux/src/cascapplicationmanagerwrapper.cpp @@ -16,6 +16,7 @@ #include "cstyletweaks.h" #include "defines.h" +#include "version.h" #include "components/cfiledialog.h" #include "utils.h" #include "common/Types.h" @@ -31,6 +32,9 @@ # include # include # include "platform_win/singleapplication.h" +# if defined(_UPDMODULE) && !defined(__OS_WIN_XP) +# include "platform_win/updatedialog.h" +# endif #else # include # include "platform_linux/singleapplication.h" @@ -1958,14 +1962,31 @@ void CAscApplicationManagerWrapper::showUpdateMessage(bool error, bool updateExi auto msg = [=]() { gotoMainWindow(); QTimer::singleShot(100, this, [=](){ +# ifdef _WIN32 + int result = WinDlg::showDialog(mainWindow()->handle(), + tr("A new version of ONLYOFFICE Desktop Editors is available!"), + tr("ONLYOFFICE Desktop Editors %1 is now available (you have %2). " + "Would you like to download it now?").arg(m_pUpdateManager->getVersion(), + QString::fromLatin1(VER_FILEVERSION_STR)), + WinDlg::DlgBtns::mbSkipRemindDownload); + + switch (result) { + case WinDlg::DLG_RESULT_DOWNLOAD: + m_pUpdateManager->loadUpdates(); + break; + case WinDlg::DLG_RESULT_SKIP: { + m_pUpdateManager->skipVersion(); + AscAppManager::sendCommandTo(0, "updates:checking", "{\"version\":\"no\"}"); + break; + } + default: + break; + } +# else CMessage mbox(mainWindow()->handle(), CMessageOpts::moButtons::mbYesDefSkipNo); switch (mbox.info(tr("Do you want to install a new version %1 of the program?").arg(version))) { case MODAL_RESULT_CUSTOM + 0: -#ifdef Q_OS_WIN - m_pUpdateManager->loadUpdates(); -#else QDesktopServices::openUrl(QUrl(DOWNLOAD_PAGE, QUrl::TolerantMode)); -#endif break; case MODAL_RESULT_CUSTOM + 1: { m_pUpdateManager->skipVersion(); @@ -1975,6 +1996,7 @@ void CAscApplicationManagerWrapper::showUpdateMessage(bool error, bool updateExi default: break; } +# endif }); }; @@ -2004,16 +2026,19 @@ void CAscApplicationManagerWrapper::showStartInstallMessage() { gotoMainWindow(); AscAppManager::sendCommandTo(0, "updates:download", "{\"progress\":\"done\"}"); - CMessage mbox(mainWindow()->handle(), CMessageOpts::moButtons::mbYesDefSkipNo); - switch (mbox.info(tr("Do you want to install a new version of the program?\n" - "To continue the installation, you must to close current session."))) - { - case MODAL_RESULT_CUSTOM + 0: { + int result = WinDlg::showDialog(mainWindow()->handle(), + tr("A new version of ONLYOFFICE Desktop Editors is available!"), + tr("ONLYOFFICE Desktop Editors %1 is now downloaded (you have %2). " + "Would you like to install it now?").arg(m_pUpdateManager->getVersion(), + QString::fromLatin1(VER_FILEVERSION_STR)), + WinDlg::DlgBtns::mbSkipRemindSaveandinstall); + switch (result) { + case WinDlg::DLG_RESULT_INSTALL: { m_pUpdateManager->scheduleRestartForUpdate(); mainWindow()->close(); break; } - case MODAL_RESULT_CUSTOM + 1: { + case WinDlg::DLG_RESULT_SKIP: { m_pUpdateManager->skipVersion(); AscAppManager::sendCommandTo(0, "updates:checking", "{\"version\":\"no\"}"); break; diff --git a/win-linux/src/cupdatemanager.cpp b/win-linux/src/cupdatemanager.cpp index ebd29f4d1..4e57ae581 100644 --- a/win-linux/src/cupdatemanager.cpp +++ b/win-linux/src/cupdatemanager.cpp @@ -389,7 +389,7 @@ int CUpdateManager::getUpdateMode() { GET_REGISTRY_USER(reg_user); #ifdef _WIN32 - const QString mode = reg_user.value("autoUpdateMode", "silent").toString(); + const QString mode = reg_user.value("autoUpdateMode", "ask").toString(); return (mode == "silent") ? UpdateMode::SILENT : (mode == "ask") ? UpdateMode::ASK : UpdateMode::DISABLE; diff --git a/win-linux/src/platform_win/resource.h b/win-linux/src/platform_win/resource.h new file mode 100644 index 000000000..6416ebb85 --- /dev/null +++ b/win-linux/src/platform_win/resource.h @@ -0,0 +1 @@ +#define IDI_MAINICON 101 diff --git a/win-linux/src/platform_win/updatedialog.cpp b/win-linux/src/platform_win/updatedialog.cpp new file mode 100644 index 000000000..828618ab1 --- /dev/null +++ b/win-linux/src/platform_win/updatedialog.cpp @@ -0,0 +1,181 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2019 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#include +#include "updatedialog.h" +#include "platform_win/resource.h" +#include +#include +#include +#include + +#define RELEASE_NOTES "https://github.com/ONLYOFFICE/DesktopEditors/blob/master/CHANGELOG.md" +#define toWCharPtr(qstr) _wcsdup(qstr.toStdWString().c_str()) +#define TEXT_SKIP toWCharPtr(QObject::tr("Skip this version")) +#define TEXT_REMIND toWCharPtr(QObject::tr("Remind me later")) +#define TEXT_INSTALL toWCharPtr(QObject::tr("Install update")) +#define TEXT_INSLATER toWCharPtr(QObject::tr("Install on Next Start")) +#define TEXT_RESTART toWCharPtr(QObject::tr("Save and Restart Now")) +#define TEXT_SAVEANDINS toWCharPtr(QObject::tr("Save and Install Now")) +#define TEXT_DOWNLOAD toWCharPtr(QObject::tr("Download update")) + + +static void BringToTop(HWND hwnd) +{ + DWORD appID = ::GetCurrentThreadId(); + DWORD frgID = ::GetWindowThreadProcessId(::GetForegroundWindow(), NULL); + ::AttachThreadInput(frgID, appID, TRUE); + ::SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); + ::SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE); + ::SetForegroundWindow(hwnd); + ::SetFocus(hwnd); + ::SetActiveWindow(hwnd); + ::AttachThreadInput(frgID, appID, FALSE); +} + +static HRESULT Pftaskdialogcallback(HWND hwnd, UINT msg, WPARAM wParam, + LPARAM lParam, LONG_PTR lpRefData) +{ + switch (msg) { + case TDN_HYPERLINK_CLICKED: + ShellExecute(NULL, L"open", (PCWSTR)lParam, NULL, NULL, SW_SHOWNORMAL); + break; + case TDN_DIALOG_CONSTRUCTED: { + QTimer::singleShot(0, [=]() { + if (hwnd) + BringToTop(hwnd); + }); + break; + } + default: + break; + } + return S_OK; +} + +int WinDlg::showDialog(QWidget *parent, + const QString &msg, + const QString &content, + DlgBtns dlgBtns) +{ + std::wstring lpCaption = QString(" %1").arg(QObject::tr("Software Update")).toStdWString(); + std::wstring lpText = QTextDocumentFragment::fromHtml(msg).toPlainText().toStdWString(); + std::wstring lpContent = QString("%1\n\n%3") + .arg(content, RELEASE_NOTES, QObject::tr("Release notes")).toStdWString(); + HWND parent_hwnd = (parent) ? (HWND)parent->winId() : NULL; + + int msgboxID = 0; + PCWSTR pIcon = MAKEINTRESOURCE(IDI_MAINICON); + TASKDIALOG_BUTTON *pButtons = NULL; + uint cButtons = 0; + switch (dlgBtns) { + case DlgBtns::mbInslaterRestart: + cButtons = 2; + pButtons = new TASKDIALOG_BUTTON[cButtons]; + pButtons[0] = {IDYES, TEXT_INSLATER}; + pButtons[1] = {IDNO, TEXT_RESTART}; + break; + case DlgBtns::mbSkipRemindInstall: + cButtons = 3; + pButtons = new TASKDIALOG_BUTTON[cButtons]; + pButtons[0] = {IDRETRY, TEXT_SKIP}; + pButtons[1] = {IDNO, TEXT_REMIND}; + pButtons[2] = {IDYES, TEXT_INSTALL}; + break; + case DlgBtns::mbSkipRemindSaveandinstall: + cButtons = 3; + pButtons = new TASKDIALOG_BUTTON[cButtons]; + pButtons[0] = {IDRETRY, TEXT_SKIP}; + pButtons[1] = {IDNO, TEXT_REMIND}; + pButtons[2] = {IDYES, TEXT_SAVEANDINS}; + break; + case DlgBtns::mbSkipRemindDownload: + cButtons = 3; + pButtons = new TASKDIALOG_BUTTON[cButtons]; + pButtons[0] = {IDRETRY, TEXT_SKIP}; + pButtons[1] = {IDNO, TEXT_REMIND}; + pButtons[2] = {IDYES, TEXT_DOWNLOAD}; + break; + default: + break; + } + + int nDefltBtn{0}; + switch (dlgBtns) { + case DlgBtns::mbInslaterRestart: nDefltBtn = IDNO; break; + case DlgBtns::mbSkipRemindInstall: nDefltBtn = IDYES; break; + case DlgBtns::mbSkipRemindSaveandinstall: nDefltBtn = IDYES; break; + case DlgBtns::mbSkipRemindDownload: nDefltBtn = IDYES; break; + default: break; + } + + TASKDIALOGCONFIG config = {0}; + ZeroMemory(&config, sizeof(config)); + config.cbSize = sizeof(config); + config.dwFlags = TDF_ENABLE_HYPERLINKS | + TDF_POSITION_RELATIVE_TO_WINDOW | + TDF_ALLOW_DIALOG_CANCELLATION; + config.hwndParent = parent_hwnd; + config.hInstance = GetModuleHandle(NULL); + config.pfCallback = Pftaskdialogcallback; + config.pButtons = pButtons; + config.cButtons = cButtons; + config.nDefaultButton = nDefltBtn; + config.pszMainIcon = pIcon; + config.pszWindowTitle = lpCaption.c_str(); + config.pszMainInstruction = lpText.c_str(); + config.pszContent = lpContent.c_str(); + config.cxWidth = 240; + + TaskDialogIndirect(&config, &msgboxID, NULL, NULL); + for (int i = 0; i < (int)cButtons; i++) + free((void*)pButtons[i].pszButtonText); + delete[] pButtons; + + int result = -1; + switch (msgboxID) { + case IDYES: result = (dlgBtns == DlgBtns::mbSkipRemindInstall || + dlgBtns == DlgBtns::mbSkipRemindSaveandinstall) ? DLG_RESULT_INSTALL : + (dlgBtns == DlgBtns::mbSkipRemindDownload) ? DLG_RESULT_DOWNLOAD : + DLG_RESULT_INSLATER; break; + case IDNO: result = (dlgBtns == DlgBtns::mbSkipRemindInstall || + dlgBtns == DlgBtns::mbSkipRemindSaveandinstall || + dlgBtns == DlgBtns::mbSkipRemindDownload) ? DLG_RESULT_REMIND : + DLG_RESULT_RESTART; break; + case IDRETRY: result = DLG_RESULT_SKIP; break; + case IDCANCEL: + default: + break; + } + + return result; +} diff --git a/win-linux/src/platform_win/updatedialog.h b/win-linux/src/platform_win/updatedialog.h new file mode 100644 index 000000000..447f915f7 --- /dev/null +++ b/win-linux/src/platform_win/updatedialog.h @@ -0,0 +1,64 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2019 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#ifndef UPDATEDIALOG_H +#define UPDATEDIALOG_H + +#include +#include + + +namespace WinDlg +{ +enum class DlgBtns { + mbSkipRemindInstall = 0, + mbSkipRemindSaveandinstall, + mbSkipRemindDownload, + mbInslaterRestart +}; + +enum DlgRes { + DLG_RESULT_SKIP = 0, + DLG_RESULT_REMIND, + DLG_RESULT_DOWNLOAD, + DLG_RESULT_INSTALL, + DLG_RESULT_INSLATER, + DLG_RESULT_RESTART +}; + +int showDialog(QWidget *parent, + const QString &msg, + const QString &content, + DlgBtns dlgBtns = DlgBtns::mbSkipRemindInstall); +} + +#endif // UPDATEDIALOG_H diff --git a/win-linux/src/prop/cmainwindowimpl.cpp b/win-linux/src/prop/cmainwindowimpl.cpp index 9b19406ae..081a7887c 100644 --- a/win-linux/src/prop/cmainwindowimpl.cpp +++ b/win-linux/src/prop/cmainwindowimpl.cpp @@ -116,7 +116,7 @@ void CMainWindowImpl::refreshAboutVersion() GET_REGISTRY_SYSTEM(reg_system) if (Utils::getWinVersion() > Utils::WinVer::WinXP && reg_system.value("CheckForUpdates", true).toBool()) { AscAppManager::sendCommandTo(0, "updates:turn", "on"); - _json_obj["updates"] = QJsonObject({{"mode", reg_user.value("autoUpdateMode","silent").toString()}}); + _json_obj["updates"] = QJsonObject({{"mode", reg_user.value("autoUpdateMode","ask").toString()}}); } #else //AscAppManager::sendCommandTo(0, "updates:turn", "on"); diff --git a/win-linux/version.rc b/win-linux/version.rc index 22284a309..42baa17ba 100644 --- a/win-linux/version.rc +++ b/win-linux/version.rc @@ -1,4 +1,5 @@ -MAINICON ICON DISCARDABLE "./res/icons/desktopeditors.ico" +#include "src/platform_win/resource.h" +IDI_MAINICON ICON DISCARDABLE "./res/icons/desktopeditors.ico" CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "./res/manifest/DesktopEditors.manifest" #include