mirror of https://github.com/OpenVPN/openvpn-gui
Add a progress dialog during Connect()
- The dialog supports retry and cancel and shows a progress marquee Signed-off-by: Selva Nair <selva.nair@gmail.compull/529/head
parent
e64b18074f
commit
ed0ceeb95b
|
@ -50,6 +50,8 @@ struct OpenVPNConnection
|
||||||
#define ISDISCONNECTED(c) (ConnectionState(c) == state_disconnected)
|
#define ISDISCONNECTED(c) (ConnectionState(c) == state_disconnected)
|
||||||
#define ISONHOLD(c) (ConnectionState(c) == state_onhold)
|
#define ISONHOLD(c) (ConnectionState(c) == state_onhold)
|
||||||
|
|
||||||
|
extern DWORD status_menu_id;
|
||||||
|
|
||||||
/* Methods in IConnectableCredentialProviderCredential that we need to define */
|
/* Methods in IConnectableCredentialProviderCredential that we need to define */
|
||||||
|
|
||||||
/* IUnknown */
|
/* IUnknown */
|
||||||
|
@ -528,6 +530,64 @@ NotifyEvents(OpenVPNConnection *oc, const wchar_t *status)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI
|
||||||
|
ProgressCallback(HWND hwnd, UINT msg, WPARAM wParam, UNUSED LPARAM lParam, LONG_PTR ref_data)
|
||||||
|
{
|
||||||
|
assert(ref_data);
|
||||||
|
|
||||||
|
OpenVPNConnection *oc = (OpenVPNConnection *) ref_data;
|
||||||
|
connection_t *c = oc->c;
|
||||||
|
IQueryContinueWithStatus *qc = oc->qc;
|
||||||
|
|
||||||
|
assert(qc);
|
||||||
|
|
||||||
|
HRESULT hr = S_FALSE;
|
||||||
|
WCHAR status[256] = L"";
|
||||||
|
|
||||||
|
if (msg == TDN_BUTTON_CLICKED && wParam == IDCANCEL)
|
||||||
|
{
|
||||||
|
dmsg(L"wParam=IDCANCEL -- returning S_OK");
|
||||||
|
hr = S_OK; /* this will cause the progress dialog to close */
|
||||||
|
}
|
||||||
|
else if (ISCONNECTED(c) || ISDISCONNECTED(c) || (qc->lpVtbl->QueryContinue(qc) != S_OK))
|
||||||
|
{
|
||||||
|
/* this will trigger IDCANCEL */
|
||||||
|
PostMessageW(hwnd, WM_CLOSE, 0, 0);
|
||||||
|
dmsg(L"profile = %ls, closing progress dialog", oc->display_name);
|
||||||
|
hr = S_OK;
|
||||||
|
}
|
||||||
|
else if (ISONHOLD(c)) /* Try to connect again */
|
||||||
|
{
|
||||||
|
ConnectHelper(c);
|
||||||
|
}
|
||||||
|
else if (!ISCONNECTED(c) && msg == TDN_BUTTON_CLICKED && wParam == status_menu_id)
|
||||||
|
{
|
||||||
|
dmsg(L"wParam = status_menu_id -- showing status window");
|
||||||
|
ShowStatusWindow(c, TRUE);
|
||||||
|
}
|
||||||
|
else if (!ISCONNECTED(c) && msg == TDN_BUTTON_CLICKED && wParam == IDRETRY)
|
||||||
|
{
|
||||||
|
dmsg(L"wParam = IDRETRY -- closing progress dialog for restart");
|
||||||
|
hr = S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg == TDN_CREATED)
|
||||||
|
{
|
||||||
|
dmsg(L"starting progress bar marquee");
|
||||||
|
PostMessageW(hwnd, TDM_SET_PROGRESS_BAR_MARQUEE, 1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg == TDN_TIMER)
|
||||||
|
{
|
||||||
|
GetConnectionStatusText(c, status, _countof(status));
|
||||||
|
NotifyEvents(oc, status);
|
||||||
|
SendMessageW(hwnd, TDM_UPDATE_ELEMENT_TEXT, TDE_CONTENT, (LPARAM) status);
|
||||||
|
dmsg(L"Connection status <%ls>", status);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI
|
static HRESULT WINAPI
|
||||||
Connect(ICCPC *this, IQueryContinueWithStatus *qc)
|
Connect(ICCPC *this, IQueryContinueWithStatus *qc)
|
||||||
{
|
{
|
||||||
|
@ -538,33 +598,41 @@ Connect(ICCPC *this, IQueryContinueWithStatus *qc)
|
||||||
|
|
||||||
oc->qc = qc;
|
oc->qc = qc;
|
||||||
NotifyEvents(oc, L"");
|
NotifyEvents(oc, L"");
|
||||||
oc->connect_cancelled = FALSE;
|
|
||||||
|
|
||||||
SetActiveProfile(oc->c);
|
again:
|
||||||
|
oc->connect_cancelled = FALSE;
|
||||||
|
SetActiveProfile(oc->c); /* This enables UI dialogs to be shown for c */
|
||||||
|
|
||||||
ConnectHelper(oc->c);
|
ConnectHelper(oc->c);
|
||||||
|
|
||||||
Sleep(100);
|
Sleep(100);
|
||||||
|
|
||||||
while (!ISCONNECTED(oc->c) && !ISDISCONNECTED(oc->c))
|
/* if not immediately connected, show a progress dialog with
|
||||||
|
* service state changes and retry/cancel options. Progress dialog
|
||||||
|
* returns on error, cancel or when connected.
|
||||||
|
*/
|
||||||
|
if (!ISCONNECTED(oc->c) && !ISDISCONNECTED(oc->c))
|
||||||
{
|
{
|
||||||
ShowStatusWindow(oc->c, TRUE);
|
dmsg(L"Runninng progress dialog");
|
||||||
GetConnectionStatusText(oc->c, status, _countof(status));
|
int res = RunProgressDialog(oc->c, ProgressCallback, (LONG_PTR) oc);
|
||||||
NotifyEvents(oc, status);
|
dmsg(L"Out of progress dialog with res = %d", res);
|
||||||
if (qc->lpVtbl->QueryContinue(qc) != S_OK)
|
|
||||||
|
if (res == IDRETRY && !ISCONNECTED(oc->c))
|
||||||
|
{
|
||||||
|
wcsncpy_s(status, _countof(status), L"Current State: Retrying", _TRUNCATE);
|
||||||
|
NotifyEvents(oc, status);
|
||||||
|
|
||||||
|
DisconnectHelper(oc->c);
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
|
else if (res == IDCANCEL && !ISCONNECTED(oc->c) && !ISDISCONNECTED(oc->c))
|
||||||
{
|
{
|
||||||
/* user wants to cancel */
|
|
||||||
wcsncpy_s(status, _countof(status), L"Current State: Cancelling", _TRUNCATE);
|
wcsncpy_s(status, _countof(status), L"Current State: Cancelling", _TRUNCATE);
|
||||||
NotifyEvents(oc, status);
|
NotifyEvents(oc, status);
|
||||||
oc->connect_cancelled = TRUE;
|
|
||||||
DisconnectHelper(oc->c);
|
DisconnectHelper(oc->c);
|
||||||
break;
|
oc->connect_cancelled = TRUE;
|
||||||
}
|
}
|
||||||
else if (ISONHOLD(oc->c))
|
|
||||||
{
|
|
||||||
ConnectHelper(oc->c);
|
|
||||||
}
|
|
||||||
Sleep(100);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GetConnectionStatusText(oc->c, status, _countof(status));
|
GetConnectionStatusText(oc->c, status, _countof(status));
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#include "openvpn-gui-res.h"
|
#include "openvpn-gui-res.h"
|
||||||
#include "localization.h"
|
#include "localization.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
#include "tray.h"
|
||||||
|
|
||||||
/* Global options structure */
|
/* Global options structure */
|
||||||
options_t o;
|
options_t o;
|
||||||
|
@ -47,6 +48,7 @@ int state_connected = connected, state_disconnected = disconnected,
|
||||||
state_onhold = onhold;
|
state_onhold = onhold;
|
||||||
|
|
||||||
static connection_t *active_profile;
|
static connection_t *active_profile;
|
||||||
|
DWORD status_menu_id = IDM_STATUSMENU;
|
||||||
|
|
||||||
/* Override management handlers that generate user dialogs
|
/* Override management handlers that generate user dialogs
|
||||||
* and pass them on only for currently active profile.
|
* and pass them on only for currently active profile.
|
||||||
|
@ -477,3 +479,41 @@ SetActiveProfile(connection_t *c)
|
||||||
{
|
{
|
||||||
active_profile = c;
|
active_profile = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
RunProgressDialog(connection_t *c, PFTASKDIALOGCALLBACK cb_fn, LONG_PTR cb_data)
|
||||||
|
{
|
||||||
|
dmsg(L"Entry with profile = <%ls>", c->config_name);
|
||||||
|
|
||||||
|
const TASKDIALOG_FLAGS flags = TDF_SHOW_MARQUEE_PROGRESS_BAR|TDF_CALLBACK_TIMER|TDF_USE_HICON_MAIN;
|
||||||
|
wchar_t main_text[256];
|
||||||
|
wchar_t details_btn_text[256];
|
||||||
|
|
||||||
|
_sntprintf_0(main_text, L"%ls %ls", LoadLocalizedString(IDS_MENU_CONNECT), c->config_name);
|
||||||
|
LoadLocalizedStringBuf(details_btn_text, _countof(main_text), IDS_MENU_STATUS);
|
||||||
|
|
||||||
|
const TASKDIALOG_BUTTON extra_buttons[] = {
|
||||||
|
{status_menu_id, details_btn_text},
|
||||||
|
};
|
||||||
|
|
||||||
|
const TASKDIALOGCONFIG taskcfg = {
|
||||||
|
.cbSize = sizeof(taskcfg),
|
||||||
|
.hwndParent = o.hWnd,
|
||||||
|
.hInstance = o.hInstance,
|
||||||
|
.dwFlags = flags,
|
||||||
|
.hMainIcon = LoadLocalizedIcon(ID_ICO_APP),
|
||||||
|
.cButtons = _countof(extra_buttons),
|
||||||
|
.pButtons = extra_buttons,
|
||||||
|
.dwCommonButtons = TDCBF_CANCEL_BUTTON|TDCBF_RETRY_BUTTON,
|
||||||
|
.pszWindowTitle = L""PACKAGE_NAME" PLAP",
|
||||||
|
.pszMainInstruction = main_text,
|
||||||
|
.pszContent = L"Starting", /* replaced on create */
|
||||||
|
.pfCallback = cb_fn,
|
||||||
|
.lpCallbackData = cb_data,
|
||||||
|
};
|
||||||
|
|
||||||
|
int button_clicked = 0;
|
||||||
|
dmsg(L"calling taskdialogindirect");
|
||||||
|
TaskDialogIndirect(&taskcfg, &button_clicked, NULL, NULL);
|
||||||
|
return button_clicked;
|
||||||
|
}
|
||||||
|
|
|
@ -107,6 +107,15 @@ void DisconnectHelper(connection_t *c);
|
||||||
*/
|
*/
|
||||||
void SetActiveProfile(connection_t *c);
|
void SetActiveProfile(connection_t *c);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A helper function to run a dialog showing progress of a connection process.
|
||||||
|
*
|
||||||
|
* @param c Connection to monitor
|
||||||
|
* @param cb_fn A callback function that is called back every 200 msec
|
||||||
|
* @param cb_data Data passed to the callback function
|
||||||
|
*/
|
||||||
|
int RunProgressDialog(connection_t *c, PFTASKDIALOGCALLBACK cb_fn, LONG_PTR cb_data);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue