From 3764ee74768a8ab76ff8d51e136be8722da5321e Mon Sep 17 00:00:00 2001 From: SimplestStudio Date: Fri, 29 Aug 2025 12:41:52 +0300 Subject: [PATCH] [win-linux] merge updatedialog with cmessage --- win-linux/defaults.pri | 2 - win-linux/src/components/cmessage.cpp | 280 ++++++++++++++--- win-linux/src/components/cmessage.h | 27 +- win-linux/src/components/cnotification.cpp | 44 ++- win-linux/src/components/cnotification.h | 6 +- win-linux/src/components/updatedialog.cpp | 335 --------------------- win-linux/src/components/updatedialog.h | 61 ---- win-linux/src/cupdatemanager.cpp | 43 +-- win-linux/src/platform_win/association.cpp | 5 +- win-linux/src/windows/cmainwindow.cpp | 6 +- 10 files changed, 312 insertions(+), 497 deletions(-) delete mode 100644 win-linux/src/components/updatedialog.cpp delete mode 100644 win-linux/src/components/updatedialog.h diff --git a/win-linux/defaults.pri b/win-linux/defaults.pri index 077301d19..5f63ce2bc 100644 --- a/win-linux/defaults.pri +++ b/win-linux/defaults.pri @@ -161,10 +161,8 @@ SOURCES += \ updmodule:!build_xp { HEADERS += $$PWD/src/cupdatemanager.h \ - $$PWD/src/components/updatedialog.h \ $$PWD/src/components/cnotification.h SOURCES += $$PWD/src/cupdatemanager.cpp \ - $$PWD/src/components/updatedialog.cpp \ $$PWD/src/components/cnotification.cpp } diff --git a/win-linux/src/components/cmessage.cpp b/win-linux/src/components/cmessage.cpp index a618d5f22..b141875cd 100644 --- a/win-linux/src/components/cmessage.cpp +++ b/win-linux/src/components/cmessage.cpp @@ -55,6 +55,7 @@ # include # include # include +# include "res/gresource.c" # define toCharPtr(qstr) qstr.toLocal8Bit().data() # define AddButton(name, response) \ gtk_dialog_add_button(GTK_DIALOG(dialog), name, response) @@ -62,6 +63,7 @@ gtk_widget_grab_focus(gtk_dialog_get_widget_for_response(GTK_DIALOG(dialog), response)) #else # include "defines.h" +# include "platform_win/resource.h" # include # include # ifndef __OS_WIN_XP @@ -78,6 +80,13 @@ #define BTN_TEXT_BUY QObject::tr("Buy Now") #define BTN_TEXT_ACTIVATE QObject::tr("Activate") #define BTN_TEXT_CONTINUE QObject::tr("Continue") +#define BTN_TEXT_SKIPVER QObject::tr("Skip this version") +#define BTN_TEXT_REMIND QObject::tr("Remind me later") +#define BTN_TEXT_INSTALL QObject::tr("Install update") +#define BTN_TEXT_INSLATER QObject::tr("Later") +#define BTN_TEXT_RESTART QObject::tr("Restart Now") +#define BTN_TEXT_SAVEANDINS QObject::tr("Save and Install Now") +#define BTN_TEXT_DOWNLOAD QObject::tr("Download update") #define TEXT_CANCEL toCharPtr(BTN_TEXT_CANCEL) #define TEXT_YES toCharPtr(BTN_TEXT_YES) @@ -87,9 +96,22 @@ #define TEXT_BUY toCharPtr(BTN_TEXT_BUY) #define TEXT_ACTIVATE toCharPtr(BTN_TEXT_ACTIVATE) #define TEXT_CONTINUE toCharPtr(BTN_TEXT_CONTINUE) +#define TEXT_SKIPVER toCharPtr(BTN_TEXT_SKIPVER) +#define TEXT_REMIND toCharPtr(BTN_TEXT_REMIND) +#define TEXT_INSTALL toCharPtr(BTN_TEXT_INSTALL) +#define TEXT_INSLATER toCharPtr(BTN_TEXT_INSLATER) +#define TEXT_RESTART toCharPtr(BTN_TEXT_RESTART) +#define TEXT_SAVEANDINS toCharPtr(BTN_TEXT_SAVEANDINS) +#define TEXT_DOWNLOAD toCharPtr(BTN_TEXT_DOWNLOAD) + #define MSG_ICON_WIDTH 35 #define MSG_ICON_HEIGHT 35 +#define DLG_PADDING 7 +#define BTN_SPACING 5 +#define BTN_PADDING 13 +#define DLG_PREF_WIDTH 240 + #define DEFAULT_BUTTON(label) label + ":default" // class CMessageEventsFilter : public QObject { @@ -125,20 +147,21 @@ public: static int showMessage(QWidget *parent, const QString &msg, MsgType msgType, - MsgBtns msgBtns = MsgBtns::mbOk, - bool *checkBoxState = nullptr, - const QString &chekBoxText = QString()); + MsgBtns msgBtns, + const CMessageOpts &opts); private: void setButtons(std::initializer_list); void setButtons(MsgBtns); void setIcon(MsgType); void setText(const QString&); + void setContent(const QString&); void setCheckBox(const QString &chekBoxText, bool checkBoxState); bool getCheckStatus(); QWidget *m_boxButtons = nullptr, *m_centralWidget = nullptr; QLabel *m_message = nullptr, + *m_content = nullptr, *m_typeIcon = nullptr; static int m_modalresult; @@ -189,6 +212,7 @@ QtMsg::QtMsg(QWidget * p) : QDialog(p) , m_boxButtons(new QWidget) , m_message(new QLabel) + , m_content(new QLabel) , m_typeIcon(new QLabel) , m_priv(new QtMsgPrivateIntf(this)) { @@ -222,8 +246,14 @@ QtMsg::QtMsg(QWidget * p) m_message->setStyleSheet(QString("margin-bottom: %1px;").arg(int(8*m_priv->dpiRatio))); m_message->setTextFormat(Qt::PlainText); + m_content->setProperty("class", "msg-report"); + m_content->setStyleSheet(QString("margin-bottom: %1px;").arg(int(8*m_priv->dpiRatio))); + m_content->setTextFormat(Qt::RichText); + m_content->setOpenExternalLinks(true); + QFormLayout * _f_layout = new QFormLayout; _f_layout->addWidget(m_message); + _f_layout->addWidget(m_content); _f_layout->setSpacing(0); _f_layout->setContentsMargins(int(10*m_priv->dpiRatio),0,int(5*m_priv->dpiRatio),0); _h_layout2->addLayout(_f_layout, 1); @@ -315,7 +345,13 @@ void QtMsg::setButtons(std::initializer_list btns) {MODAL_RESULT_SKIP, BTN_TEXT_SKIP}, {MODAL_RESULT_BUY, BTN_TEXT_BUY}, {MODAL_RESULT_ACTIVATE, BTN_TEXT_ACTIVATE}, - {MODAL_RESULT_CONTINUE, BTN_TEXT_CONTINUE} + {MODAL_RESULT_CONTINUE, BTN_TEXT_CONTINUE}, + {MODAL_RESULT_SKIPVER, BTN_TEXT_SKIPVER}, + {MODAL_RESULT_REMIND, BTN_TEXT_REMIND}, + {MODAL_RESULT_DOWNLOAD, BTN_TEXT_DOWNLOAD}, + {MODAL_RESULT_INSTALL, BTN_TEXT_INSTALL}, + {MODAL_RESULT_INSLATER, BTN_TEXT_INSLATER}, + {MODAL_RESULT_RESTART, BTN_TEXT_RESTART} }; m_boxButtons->layout()->addWidget(_btn); @@ -343,6 +379,10 @@ void QtMsg::setButtons(MsgBtns btns) case MsgBtns::mbBuy: setButtons({DEFAULT_BUTTON(BTN_TEXT_BUY)}); break; case MsgBtns::mbActivateDefContinue: setButtons({DEFAULT_BUTTON(BTN_TEXT_ACTIVATE), BTN_TEXT_CONTINUE}); break; case MsgBtns::mbContinue: setButtons({DEFAULT_BUTTON(BTN_TEXT_CONTINUE)}); break; + case MsgBtns::mbInslaterRestart: setButtons({BTN_TEXT_INSLATER, DEFAULT_BUTTON(BTN_TEXT_RESTART)}); break; + case MsgBtns::mbSkipRemindInstall: setButtons({BTN_TEXT_SKIPVER, BTN_TEXT_REMIND, DEFAULT_BUTTON(BTN_TEXT_INSTALL)}); break; + case MsgBtns::mbSkipRemindSaveandinstall: setButtons({BTN_TEXT_SKIPVER, BTN_TEXT_REMIND, DEFAULT_BUTTON(BTN_TEXT_INSTALL)}); break; + case MsgBtns::mbSkipRemindDownload: setButtons({BTN_TEXT_SKIPVER, BTN_TEXT_REMIND, DEFAULT_BUTTON(BTN_TEXT_DOWNLOAD)}); break; default: break; } } @@ -367,8 +407,7 @@ int QtMsg::showMessage(QWidget *parent, const QString &msg, MsgType msgType, MsgBtns msgBtns, - bool *checkBoxState, - const QString &chekBoxText) + const CMessageOpts &opts) { #ifdef __linux__ WindowHelper::CParentDisable oDisabler(parent); @@ -383,14 +422,22 @@ int QtMsg::showMessage(QWidget *parent, #endif } dlg.setText(QTextDocumentFragment::fromHtml(msg).toPlainText()); + QString content = opts.contentText; + if (!content.isEmpty() && !opts.linkText.isEmpty()) { + content.append("\n"); + content.replace("\n", "
"); + } + content.append(opts.linkText); + if (!content.isEmpty()) + dlg.setContent(content); dlg.setIcon(msgType); if (msgBtns != MsgBtns::mbOk) dlg.setButtons(msgBtns); - if (checkBoxState != nullptr) - dlg.setCheckBox(chekBoxText, *checkBoxState); + if (opts.checkBoxState != nullptr) + dlg.setCheckBox(opts.chekBoxText, *opts.checkBoxState); dlg.exec(); - if (checkBoxState != nullptr) - *checkBoxState = dlg.getCheckStatus(); + if (opts.checkBoxState != nullptr) + *opts.checkBoxState = dlg.getCheckStatus(); return m_modalresult; } @@ -401,6 +448,7 @@ void QtMsg::setIcon(MsgType msgType) case MsgType::MSG_INFO: m_typeIcon->setProperty("type", "msg-info"); break; case MsgType::MSG_CONFIRM: m_typeIcon->setProperty("type", "msg-conf"); break; case MsgType::MSG_ERROR: m_typeIcon->setProperty("type", "msg-error"); break; + case MsgType::MSG_BRAND: m_typeIcon->setProperty("type", "msg-info"); break; default: break; } } @@ -410,11 +458,19 @@ void QtMsg::setText( const QString& t) m_message->setText(t); } +void QtMsg::setContent( const QString& t) +{ + m_content->setText(t); +} + #ifdef _WIN32 # ifndef __OS_WIN_XP static HRESULT CALLBACK 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) @@ -427,16 +483,37 @@ static HRESULT CALLBACK Pftaskdialogcallback(HWND hwnd, UINT msg, WPARAM wParam, } return S_OK; } + +static int calcApproxMinWidth(TASKDIALOG_BUTTON *pButtons, uint cButtons) +{ + int width = 0; + HDC hdc = GetDC(NULL); + long units = GetDialogBaseUnits(); + HGDIOBJ hFont = GetStockObject(DEFAULT_GUI_FONT); + SelectObject(hdc, hFont); + for (uint i = 0; i < cButtons; i++) { + SIZE textSize = {0,0}; + const wchar_t *text = pButtons[i].pszButtonText; + GetTextExtentPoint32(hdc, text, (int)std::wcslen(text), &textSize); + width += MulDiv(textSize.cx, 4, LOWORD(units)); + } + ReleaseDC(NULL, hdc); + width += (2 * DLG_PADDING) + (2 * BTN_PADDING * cButtons) + (BTN_SPACING * (cButtons - 1)); + return width; +} # endif namespace WinMsg { -int showMessage(QWidget *parent, const QString &msg, MsgType msgType, MsgBtns msgBtns, - bool *checkBoxState, const QString &chekBoxText) +int showMessage(QWidget *parent, const QString &msg, MsgType msgType, MsgBtns msgBtns, const CMessageOpts &opts) { std::wstring lpCaption = QString(" %1").arg(WINDOW_TITLE).toStdWString(); std::wstring lpText = QTextDocumentFragment::fromHtml(msg).toPlainText().toStdWString(); - std::wstring lpCheckBoxText = chekBoxText.toStdWString(); + std::wstring lpContent = opts.contentText.toStdWString(); + if (!lpContent.empty() && !opts.linkText.isEmpty()) + lpContent.append(L"\n"); + lpContent.append(opts.linkText.toStdWString()); + std::wstring lpCheckBoxText = opts.chekBoxText.toStdWString(); HWND parent_hwnd = (parent) ? (HWND)parent->winId() : nullptr; if (parent_hwnd && IsIconic(parent_hwnd)) ShowWindow(parent_hwnd, SW_RESTORE); @@ -449,6 +526,7 @@ int showMessage(QWidget *parent, const QString &msg, MsgType msgType, MsgBtns ms case MsgType::MSG_WARN: pIcon = TD_WARNING_ICON; break; case MsgType::MSG_CONFIRM: pIcon = TD_SHIELD_ICON; break; case MsgType::MSG_ERROR: pIcon = TD_ERROR_ICON; break; + case MsgType::MSG_BRAND: pIcon = MAKEINTRESOURCE(IDI_MAINICON); break; default: pIcon = TD_INFORMATION_ICON; break; } @@ -500,6 +578,33 @@ int showMessage(QWidget *parent, const QString &msg, MsgType msgType, MsgBtns ms pButtons = new TASKDIALOG_BUTTON[cButtons]; pButtons[0] = {IDOK, TEXT_CONTINUE}; break; + case MsgBtns::mbInslaterRestart: + cButtons = 2; + pButtons = new TASKDIALOG_BUTTON[cButtons]; + pButtons[0] = {IDYES, TEXT_INSLATER}; + pButtons[1] = {IDNO, TEXT_RESTART}; + break; + case MsgBtns::mbSkipRemindInstall: + cButtons = 3; + pButtons = new TASKDIALOG_BUTTON[cButtons]; + pButtons[0] = {IDRETRY, TEXT_SKIPVER}; + pButtons[1] = {IDNO, TEXT_REMIND}; + pButtons[2] = {IDYES, TEXT_INSTALL}; + break; + case MsgBtns::mbSkipRemindSaveandinstall: + cButtons = 3; + pButtons = new TASKDIALOG_BUTTON[cButtons]; + pButtons[0] = {IDRETRY, TEXT_SKIPVER}; + pButtons[1] = {IDNO, TEXT_REMIND}; + pButtons[2] = {IDYES, TEXT_SAVEANDINS}; + break; + case MsgBtns::mbSkipRemindDownload: + cButtons = 3; + pButtons = new TASKDIALOG_BUTTON[cButtons]; + pButtons[0] = {IDRETRY, TEXT_SKIPVER}; + pButtons[1] = {IDNO, TEXT_REMIND}; + pButtons[2] = {IDYES, TEXT_DOWNLOAD}; + break; default: cButtons = 1; pButtons = new TASKDIALOG_BUTTON[cButtons]; @@ -519,17 +624,21 @@ int showMessage(QWidget *parent, const QString &msg, MsgType msgType, MsgBtns ms case MsgBtns::mbBuy: nDefltBtn = IDYES; break; case MsgBtns::mbActivateDefContinue: nDefltBtn = IDYES; break; case MsgBtns::mbContinue: nDefltBtn = IDOK; break; + case MsgBtns::mbInslaterRestart: nDefltBtn = IDNO; break; + case MsgBtns::mbSkipRemindInstall: nDefltBtn = IDYES; break; + case MsgBtns::mbSkipRemindSaveandinstall: nDefltBtn = IDYES; break; + case MsgBtns::mbSkipRemindDownload: nDefltBtn = IDYES; break; default: nDefltBtn = IDOK; break; } - BOOL chkState = (checkBoxState) ? (BOOL)*checkBoxState : FALSE; + BOOL chkState = (opts.checkBoxState) ? (BOOL)*opts.checkBoxState : FALSE; TASKDIALOGCONFIG config = {0}; ZeroMemory(&config, sizeof(config)); config.cbSize = sizeof(config); config.dwFlags = TDF_POSITION_RELATIVE_TO_WINDOW | TDF_ALLOW_DIALOG_CANCELLATION | - TDF_SIZE_TO_CONTENT; + TDF_SIZE_TO_CONTENT | TDF_ENABLE_HYPERLINKS; if (AscAppManager::isRtlEnabled()) config.dwFlags |= TDF_RTL_LAYOUT; config.hwndParent = parent_hwnd; @@ -541,16 +650,18 @@ int showMessage(QWidget *parent, const QString &msg, MsgType msgType, MsgBtns ms config.pszMainIcon = pIcon; config.pszWindowTitle = lpCaption.c_str(); config.pszMainInstruction = lpText.c_str(); - config.pszContent = NULL; + config.pszContent = !lpContent.empty() ? lpContent.c_str() : NULL; + if (msgType == MsgType::MSG_BRAND) + config.cxWidth = calcApproxMinWidth(pButtons, cButtons) > DLG_PREF_WIDTH ? 0 : DLG_PREF_WIDTH; if (chkState == TRUE) config.dwFlags |= TDF_VERIFICATION_FLAG_CHECKED; - if (checkBoxState) + if (opts.checkBoxState) config.pszVerificationText = lpCheckBoxText.c_str(); - TaskDialogIndirect(&config, &msgboxID, NULL, (checkBoxState != nullptr) ? &chkState : NULL); - if (checkBoxState != nullptr) - *checkBoxState = (chkState == TRUE); + TaskDialogIndirect(&config, &msgboxID, NULL, (opts.checkBoxState != nullptr) ? &chkState : NULL); + if (opts.checkBoxState != nullptr) + *opts.checkBoxState = (chkState == TRUE); for (int i = 0; i < (int)cButtons; i++) free((void*)pButtons[i].pszButtonText); @@ -562,6 +673,7 @@ int showMessage(QWidget *parent, const QString &msg, MsgType msgType, MsgBtns ms case MsgType::MSG_WARN: uType |= MB_ICONWARNING; break; case MsgType::MSG_CONFIRM: uType |= MB_ICONQUESTION; break; case MsgType::MSG_ERROR: uType |= MB_ICONERROR; break; + case MsgType::MSG_BRAND: uType |= MB_ICONINFORMATION; break; default: uType |= MB_ICONINFORMATION; break; } @@ -581,13 +693,20 @@ int showMessage(QWidget *parent, const QString &msg, MsgType msgType, MsgBtns ms int result = MODAL_RESULT_CANCEL; switch (msgboxID) { case IDYES: result = (msgBtns == MsgBtns::mbBuy) ? MODAL_RESULT_BUY : - (msgBtns == MsgBtns::mbActivateDefContinue) ? MODAL_RESULT_ACTIVATE : MODAL_RESULT_YES; + (msgBtns == MsgBtns::mbActivateDefContinue) ? MODAL_RESULT_ACTIVATE : + (msgBtns == MsgBtns::mbSkipRemindInstall || msgBtns == MsgBtns::mbSkipRemindSaveandinstall) ? MODAL_RESULT_INSTALL : + (msgBtns == MsgBtns::mbSkipRemindDownload) ? MODAL_RESULT_DOWNLOAD : + (msgBtns == MsgBtns::mbInslaterRestart) ? MODAL_RESULT_INSLATER : MODAL_RESULT_YES; break; - case IDNO: result = (msgBtns == MsgBtns::mbActivateDefContinue) ? MODAL_RESULT_CONTINUE : MODAL_RESULT_NO; + case IDNO: result = (msgBtns == MsgBtns::mbActivateDefContinue) ? MODAL_RESULT_CONTINUE : + (msgBtns == MsgBtns::mbSkipRemindInstall || msgBtns == MsgBtns::mbSkipRemindSaveandinstall + || msgBtns == MsgBtns::mbSkipRemindDownload) ? MODAL_RESULT_REMIND : + (msgBtns == MsgBtns::mbInslaterRestart) ? MODAL_RESULT_RESTART : MODAL_RESULT_NO; break; case IDOK: result = (msgBtns == MsgBtns::mbContinue) ? MODAL_RESULT_CONTINUE : MODAL_RESULT_OK; break; - case IDRETRY: result = MODAL_RESULT_SKIP; + case IDRETRY: result = (msgBtns == MsgBtns::mbSkipRemindInstall || msgBtns == MsgBtns::mbSkipRemindSaveandinstall + || msgBtns == MsgBtns::mbSkipRemindDownload) ? MODAL_RESULT_SKIPVER : MODAL_RESULT_SKIP; break; case IDCANCEL: default: @@ -598,15 +717,24 @@ int showMessage(QWidget *parent, const QString &msg, MsgType msgType, MsgBtns ms } } #else +static void on_link_clicked(GtkWidget*, gchar *uri, gpointer) +{ + gtk_show_uri(NULL, uri, GDK_CURRENT_TIME, NULL); +} + namespace GtkMsg { -int showMessage(QWidget *parent, const QString &msg, MsgType msgType, MsgBtns msgBtns, - bool *checkBoxState, const QString &chekBoxText) +int showMessage(QWidget *parent, const QString &msg, MsgType msgType, MsgBtns msgBtns, const CMessageOpts &opts) { - QString plainText = QTextDocumentFragment::fromHtml(msg).toPlainText(); - const int delim = plainText.indexOf('\n'); - const QString primaryText = (delim != -1) ? plainText.mid(0, delim) : plainText; - const QString secondaryText = (delim != -1) ? plainText.mid(delim + 1) : ""; + QString primaryText = QTextDocumentFragment::fromHtml(msg).toPlainText(); + QString secondaryText = opts.contentText; + if (secondaryText.isEmpty()) { + const int delim = primaryText.indexOf('\n'); + if (delim != -1) { + secondaryText = primaryText.mid(delim + 1); + primaryText = primaryText.mid(0, delim); + } + } Window parent_xid = (parent) ? (Window)parent->winId() : 0L; const char* img_name = NULL; @@ -615,12 +743,17 @@ int showMessage(QWidget *parent, const QString &msg, MsgType msgType, MsgBtns ms case MsgType::MSG_WARN: img_name = "dialog-warning"; break; case MsgType::MSG_CONFIRM: img_name = "dialog-question"; break; case MsgType::MSG_ERROR: img_name = "dialog-error"; break; + case MsgType::MSG_BRAND: img_name = "/icons/app-icon_64.png"; break; default: img_name = "dialog-information"; break; } GtkWidget *image = NULL; - image = gtk_image_new(); - gtk_image_set_from_icon_name(GTK_IMAGE(image), img_name, GTK_ICON_SIZE_DIALOG); + if (msgType == MsgType::MSG_BRAND) { + image = gtk_image_new_from_resource(img_name); + } else { + image = gtk_image_new(); + gtk_image_set_from_icon_name(GTK_IMAGE(image), img_name, GTK_ICON_SIZE_DIALOG); + } GtkDialogFlags flags; flags = (GtkDialogFlags)(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT); @@ -633,6 +766,7 @@ int showMessage(QWidget *parent, const QString &msg, MsgType msgType, MsgBtns ms GTK_BUTTONS_NONE, "%s", primaryText.toLocal8Bit().data()); + // gtk_window_set_skip_taskbar_hint(GTK_WINDOW(dialog), TRUE); g_signal_connect(G_OBJECT(dialog), "realize", G_CALLBACK(set_parent), (gpointer)&parent_xid); g_signal_connect(G_OBJECT(dialog), "map_event", G_CALLBACK(set_focus), NULL); DialogTag tag; // unable to send parent_xid via g_signal_connect and "focus_out_event" @@ -643,18 +777,41 @@ int showMessage(QWidget *parent, const QString &msg, MsgType msgType, MsgBtns ms //gtk_window_set_title(GTK_WINDOW(dialog), APP_TITLE); if (!secondaryText.isEmpty()) gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog), "%s", secondaryText.toLocal8Bit().data()); - gtk_message_dialog_set_image(GTK_MESSAGE_DIALOG(dialog), image); - gtk_widget_show_all(image); - + if (image) { + gtk_message_dialog_set_image(GTK_MESSAGE_DIALOG(dialog), image); + if (msgType == MsgType::MSG_BRAND) + gtk_widget_set_margin_top(image, 6); + gtk_widget_show_all(image); + } + if (!opts.linkText.isEmpty()) { + GtkWidget *msg_area = gtk_message_dialog_get_message_area(GTK_MESSAGE_DIALOG(dialog)); + GtkWidget *label = gtk_label_new(opts.linkText.toLocal8Bit().data()); + gtk_label_set_use_markup(GTK_LABEL(label), TRUE); + gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); + gtk_label_set_max_width_chars(GTK_LABEL(label), 50); + g_signal_connect(G_OBJECT(label), "activate-link", G_CALLBACK(on_link_clicked), NULL); + gtk_container_add(GTK_CONTAINER(msg_area), label); + gtk_widget_show_all(label); + } GtkWidget *chkbox = NULL; - if (checkBoxState != nullptr) { + if (opts.checkBoxState != nullptr) { //GtkWidget *cont_area = gtk_dialog_get_content_area(GTK_DIALOG (dialog)); GtkWidget *msg_area = gtk_message_dialog_get_message_area(GTK_MESSAGE_DIALOG(dialog)); - chkbox = gtk_check_button_new_with_label(chekBoxText.toLocal8Bit().data()); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chkbox), (*checkBoxState) ? TRUE : FALSE); + chkbox = gtk_check_button_new_with_label(opts.chekBoxText.toLocal8Bit().data()); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chkbox), *opts.checkBoxState); gtk_container_add(GTK_CONTAINER(msg_area), chkbox); gtk_widget_show_all(chkbox); } + if (msgType == MsgType::MSG_BRAND) { // Set text alignment + GtkWidget *msg_area = gtk_message_dialog_get_message_area(GTK_MESSAGE_DIALOG(dialog)); + GList *children = gtk_container_get_children(GTK_CONTAINER(msg_area)); + for (GList *iter = children; iter != NULL; iter = g_list_next(iter)) { + GtkWidget *child = GTK_WIDGET(iter->data); + if (GTK_IS_LABEL(child)) + gtk_widget_set_halign(child, GTK_ALIGN_START); + } + g_list_free(children); + } switch (msgBtns) { case MsgBtns::mbYesNo: @@ -688,6 +845,25 @@ int showMessage(QWidget *parent, const QString &msg, MsgType msgType, MsgBtns ms case MsgBtns::mbContinue: AddButton(TEXT_CONTINUE, GTK_RESPONSE_OK); break; + case MsgBtns::mbInslaterRestart: + AddButton(TEXT_INSLATER, GTK_RESPONSE_YES); + AddButton(TEXT_RESTART, GTK_RESPONSE_NO); + break; + case MsgBtns::mbSkipRemindInstall: + AddButton(TEXT_SKIPVER, GTK_RESPONSE_REJECT); + AddButton(TEXT_REMIND, GTK_RESPONSE_NO); + AddButton(TEXT_INSTALL, GTK_RESPONSE_YES); + break; + case MsgBtns::mbSkipRemindSaveandinstall: + AddButton(TEXT_SKIPVER, GTK_RESPONSE_REJECT); + AddButton(TEXT_REMIND, GTK_RESPONSE_NO); + AddButton(TEXT_SAVEANDINS, GTK_RESPONSE_YES); + break; + case MsgBtns::mbSkipRemindDownload: + AddButton(TEXT_SKIPVER, GTK_RESPONSE_REJECT); + AddButton(TEXT_REMIND, GTK_RESPONSE_NO); + AddButton(TEXT_DOWNLOAD, GTK_RESPONSE_YES); + break; default: AddButton(TEXT_OK, GTK_RESPONSE_OK); break; @@ -704,6 +880,10 @@ int showMessage(QWidget *parent, const QString &msg, MsgType msgType, MsgBtns ms case MsgBtns::mbBuy: GrabFocus(GTK_RESPONSE_YES); break; case MsgBtns::mbActivateDefContinue: GrabFocus(GTK_RESPONSE_YES); break; case MsgBtns::mbContinue: GrabFocus(GTK_RESPONSE_OK); break; + case MsgBtns::mbInslaterRestart: GrabFocus(GTK_RESPONSE_NO); break; + case MsgBtns::mbSkipRemindInstall: GrabFocus(GTK_RESPONSE_YES); break; + case MsgBtns::mbSkipRemindSaveandinstall: GrabFocus(GTK_RESPONSE_YES); break; + case MsgBtns::mbSkipRemindDownload: GrabFocus(GTK_RESPONSE_YES); break; default: GrabFocus(GTK_RESPONSE_OK); break; } @@ -711,13 +891,20 @@ int showMessage(QWidget *parent, const QString &msg, MsgType msgType, MsgBtns ms int result = MODAL_RESULT_CANCEL; switch (msgboxID) { case GTK_RESPONSE_YES: result = (msgBtns == MsgBtns::mbBuy) ? MODAL_RESULT_BUY : - (msgBtns == MsgBtns::mbActivateDefContinue) ? MODAL_RESULT_ACTIVATE : MODAL_RESULT_YES; + (msgBtns == MsgBtns::mbActivateDefContinue) ? MODAL_RESULT_ACTIVATE : + (msgBtns == MsgBtns::mbSkipRemindInstall || msgBtns == MsgBtns::mbSkipRemindSaveandinstall) ? MODAL_RESULT_INSTALL : + (msgBtns == MsgBtns::mbSkipRemindDownload) ? MODAL_RESULT_DOWNLOAD : + (msgBtns == MsgBtns::mbInslaterRestart) ? MODAL_RESULT_INSLATER : MODAL_RESULT_YES; break; - case GTK_RESPONSE_NO: result = (msgBtns == MsgBtns::mbActivateDefContinue) ? MODAL_RESULT_CONTINUE : MODAL_RESULT_NO; + case GTK_RESPONSE_NO: result = (msgBtns == MsgBtns::mbActivateDefContinue) ? MODAL_RESULT_CONTINUE : + (msgBtns == MsgBtns::mbSkipRemindInstall || msgBtns == MsgBtns::mbSkipRemindSaveandinstall + || msgBtns == MsgBtns::mbSkipRemindDownload) ? MODAL_RESULT_REMIND : + (msgBtns == MsgBtns::mbInslaterRestart) ? MODAL_RESULT_RESTART : MODAL_RESULT_NO; break; case GTK_RESPONSE_OK: result = (msgBtns == MsgBtns::mbContinue) ? MODAL_RESULT_CONTINUE : MODAL_RESULT_OK; break; - case GTK_RESPONSE_REJECT: result = MODAL_RESULT_SKIP; + case GTK_RESPONSE_REJECT: result = (msgBtns == MsgBtns::mbSkipRemindInstall || msgBtns == MsgBtns::mbSkipRemindSaveandinstall + || msgBtns == MsgBtns::mbSkipRemindDownload) ? MODAL_RESULT_SKIPVER : MODAL_RESULT_SKIP; break; case GTK_RESPONSE_DELETE_EVENT: case GTK_RESPONSE_CANCEL: @@ -725,9 +912,9 @@ int showMessage(QWidget *parent, const QString &msg, MsgType msgType, MsgBtns ms break; } - if (checkBoxState != nullptr) { + if (opts.checkBoxState != nullptr) { gboolean chkState = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(chkbox)); - *checkBoxState = (chkState == TRUE); + *opts.checkBoxState = (chkState == TRUE); } gtk_widget_destroy(dialog); @@ -743,20 +930,19 @@ int CMessage::showMessage(QWidget *parent, const QString &msg, MsgType msgType, MsgBtns msgBtns, - bool *checkBoxState, - const QString &chekBoxText) + const CMessageOpts &opts) { if (WindowHelper::useNativeDialog()) { #ifdef _WIN32 # ifndef __OS_WIN_XP - return WinMsg::showMessage(parent, msg, msgType, msgBtns, checkBoxState, chekBoxText); + return WinMsg::showMessage(parent, msg, msgType, msgBtns, opts); # endif #else WindowHelper::CParentDisable oDisabler(parent); - return GtkMsg::showMessage(parent, msg, msgType, msgBtns, checkBoxState, chekBoxText); + return GtkMsg::showMessage(parent, msg, msgType, msgBtns, opts); #endif } - return QtMsg::showMessage(parent, msg, msgType, msgBtns, checkBoxState, chekBoxText); + return QtMsg::showMessage(parent, msg, msgType, msgBtns, opts); } void CMessage::confirm(QWidget *parent, const QString &msg) diff --git a/win-linux/src/components/cmessage.h b/win-linux/src/components/cmessage.h index 49d3c414e..9d2b41211 100644 --- a/win-linux/src/components/cmessage.h +++ b/win-linux/src/components/cmessage.h @@ -47,13 +47,18 @@ enum class MsgBtns { mbYesDefSkipNo, mbBuy, mbActivateDefContinue, - mbContinue + mbContinue, + mbSkipRemindInstall, + mbSkipRemindSaveandinstall, + mbSkipRemindDownload, + mbInslaterRestart }; enum class MsgType { MSG_INFO = 0, MSG_WARN, MSG_CONFIRM, - MSG_ERROR + MSG_ERROR, + MSG_BRAND }; enum MsgRes { MODAL_RESULT_CANCEL = 0, @@ -63,7 +68,20 @@ enum MsgRes { MODAL_RESULT_SKIP, MODAL_RESULT_BUY, MODAL_RESULT_ACTIVATE, - MODAL_RESULT_CONTINUE + MODAL_RESULT_CONTINUE, + MODAL_RESULT_SKIPVER, + MODAL_RESULT_REMIND, + MODAL_RESULT_DOWNLOAD, + MODAL_RESULT_INSTALL, + MODAL_RESULT_INSLATER, + MODAL_RESULT_RESTART +}; + +struct CMessageOpts { + bool *checkBoxState = nullptr; + QString chekBoxText; + QString contentText; + QString linkText; }; class QWidget; @@ -73,8 +91,7 @@ int showMessage(QWidget *parent, const QString &msg, MsgType msgType, MsgBtns msgBtns = MsgBtns::mbOk, - bool *checkBoxState = nullptr, - const QString &chekBoxText = QString()); + const CMessageOpts &opts = {}); void confirm(QWidget *parent, const QString &msg); void info(QWidget *parent, const QString &msg); diff --git a/win-linux/src/components/cnotification.cpp b/win-linux/src/components/cnotification.cpp index b4d3559bd..0c8e7334b 100644 --- a/win-linux/src/components/cnotification.cpp +++ b/win-linux/src/components/cnotification.cpp @@ -65,8 +65,6 @@ #define TEXT_SAVEANDINS toTStr(QObject::tr("Install")) #define TEXT_DOWNLOAD toTStr(QObject::tr("Download")) -using namespace WinDlg; - #ifdef __linux__ # define addAction(action, label) notify_notification_add_action(ntf, action, label, NOTIFY_ACTION_CALLBACK(action_callback), (void*)&pimpl->ntfMap, NULL); @@ -76,13 +74,13 @@ static void action_callback(NotifyNotification *ntf, char *action, void *data) { if (!data) return; - int res = strcmp(action, "inslater") == 0 ? DLG_RESULT_INSLATER : - strcmp(action, "restart") == 0 ? DLG_RESULT_RESTART : - strcmp(action, "skip") == 0 ? DLG_RESULT_SKIP : - strcmp(action, "remind") == 0 ? DLG_RESULT_REMIND : - strcmp(action, "install") == 0 ? DLG_RESULT_INSTALL : - strcmp(action, "saveins") == 0 ? DLG_RESULT_INSTALL : - strcmp(action, "download") == 0 ? DLG_RESULT_DOWNLOAD : -1; + int res = strcmp(action, "inslater") == 0 ? MODAL_RESULT_INSLATER : + strcmp(action, "restart") == 0 ? MODAL_RESULT_RESTART : + strcmp(action, "skip") == 0 ? MODAL_RESULT_SKIP : + strcmp(action, "remind") == 0 ? MODAL_RESULT_REMIND : + strcmp(action, "install") == 0 ? MODAL_RESULT_INSTALL : + strcmp(action, "saveins") == 0 ? MODAL_RESULT_INSTALL : + strcmp(action, "download") == 0 ? MODAL_RESULT_DOWNLOAD : -1; NtfMap *ntfMap = (NtfMap*)data; if (ntfMap->find(ntf) != ntfMap->end()) { @@ -168,7 +166,7 @@ using namespace WinToastLib; class ToastHandler : public IWinToastHandler { public: - ToastHandler(DlgBtns _dlgBtns, FnVoidInt _callback) : dlgBtns(_dlgBtns), callback(_callback) + ToastHandler(MsgBtns _dlgBtns, FnVoidInt _callback) : dlgBtns(_dlgBtns), callback(_callback) {} virtual void toastActivated() const final // The user clicked in this toast {} @@ -176,9 +174,9 @@ public: { int res = -1; switch (actionIndex) { - case 0: res = (dlgBtns == DlgBtns::mbInslaterRestart) ? DLG_RESULT_INSLATER : DLG_RESULT_SKIP; break; - case 1: res = (dlgBtns == DlgBtns::mbInslaterRestart) ? DLG_RESULT_RESTART : DLG_RESULT_REMIND; break; - case 2: res = (dlgBtns == DlgBtns::mbSkipRemindDownload) ? DLG_RESULT_DOWNLOAD : DLG_RESULT_INSTALL; break; + case 0: res = (dlgBtns == MsgBtns::mbInslaterRestart) ? MODAL_RESULT_INSLATER : MODAL_RESULT_SKIP; break; + case 1: res = (dlgBtns == MsgBtns::mbInslaterRestart) ? MODAL_RESULT_RESTART : MODAL_RESULT_REMIND; break; + case 2: res = (dlgBtns == MsgBtns::mbSkipRemindDownload) ? MODAL_RESULT_DOWNLOAD : MODAL_RESULT_INSTALL; break; default: break; } @@ -207,7 +205,7 @@ public: } private: - DlgBtns dlgBtns; + MsgBtns dlgBtns; FnVoidInt callback; }; #endif @@ -300,7 +298,7 @@ void CNotification::clear() #endif } -bool CNotification::show(const QString &msg, const QString &content, DlgBtns dlgBtns, const FnVoidInt &callback) +bool CNotification::show(const QString &msg, const QString &content, MsgBtns dlgBtns, const FnVoidInt &callback) { #ifdef __linux__ if (!isNotificationsEnabled()) @@ -314,21 +312,21 @@ bool CNotification::show(const QString &msg, const QString &content, DlgBtns dlg if (callback) { switch (dlgBtns) { - case DlgBtns::mbInslaterRestart: + case MsgBtns::mbInslaterRestart: addAction("inslater", TEXT_INSLATER.c_str()); addAction("restart", TEXT_RESTART.c_str()); break; - case DlgBtns::mbSkipRemindInstall: + case MsgBtns::mbSkipRemindInstall: addAction("skip", TEXT_SKIP.c_str()); addAction("remind", TEXT_REMIND.c_str()); addAction("install", TEXT_INSTALL.c_str()); break; - case DlgBtns::mbSkipRemindSaveandinstall: + case MsgBtns::mbSkipRemindSaveandinstall: addAction("skip", TEXT_SKIP.c_str()); addAction("remind", TEXT_REMIND.c_str()); addAction("saveins", TEXT_SAVEANDINS.c_str()); break; - case DlgBtns::mbSkipRemindDownload: + case MsgBtns::mbSkipRemindDownload: addAction("skip", TEXT_SKIP.c_str()); addAction("remind", TEXT_REMIND.c_str()); addAction("download", TEXT_DOWNLOAD.c_str()); @@ -353,21 +351,21 @@ bool CNotification::show(const QString &msg, const QString &content, DlgBtns dlg tmpl.setExpiration(NOTIF_TIMEOUT_MS); switch (dlgBtns) { - case DlgBtns::mbInslaterRestart: + case MsgBtns::mbInslaterRestart: tmpl.addAction(TEXT_INSLATER); tmpl.addAction(TEXT_RESTART); break; - case DlgBtns::mbSkipRemindInstall: + case MsgBtns::mbSkipRemindInstall: tmpl.addAction(TEXT_SKIP); tmpl.addAction(TEXT_REMIND); tmpl.addAction(TEXT_INSTALL); break; - case DlgBtns::mbSkipRemindSaveandinstall: + case MsgBtns::mbSkipRemindSaveandinstall: tmpl.addAction(TEXT_SKIP); tmpl.addAction(TEXT_REMIND); tmpl.addAction(TEXT_SAVEANDINS); break; - case DlgBtns::mbSkipRemindDownload: + case MsgBtns::mbSkipRemindDownload: tmpl.addAction(TEXT_SKIP); tmpl.addAction(TEXT_REMIND); tmpl.addAction(TEXT_DOWNLOAD); diff --git a/win-linux/src/components/cnotification.h b/win-linux/src/components/cnotification.h index 9a149d05a..bde3e2c81 100644 --- a/win-linux/src/components/cnotification.h +++ b/win-linux/src/components/cnotification.h @@ -33,10 +33,10 @@ #ifndef CNOTIFICATION_H #define CNOTIFICATION_H -#include "components/updatedialog.h" +#include "components/cmessage.h" #include -#define mbNone WinDlg::DlgBtns(-1) +#define mbNone MsgBtns(-1) #define NOTIF_FAILED -2 //#define NOTIF_DISMISSED -3 @@ -49,7 +49,7 @@ public: CNotification& operator=(const CNotification&) = delete; static CNotification& instance(); bool init(); - bool show(const QString &msg, const QString &content, WinDlg::DlgBtns dlgBtns = mbNone, const FnVoidInt &callback = nullptr); + bool show(const QString &msg, const QString &content, MsgBtns dlgBtns = mbNone, const FnVoidInt &callback = nullptr); void clear(); private: diff --git a/win-linux/src/components/updatedialog.cpp b/win-linux/src/components/updatedialog.cpp deleted file mode 100644 index 96b98e9f7..000000000 --- a/win-linux/src/components/updatedialog.cpp +++ /dev/null @@ -1,335 +0,0 @@ -/* - * (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 "cascapplicationmanagerwrapper.h" -#include "defines.h" -#include "utils.h" -#include -#include -#ifdef __linux__ -# pragma push_macro("signals") -# undef signals -# include "platform_linux/gtkutils.h" -# pragma pop_macro("signals") -# include -# include -# include "res/gresource.c" -# define toCharPtr(qstr) qstr.toLocal8Bit().data() -#else -# include -# include -# define toCharPtr(qstr) _wcsdup(qstr.toStdWString().c_str()) -#endif - -#define DLG_PADDING 7 -#define BTN_SPACING 5 -#define BTN_PADDING 13 -#define DLG_PREF_WIDTH 240 - -#define BTN_TEXT_SKIPVER QObject::tr("Skip this version") -#define BTN_TEXT_REMIND QObject::tr("Remind me later") -#define BTN_TEXT_INSTALL QObject::tr("Install update") -#define BTN_TEXT_INSLATER QObject::tr("Later") -#define BTN_TEXT_RESTART QObject::tr("Restart Now") -#define BTN_TEXT_SAVEANDINS QObject::tr("Save and Install Now") -#define BTN_TEXT_DOWNLOAD QObject::tr("Download update") - -#define TEXT_SKIP toCharPtr(BTN_TEXT_SKIPVER) -#define TEXT_REMIND toCharPtr(BTN_TEXT_REMIND) -#define TEXT_INSTALL toCharPtr(BTN_TEXT_INSTALL) -#define TEXT_INSLATER toCharPtr(BTN_TEXT_INSLATER) -#define TEXT_RESTART toCharPtr(BTN_TEXT_RESTART) -#define TEXT_SAVEANDINS toCharPtr(BTN_TEXT_SAVEANDINS) -#define TEXT_DOWNLOAD toCharPtr(BTN_TEXT_DOWNLOAD) - -#ifdef __linux__ -# define AddButton(name, response) \ - gtk_dialog_add_button(GTK_DIALOG(dialog), name, response) -# define GrabFocus(response) \ - gtk_widget_grab_focus(gtk_dialog_get_widget_for_response(GTK_DIALOG(dialog), response)) - -static void on_link_clicked(GtkWidget*, gchar *uri, gpointer) -{ - gtk_show_uri(NULL, uri, GDK_CURRENT_TIME, NULL); -} -#else -static int calcApproxMinWidth(TASKDIALOG_BUTTON *pButtons, uint cButtons) -{ - int width = 0; - HDC hdc = GetDC(NULL); - long units = GetDialogBaseUnits(); - HGDIOBJ hFont = GetStockObject(DEFAULT_GUI_FONT); - SelectObject(hdc, hFont); - for (uint i = 0; i < cButtons; i++) { - SIZE textSize = {0,0}; - const wchar_t *text = pButtons[i].pszButtonText; - GetTextExtentPoint32(hdc, text, (int)std::wcslen(text), &textSize); - width += MulDiv(textSize.cx, 4, LOWORD(units)); - } - ReleaseDC(NULL, hdc); - width += (2 * DLG_PADDING) + (2 * BTN_PADDING * cButtons) + (BTN_SPACING * (cButtons - 1)); - return width; -} - -static HRESULT CALLBACK 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) - WindowHelper::bringToTop(hwnd); - }); - break; - } - default: - break; - } - return S_OK; -} -#endif - -#ifdef _WIN32 -int WinDlg::showDialog(QWidget *parent, const QString &msg, const QString &content, DlgBtns dlgBtns) -{ - std::wstring lpCaption = QString(" %1").arg(WINDOW_TITLE).toStdWString(); - std::wstring lpText = QTextDocumentFragment::fromHtml(msg).toPlainText().toStdWString(); - QString linkText = !QString(RELEASE_NOTES).isEmpty() ? - QString("\n%2").arg(QString(RELEASE_NOTES), QObject::tr("Release notes")) : ""; - std::wstring lpContent = QString("%1\n%2").arg(content, linkText).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 = {sizeof(TASKDIALOGCONFIG)}; - config.dwFlags = TDF_ENABLE_HYPERLINKS | - TDF_POSITION_RELATIVE_TO_WINDOW | - TDF_ALLOW_DIALOG_CANCELLATION; - if (AscAppManager::isRtlEnabled()) - config.dwFlags |= TDF_RTL_LAYOUT; - config.hwndParent = parent_hwnd; - config.hInstance = GetModuleHandle(NULL); - config.pfCallback = (PFTASKDIALOGCALLBACK)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 = calcApproxMinWidth(pButtons, cButtons) > DLG_PREF_WIDTH ? 0 : DLG_PREF_WIDTH; - - 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; -} -#else -int WinDlg::showDialog(QWidget *parent, const QString &msg, const QString &content, DlgBtns dlgBtns) -{ -// QString title = QString(" %1").arg(WINDOW_TITLE); - QString primaryText = QTextDocumentFragment::fromHtml(msg).toPlainText(); - QString linkText = !QString(RELEASE_NOTES).isEmpty() ? - QString("%2").arg(QString(RELEASE_NOTES), QObject::tr("Release notes")) : ""; - WindowHelper::CParentDisable oDisabler(parent); - Window parent_xid = (parent) ? (Window)parent->winId() : 0L; - - GtkDialogFlags flags; - flags = (GtkDialogFlags)(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT); - - if (AscAppManager::isRtlEnabled()) - gtk_widget_set_default_direction(GTK_TEXT_DIR_RTL); - GtkWidget *dialog = NULL; - dialog = gtk_message_dialog_new(NULL, flags, - GTK_MESSAGE_OTHER, // Message type doesn't show icon - GTK_BUTTONS_NONE, - "%s", primaryText.toLocal8Bit().data()); - - gtk_window_set_skip_taskbar_hint(GTK_WINDOW(dialog), TRUE); - g_signal_connect(G_OBJECT(dialog), "realize", G_CALLBACK(set_parent), (gpointer)&parent_xid); - g_signal_connect(G_OBJECT(dialog), "map_event", G_CALLBACK(set_focus), NULL); - DialogTag tag; // unable to send parent_xid via g_signal_connect and "focus_out_event" - memset(&tag, 0, sizeof(tag)); - tag.dialog = dialog; - tag.parent_xid = (ulong)parent_xid; - g_signal_connect_swapped(G_OBJECT(dialog), "focus_out_event", G_CALLBACK(focus_out), (gpointer)&tag); - // gtk_window_set_title(GTK_WINDOW(dialog), title.toLocal8Bit().data()); - if (!content.isEmpty()) - gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog), "%s", content.toLocal8Bit().data()); - - if (GtkWidget *image = gtk_image_new_from_resource("/icons/app-icon_64.png")) { - gtk_message_dialog_set_image(GTK_MESSAGE_DIALOG(dialog), image); - gtk_widget_set_margin_top(image, 6); - gtk_widget_show_all(image); - } - - if (!linkText.isEmpty()) { - GtkWidget *msg_area = gtk_message_dialog_get_message_area(GTK_MESSAGE_DIALOG(dialog)); - GtkWidget *label = gtk_label_new(linkText.toLocal8Bit().data()); - gtk_label_set_use_markup(GTK_LABEL(label), TRUE); - gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); - gtk_label_set_max_width_chars(GTK_LABEL(label), 50); - g_signal_connect(G_OBJECT(label), "activate-link", G_CALLBACK(on_link_clicked), NULL); - gtk_container_add(GTK_CONTAINER(msg_area), label); - gtk_widget_show_all(label); - } - - { // Set text alignment - GtkWidget *msg_area = gtk_message_dialog_get_message_area(GTK_MESSAGE_DIALOG(dialog)); - GList *children = gtk_container_get_children(GTK_CONTAINER(msg_area)); - for (GList *iter = children; iter != NULL; iter = g_list_next(iter)) { - GtkWidget *child = GTK_WIDGET(iter->data); - if (GTK_IS_LABEL(child)) - gtk_widget_set_halign(child, GTK_ALIGN_START); - } - g_list_free(children); - } - - switch (dlgBtns) { - case DlgBtns::mbInslaterRestart: - AddButton(TEXT_INSLATER, GTK_RESPONSE_YES); - AddButton(TEXT_RESTART, GTK_RESPONSE_NO); - break; - case DlgBtns::mbSkipRemindInstall: - AddButton(TEXT_SKIP, GTK_RESPONSE_REJECT); - AddButton(TEXT_REMIND, GTK_RESPONSE_NO); - AddButton(TEXT_INSTALL, GTK_RESPONSE_YES); - break; - case DlgBtns::mbSkipRemindSaveandinstall: - AddButton(TEXT_SKIP, GTK_RESPONSE_REJECT); - AddButton(TEXT_REMIND, GTK_RESPONSE_NO); - AddButton(TEXT_SAVEANDINS, GTK_RESPONSE_YES); - break; - case DlgBtns::mbSkipRemindDownload: - AddButton(TEXT_SKIP, GTK_RESPONSE_REJECT); - AddButton(TEXT_REMIND, GTK_RESPONSE_NO); - AddButton(TEXT_DOWNLOAD, GTK_RESPONSE_YES); - break; - default: - break; - } - - switch (dlgBtns) { - case DlgBtns::mbInslaterRestart: GrabFocus(GTK_RESPONSE_NO); break; - case DlgBtns::mbSkipRemindInstall: GrabFocus(GTK_RESPONSE_YES); break; - case DlgBtns::mbSkipRemindSaveandinstall: GrabFocus(GTK_RESPONSE_YES); break; - case DlgBtns::mbSkipRemindDownload: GrabFocus(GTK_RESPONSE_YES); break; - default: break; - } - - int msgboxID = gtk_dialog_run (GTK_DIALOG (dialog)); - int result = GTK_RESPONSE_CANCEL; - switch (msgboxID) { - case GTK_RESPONSE_YES: result = (dlgBtns == DlgBtns::mbSkipRemindInstall || - dlgBtns == DlgBtns::mbSkipRemindSaveandinstall) ? DLG_RESULT_INSTALL : - (dlgBtns == DlgBtns::mbSkipRemindDownload) ? DLG_RESULT_DOWNLOAD : - DLG_RESULT_INSLATER; break; - case GTK_RESPONSE_NO: result = (dlgBtns == DlgBtns::mbSkipRemindInstall || - dlgBtns == DlgBtns::mbSkipRemindSaveandinstall || - dlgBtns == DlgBtns::mbSkipRemindDownload) ? DLG_RESULT_REMIND : - DLG_RESULT_RESTART; break; - case GTK_RESPONSE_REJECT: result = DLG_RESULT_SKIP; break; - case GTK_RESPONSE_CANCEL: - default: - break; - } - gtk_widget_destroy(dialog); - - return result; -} -#endif diff --git a/win-linux/src/components/updatedialog.h b/win-linux/src/components/updatedialog.h deleted file mode 100644 index 4c14b8333..000000000 --- a/win-linux/src/components/updatedialog.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * (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/cupdatemanager.cpp b/win-linux/src/cupdatemanager.cpp index c5fdae60f..7233ae6a1 100644 --- a/win-linux/src/cupdatemanager.cpp +++ b/win-linux/src/cupdatemanager.cpp @@ -42,7 +42,7 @@ #include "version.h" #include "clangater.h" #include "clogger.h" -#include "components/updatedialog.h" +#include "components/cmessage.h" #include "cascapplicationmanagerwrapper.h" #include #ifdef _WIN32 @@ -55,7 +55,6 @@ # include # include # include -# include "components/cmessage.h" # define DAEMON_NAME "/updatesvc" # define GetPid() getpid() #endif @@ -71,6 +70,7 @@ #define CHECK_ON_STARTUP_MS 9000 #define CMD_ARGUMENT_UPDATES_INTERVAL L"--updates-interval" #define SERVICE_NAME APP_TITLE " Update Service" +#define LINK_TEXT QString("%2").arg(QString(RELEASE_NOTES), QObject::tr("Release notes")) #define __GLOBAL_LOCK if (m_lock) {CLogger::log("Blocked in: " + FUNCTION_INFO); return;} m_lock = true; \ CLogger::log("Locking and further execution:" + FUNCTION_INFO); #define __UNLOCK m_lock = false; CLogger::log("Unlocked in:" + FUNCTION_INFO); @@ -894,28 +894,31 @@ void CUpdateManager::showUpdateMessage(QWidget *parent, bool forceModal, int res if (CNotification::instance().show(title, QString("%1\n%2: %3\n%4: %5").arg(name, tr("Current version"), curr_version, tr("New version"), m_packageData->version), - WinDlg::DlgBtns::mbSkipRemindDownload, [=](int res) { + MsgBtns::mbSkipRemindDownload, [=](int res) { QMetaObject::invokeMethod(this, "showUpdateMessage", Qt::QueuedConnection, Q_ARG(QWidget*, parent), Q_ARG(bool, res == NOTIF_FAILED), Q_ARG(int, res)); })) { __UNLOCK return; } } - result = WinDlg::showDialog(parent, title, - QString("%1\n%2: %3\n%4: %5\n%6 (%7 MB)").arg(name, tr("Current version"), - curr_version, tr("New version"), m_packageData->version, - text, m_packageData->fileSize), - WinDlg::DlgBtns::mbSkipRemindDownload); + + QString content = QString("%1\n%2: %3\n%4: %5\n%6 (%7 MB)") + .arg(name, tr("Current version"), curr_version, tr("New version"), m_packageData->version, text, m_packageData->fileSize); + CMessageOpts opts; + opts.contentText = QString("%1\n").arg(content); + if (!QString(RELEASE_NOTES).isEmpty()) + opts.linkText = LINK_TEXT; + result = CMessage::showMessage(parent, title, MsgType::MSG_BRAND, MsgBtns::mbSkipRemindDownload, opts); __UNLOCK } switch (result) { - case WinDlg::DLG_RESULT_DOWNLOAD: + case MsgRes::MODAL_RESULT_DOWNLOAD: if (m_packageData->isInstallable) loadUpdates(); else Utils::openUrl(DOWNLOAD_PAGE); break; - case WinDlg::DLG_RESULT_SKIP: { + case MsgRes::MODAL_RESULT_SKIP: { skipVersion(); refreshStartPage({"success", {TXT_UPDATED}, BTN_TXT_CHECK, "check", "false"}); m_pLastCheckMsgTimer->start(); @@ -937,28 +940,32 @@ void CUpdateManager::showStartInstallMessage(QWidget *parent, bool forceModal, i if (CNotification::instance().show(title, QString("%1\n%2: %3\n%4: %5").arg(name, tr("Current version"), curr_version, tr("New version"), m_packageData->version), - WinDlg::DlgBtns::mbInslaterRestart, [=](int res) { + MsgBtns::mbInslaterRestart, [=](int res) { QMetaObject::invokeMethod(this, "showStartInstallMessage", Qt::QueuedConnection, Q_ARG(QWidget*, parent), Q_ARG(bool, res == NOTIF_FAILED), Q_ARG(int, res)); })) { __UNLOCK return; } } - result = WinDlg::showDialog(parent, title, - QString("%1\n%2: %3\n%4: %5\n%6").arg(name, tr("Current version"), - curr_version, tr("New version"), m_packageData->version, - tr("To finish updating, restart the app")), - WinDlg::DlgBtns::mbInslaterRestart); + + QString content = QString("%1\n%2: %3\n%4: %5\n%6") + .arg(name, tr("Current version"), curr_version, tr("New version"), m_packageData->version, + tr("To finish updating, restart the app")); + CMessageOpts opts; + opts.contentText = QString("%1\n").arg(content); + if (!QString(RELEASE_NOTES).isEmpty()) + opts.linkText = LINK_TEXT; + result = CMessage::showMessage(parent, title, MsgType::MSG_BRAND, MsgBtns::mbInslaterRestart, opts); __UNLOCK } switch (result) { - case WinDlg::DLG_RESULT_RESTART: { + case MsgRes::MODAL_RESULT_RESTART: { m_startUpdateOnClose = true; m_restartAfterUpdate = true; AscAppManager::closeAppWindows(); break; } - case WinDlg::DLG_RESULT_INSLATER: { + case MsgRes::MODAL_RESULT_INSLATER: { #ifdef _WIN32 m_startUpdateOnClose = (m_packageData->fileType == "archive"); #else diff --git a/win-linux/src/platform_win/association.cpp b/win-linux/src/platform_win/association.cpp index 1731d6fe3..c6ba6bda8 100644 --- a/win-linux/src/platform_win/association.cpp +++ b/win-linux/src/platform_win/association.cpp @@ -216,7 +216,10 @@ void Association::AssociationPrivate::tryProposeAssociation(QWidget *parent, con .arg(QString(WINDOW_NAME), QString::fromStdWString(unassocFileExts[0])) : QObject::tr("Do you want to make %1 your default application for all supported extensions?") .arg(QString(WINDOW_NAME)); - int res = CMessage::showMessage(parent, msg, MsgType::MSG_INFO, MsgBtns::mbYesDefNo, &m_ignoreAssocMsg, QObject::tr("Do not show this message again")); + CMessageOpts opts; + opts.checkBoxState = &m_ignoreAssocMsg; + opts.chekBoxText = QObject::tr("Do not show this message again"); + int res = CMessage::showMessage(parent, msg, MsgType::MSG_INFO, MsgBtns::mbYesDefNo, opts); if (m_ignoreAssocMsg) { GET_REGISTRY_USER(reg_user) reg_user.setValue("ignoreAssocMsg", true); diff --git a/win-linux/src/windows/cmainwindow.cpp b/win-linux/src/windows/cmainwindow.cpp index 801cc8b7b..497b760af 100644 --- a/win-linux/src/windows/cmainwindow.cpp +++ b/win-linux/src/windows/cmainwindow.cpp @@ -310,9 +310,11 @@ void CMainWindow::close() for (int i = 0; i < m_pTabs->count(); i++) { if (!m_pTabs->modifiedByIndex(i)) { bool dontAskAgain = false; + CMessageOpts opts; + opts.checkBoxState = &dontAskAgain; + opts.chekBoxText = tr("Don't ask again."); int res = CMessage::showMessage(this, tr("More than one document is open.
Close the window anyway?"), - MsgType::MSG_WARN, MsgBtns::mbYesNo, &dontAskAgain, - tr("Don't ask again.")); + MsgType::MSG_WARN, MsgBtns::mbYesNo, opts); if (dontAskAgain) reg_user.setValue("ignoreMsgAboutOpenTabs", true); if (res != MODAL_RESULT_YES) {