summaryrefslogtreecommitdiff
path: root/src/modules/protocols/protoopts.cpp
diff options
context:
space:
mode:
authorVadim Dashevskiy <watcherhd@gmail.com>2012-05-15 10:38:20 +0000
committerVadim Dashevskiy <watcherhd@gmail.com>2012-05-15 10:38:20 +0000
commit48540940b6c28bb4378abfeb500ec45a625b37b6 (patch)
tree2ef294c0763e802f91d868bdef4229b6868527de /src/modules/protocols/protoopts.cpp
parent5c350913f011e119127baeb32a6aedeb4f0d33bc (diff)
initial commit
git-svn-id: http://svn.miranda-ng.org/main/trunk@2 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'src/modules/protocols/protoopts.cpp')
-rw-r--r--src/modules/protocols/protoopts.cpp1084
1 files changed, 1084 insertions, 0 deletions
diff --git a/src/modules/protocols/protoopts.cpp b/src/modules/protocols/protoopts.cpp
new file mode 100644
index 0000000000..3d9c0a2b36
--- /dev/null
+++ b/src/modules/protocols/protoopts.cpp
@@ -0,0 +1,1084 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2009 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "commonheaders.h"
+
+#define LBN_MY_CHECK 0x1000
+#define LBN_MY_RENAME 0x1001
+
+#define WM_MY_REFRESH (WM_USER+0x1000)
+#define WM_MY_RENAME (WM_USER+0x1001)
+
+INT_PTR Proto_EnumProtocols( WPARAM, LPARAM );
+bool CheckProtocolOrder(void);
+
+#define errMsg \
+"WARNING! The account is going to be deleted. It means that all its \
+settings, contacts and histories will be also erased.\n\n\
+Are you absolutely sure?"
+
+#define upgradeMsg \
+"Your account was successfully upgraded. \
+To activate it, restart of Miranda is needed.\n\n\
+If you want to restart Miranda now, press Yes, if you want to upgrade another account, press No"
+
+#define legacyMsg \
+"This account uses legacy protocol plugin. \
+Use Miranda IM options dialogs to change it's preferences."
+
+#define welcomeMsg \
+"Welcome to Miranda IM's account manager!\n \
+Here you can set up your IM accounts.\n\n \
+Select an account from the list on the left to see the available options. \
+Alternatively, just click on the Plus sign underneath the list to set up a new IM account."
+
+static HWND hAccMgr = NULL;
+
+extern HANDLE hAccListChanged;
+
+int UnloadPlugin( TCHAR* buf, int bufLen );
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Account edit form
+// Gets PROTOACCOUNT* as a parameter, or NULL to edit a new one
+
+typedef struct
+{
+ int action;
+ PROTOACCOUNT* pa;
+}
+ AccFormDlgParam;
+
+static INT_PTR CALLBACK AccFormDlgProc(HWND hwndDlg,UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch( message ) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+ {
+ PROTOCOLDESCRIPTOR** proto;
+ int protoCount, i, cnt = 0;
+ Proto_EnumProtocols(( WPARAM )&protoCount, ( LPARAM )&proto );
+ for ( i=0; i < protoCount; i++ ) {
+ PROTOCOLDESCRIPTOR* pd = proto[i];
+ if ( pd->type == PROTOTYPE_PROTOCOL && pd->cbSize == sizeof( *pd )) {
+ SendDlgItemMessageA( hwndDlg, IDC_PROTOTYPECOMBO, CB_ADDSTRING, 0, (LPARAM)proto[i]->szName );
+ ++cnt;
+ }
+ }
+ SendDlgItemMessage( hwndDlg, IDC_PROTOTYPECOMBO, CB_SETCURSEL, 0, 0 );
+ EnableWindow( GetDlgItem( hwndDlg, IDOK ), cnt != 0 );
+
+ SetWindowLongPtr( hwndDlg, GWLP_USERDATA, lParam );
+ AccFormDlgParam* param = ( AccFormDlgParam* )lParam;
+
+ if ( param->action == PRAC_ADDED ) // new account
+ SetWindowText( hwndDlg, TranslateT( "Create new account" ));
+ else {
+ TCHAR str[200];
+ if ( param->action == PRAC_CHANGED ) { // update
+ EnableWindow( GetDlgItem( hwndDlg, IDC_PROTOTYPECOMBO ), FALSE );
+ mir_sntprintf( str, SIZEOF(str), _T("%s: %s"), TranslateT( "Editing account" ), param->pa->tszAccountName );
+ }
+ else mir_sntprintf( str, SIZEOF(str), _T("%s: %s"), TranslateT( "Upgrading account" ), param->pa->tszAccountName );
+
+ SetWindowText( hwndDlg, str );
+ SetDlgItemText( hwndDlg, IDC_ACCNAME, param->pa->tszAccountName );
+ SetDlgItemTextA( hwndDlg, IDC_ACCINTERNALNAME, param->pa->szModuleName );
+ SendDlgItemMessageA( hwndDlg, IDC_PROTOTYPECOMBO, CB_SELECTSTRING, -1, (LPARAM)param->pa->szProtoName );
+
+ EnableWindow( GetDlgItem( hwndDlg, IDC_ACCINTERNALNAME ), FALSE );
+ }
+ SendDlgItemMessage( hwndDlg, IDC_ACCINTERNALNAME, EM_LIMITTEXT, 40, 0 );
+ }
+ return TRUE;
+
+ case WM_COMMAND:
+ switch( LOWORD(wParam)) {
+ case IDOK:
+ {
+ AccFormDlgParam* param = ( AccFormDlgParam* )GetWindowLongPtr( hwndDlg, GWLP_USERDATA );
+ PROTOACCOUNT* pa = param->pa;
+
+ if ( param->action == PRAC_ADDED ) {
+ char buf[200];
+ GetDlgItemTextA( hwndDlg, IDC_ACCINTERNALNAME, buf, SIZEOF( buf ));
+ rtrim( buf );
+ if ( buf[0] ) {
+ for (int i = 0; i < accounts.getCount(); ++i)
+ if (_stricmp(buf, accounts[i]->szModuleName) == 0)
+ return FALSE;
+ } }
+
+ switch( param->action ) {
+ case PRAC_UPGRADED:
+ {
+ int idx;
+ BOOL oldProto = pa->bOldProto;
+ TCHAR szPlugin[MAX_PATH];
+ mir_sntprintf(szPlugin, SIZEOF(szPlugin), _T("%s.dll"), StrConvT(pa->szProtoName));
+ idx = accounts.getIndex(pa);
+ UnloadAccount(pa, false, false);
+ accounts.remove(idx);
+ if (oldProto && UnloadPlugin(szPlugin, SIZEOF(szPlugin)))
+ {
+ TCHAR szNewName[MAX_PATH];
+ mir_sntprintf(szNewName, SIZEOF(szNewName), _T("%s~"), szPlugin);
+ MoveFile(szPlugin, szNewName);
+ }
+ }
+ // fall through
+
+ case PRAC_ADDED:
+ pa = (PROTOACCOUNT*)mir_calloc( sizeof( PROTOACCOUNT ));
+ pa->cbSize = sizeof( PROTOACCOUNT );
+ pa->bIsEnabled = TRUE;
+ pa->bIsVisible = TRUE;
+
+ pa->iOrder = accounts.getCount();
+ pa->type = PROTOTYPE_PROTOCOL;
+ break;
+ }
+ {
+ TCHAR buf[256];
+ GetDlgItemText( hwndDlg, IDC_ACCNAME, buf, SIZEOF( buf ));
+ mir_free(pa->tszAccountName);
+ pa->tszAccountName = mir_tstrdup( buf );
+ }
+ if ( param->action == PRAC_ADDED || param->action == PRAC_UPGRADED )
+ {
+ char buf[200];
+ GetDlgItemTextA( hwndDlg, IDC_PROTOTYPECOMBO, buf, SIZEOF( buf ));
+ pa->szProtoName = mir_strdup( buf );
+ GetDlgItemTextA( hwndDlg, IDC_ACCINTERNALNAME, buf, SIZEOF( buf ));
+ rtrim( buf );
+ if ( buf[0] == 0 ) {
+ int count = 1;
+ for( ;; ) {
+ DBVARIANT dbv;
+ mir_snprintf( buf, SIZEOF(buf), "%s_%d", pa->szProtoName, count++ );
+ if ( DBGetContactSettingString( NULL, buf, "AM_BaseProto", &dbv ))
+ break;
+ DBFreeVariant( &dbv );
+ } }
+ pa->szModuleName = mir_strdup( buf );
+
+ if ( !pa->tszAccountName[0] ) {
+ mir_free(pa->tszAccountName);
+ pa->tszAccountName = mir_a2t(buf);
+ }
+
+ DBWriteContactSettingString( NULL, pa->szModuleName, "AM_BaseProto", pa->szProtoName );
+ accounts.insert( pa );
+
+ if ( ActivateAccount( pa )) {
+ pa->ppro->OnEvent( EV_PROTO_ONLOAD, 0, 0 );
+ if (!DBGetContactSettingByte(NULL, "CList", "MoveProtoMenus", FALSE))
+ pa->ppro->OnEvent( EV_PROTO_ONMENU, 0, 0 );
+ }
+ else pa->type = PROTOTYPE_DISPROTO;
+ }
+
+ WriteDbAccounts();
+ NotifyEventHooks( hAccListChanged, param->action, ( LPARAM )pa );
+
+ SendMessage( GetParent(hwndDlg), WM_MY_REFRESH, 0, 0 );
+ }
+
+ EndDialog( hwndDlg, TRUE );
+ break;
+
+ case IDCANCEL:
+ EndDialog( hwndDlg, FALSE );
+ break;
+ }
+ }
+
+ return FALSE;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Accounts manager
+
+struct TAccMgrData
+{
+ HFONT hfntTitle, hfntText;
+ int titleHeight, textHeight;
+ int selectedHeight, normalHeight;
+ int iSelected;
+};
+
+struct TAccListData
+{
+ WNDPROC oldWndProc;
+ int iItem;
+ RECT rcCheck;
+
+ HWND hwndEdit;
+ WNDPROC oldEditProc;
+};
+
+static void sttClickButton(HWND hwndDlg, int idcButton)
+{
+ if (IsWindowEnabled(GetDlgItem(hwndDlg, idcButton)))
+ PostMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(idcButton, BN_CLICKED), (LPARAM)GetDlgItem(hwndDlg, idcButton));
+}
+
+static LRESULT CALLBACK sttEditSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg)
+ {
+ case WM_KEYDOWN:
+ switch (wParam) {
+ case VK_RETURN:
+ DestroyWindow(hwnd);
+ return 0;
+
+ case VK_ESCAPE:
+ SetWindowLongPtr(hwnd, GWLP_WNDPROC, GetWindowLongPtr(hwnd, GWLP_USERDATA));
+ DestroyWindow(hwnd);
+ return 0;
+ }
+ break;
+
+ case WM_GETDLGCODE:
+ if (wParam == VK_RETURN || wParam == VK_ESCAPE)
+ return DLGC_WANTMESSAGE;
+ break;
+
+ case WM_KILLFOCUS:
+ {
+ int length = GetWindowTextLength(hwnd) + 1;
+ TCHAR *str = ( TCHAR* )mir_alloc(sizeof(TCHAR) * length);
+ GetWindowText(hwnd, str, length);
+ SendMessage(GetParent(GetParent(hwnd)), WM_COMMAND, MAKEWPARAM(GetWindowLongPtr(GetParent(hwnd), GWL_ID), LBN_MY_RENAME), (LPARAM)str);
+ }
+ DestroyWindow(hwnd);
+ return 0;
+ }
+ return CallWindowProc((WNDPROC)GetWindowLongPtr(hwnd, GWLP_USERDATA), hwnd, msg, wParam, lParam);
+}
+
+static LRESULT CALLBACK AccListWndProc(HWND hwnd,UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ struct TAccListData *dat = (struct TAccListData *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
+ if ( !dat )
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+
+ switch (msg) {
+ case WM_LBUTTONDOWN:
+ {
+ POINT pt = {LOWORD(lParam), HIWORD(lParam)};
+ int iItem = LOWORD(SendMessage(hwnd, LB_ITEMFROMPOINT, 0, lParam));
+ ListBox_GetItemRect(hwnd, iItem, &dat->rcCheck);
+
+ dat->rcCheck.right = dat->rcCheck.left + GetSystemMetrics(SM_CXSMICON) + 4;
+ dat->rcCheck.bottom = dat->rcCheck.top + GetSystemMetrics(SM_CYSMICON) + 4;
+ if (PtInRect(&dat->rcCheck, pt))
+ dat->iItem = iItem;
+ else
+ dat->iItem = -1;
+ }
+ break;
+
+ case WM_LBUTTONUP:
+ {
+ POINT pt = {LOWORD(lParam), HIWORD(lParam)};
+ if ((dat->iItem >= 0) && PtInRect(&dat->rcCheck, pt))
+ PostMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(GetWindowLongPtr(hwnd, GWL_ID), LBN_MY_CHECK), (LPARAM)dat->iItem);
+ dat->iItem = -1;
+ }
+ break;
+
+ case WM_CHAR:
+ if (wParam == ' ') {
+ int iItem = ListBox_GetCurSel(hwnd);
+ if (iItem >= 0)
+ PostMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(GetWindowLongPtr(hwnd, GWL_ID), LBN_MY_CHECK), (LPARAM)iItem);
+ return 0;
+ }
+
+ if (wParam == 10 /* enter */)
+ return 0;
+
+ break;
+
+ case WM_GETDLGCODE:
+ if (wParam == VK_RETURN)
+ return DLGC_WANTMESSAGE;
+ break;
+
+ case WM_MY_RENAME:
+ {
+ RECT rc;
+ struct TAccMgrData *parentDat = (struct TAccMgrData *)GetWindowLongPtr(GetParent(hwnd), GWLP_USERDATA);
+ PROTOACCOUNT *pa = (PROTOACCOUNT *)ListBox_GetItemData(hwnd, ListBox_GetCurSel(hwnd));
+ if (!pa || pa->bOldProto || pa->bDynDisabled)
+ return 0;
+
+ ListBox_GetItemRect(hwnd, ListBox_GetCurSel(hwnd), &rc);
+ rc.left += 2*GetSystemMetrics(SM_CXSMICON) + 4;
+ rc.bottom = rc.top + max(GetSystemMetrics(SM_CXSMICON), parentDat->titleHeight) + 4 - 1;
+ ++rc.top; --rc.right;
+
+ dat->hwndEdit = CreateWindow(_T("EDIT"), pa->tszAccountName, WS_CHILD|WS_BORDER|ES_AUTOHSCROLL, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, hwnd, NULL, hMirandaInst, NULL);
+ SetWindowLongPtr(dat->hwndEdit, GWLP_USERDATA, SetWindowLongPtr(dat->hwndEdit, GWLP_WNDPROC, (LONG_PTR)sttEditSubclassProc));
+ SendMessage(dat->hwndEdit, WM_SETFONT, (WPARAM)parentDat->hfntTitle, 0);
+ SendMessage(dat->hwndEdit, EM_SETMARGINS, EC_LEFTMARGIN|EC_RIGHTMARGIN|EC_USEFONTINFO, 0);
+ SendMessage(dat->hwndEdit, EM_SETSEL, 0, (LPARAM) (-1));
+ ShowWindow(dat->hwndEdit, SW_SHOW);
+ }
+ SetFocus(dat->hwndEdit);
+ break;
+
+ case WM_KEYDOWN:
+ switch (wParam) {
+ case VK_F2:
+ PostMessage(hwnd, WM_MY_RENAME, 0, 0);
+ return 0;
+
+ case VK_INSERT:
+ sttClickButton(GetParent(hwnd), IDC_ADD);
+ return 0;
+
+ case VK_DELETE:
+ sttClickButton(GetParent(hwnd), IDC_REMOVE);
+ return 0;
+
+ case VK_RETURN:
+ if (GetAsyncKeyState(VK_CONTROL))
+ sttClickButton(GetParent(hwnd), IDC_EDIT);
+ else
+ sttClickButton(GetParent(hwnd), IDOK);
+ return 0;
+ }
+ break;
+ }
+
+ return CallWindowProc(dat->oldWndProc, hwnd, msg, wParam, lParam);
+}
+
+static void sttSubclassAccList(HWND hwnd, BOOL subclass)
+{
+ if (subclass) {
+ struct TAccListData *dat = (struct TAccListData *)mir_alloc(sizeof(struct TAccListData));
+ dat->iItem = -1;
+ dat->oldWndProc = (WNDPROC)GetWindowLongPtr(hwnd, GWLP_WNDPROC);
+ SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)dat);
+ SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)AccListWndProc);
+ }
+ else {
+ struct TAccListData *dat = (struct TAccListData *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
+ SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)dat->oldWndProc);
+ SetWindowLongPtr(hwnd, GWLP_USERDATA, 0);
+ mir_free(dat);
+} }
+
+static void sttSelectItem(struct TAccMgrData *dat, HWND hwndList, int iItem)
+{
+ if ((dat->iSelected != iItem) && (dat->iSelected >= 0))
+ ListBox_SetItemHeight(hwndList, dat->iSelected, dat->normalHeight);
+
+ dat->iSelected = iItem;
+ ListBox_SetItemHeight(hwndList, dat->iSelected, dat->selectedHeight);
+ RedrawWindow(hwndList, NULL, NULL, RDW_INVALIDATE);
+}
+
+static void sttUpdateAccountInfo(HWND hwndDlg, struct TAccMgrData *dat)
+{
+ HWND hwndList = GetDlgItem(hwndDlg, IDC_ACCLIST);
+ int curSel = ListBox_GetCurSel( hwndList );
+ if ( curSel != LB_ERR ) {
+ HWND hwnd;
+ char svc[MAXMODULELABELLENGTH];
+
+ PROTOACCOUNT *pa = (PROTOACCOUNT *)ListBox_GetItemData(hwndList, curSel);
+ if ( pa ) {
+ EnableWindow( GetDlgItem( hwndDlg, IDC_UPGRADE ), pa->bOldProto || pa->bDynDisabled );
+ EnableWindow( GetDlgItem( hwndDlg, IDC_EDIT ), !pa->bOldProto && !pa->bDynDisabled );
+ EnableWindow( GetDlgItem( hwndDlg, IDC_REMOVE ), TRUE );
+ EnableWindow( GetDlgItem( hwndDlg, IDC_OPTIONS ), pa->ppro != 0 );
+
+ if ( dat->iSelected >= 0 ) {
+ PROTOACCOUNT *pa_old = (PROTOACCOUNT *)ListBox_GetItemData(hwndList, dat->iSelected);
+ if (pa_old && pa_old != pa && pa_old->hwndAccMgrUI)
+ ShowWindow(pa_old->hwndAccMgrUI, SW_HIDE);
+ }
+
+ if ( pa->hwndAccMgrUI ) {
+ ShowWindow(GetDlgItem(hwndDlg, IDC_TXT_INFO), SW_HIDE);
+ ShowWindow(pa->hwndAccMgrUI, SW_SHOW);
+ }
+ else if ( !pa->ppro ) {
+ ShowWindow(GetDlgItem(hwndDlg, IDC_TXT_INFO), SW_SHOW);
+ SetWindowText(GetDlgItem(hwndDlg, IDC_TXT_INFO), TranslateT("Account is disabled. Please activate it to access options."));
+ }
+ else {
+ mir_snprintf(svc, SIZEOF(svc), "%s%s", pa->szModuleName, PS_CREATEACCMGRUI);
+ hwnd = (HWND)CallService(svc, 0, (LPARAM)hwndDlg);
+ if (hwnd && (hwnd != (HWND)CALLSERVICE_NOTFOUND)) {
+ RECT rc;
+
+ ShowWindow(GetDlgItem(hwndDlg, IDC_TXT_INFO), SW_HIDE);
+
+ GetWindowRect(GetDlgItem(hwndDlg, IDC_TXT_INFO), &rc);
+ MapWindowPoints(NULL, hwndDlg, (LPPOINT)&rc, 2);
+ SetWindowPos(hwnd, hwndList, rc.left, rc.top, 0, 0, SWP_NOSIZE|SWP_SHOWWINDOW);
+
+ pa->hwndAccMgrUI = hwnd;
+ }
+ else {
+ ShowWindow(GetDlgItem(hwndDlg, IDC_TXT_INFO), SW_SHOW);
+ SetWindowText(GetDlgItem(hwndDlg, IDC_TXT_INFO), TranslateT(legacyMsg));
+ } }
+ return;
+ } }
+
+ EnableWindow( GetDlgItem( hwndDlg, IDC_UPGRADE ), FALSE );
+ EnableWindow( GetDlgItem( hwndDlg, IDC_EDIT ), FALSE );
+ EnableWindow( GetDlgItem( hwndDlg, IDC_REMOVE ), FALSE );
+ EnableWindow( GetDlgItem( hwndDlg, IDC_OPTIONS ), FALSE );
+
+ ShowWindow(GetDlgItem(hwndDlg, IDC_TXT_INFO), SW_SHOW);
+ SetWindowText(GetDlgItem(hwndDlg, IDC_TXT_INFO), TranslateT(welcomeMsg));
+}
+
+INT_PTR CALLBACK AccMgrDlgProc(HWND hwndDlg,UINT message, WPARAM wParam, LPARAM lParam)
+{
+ struct TAccMgrData *dat = (struct TAccMgrData *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+
+ switch(message) {
+ case WM_INITDIALOG:
+ {
+ TAccMgrData *dat = (TAccMgrData *)mir_alloc(sizeof(TAccMgrData));
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)dat);
+
+ TranslateDialogDefault(hwndDlg);
+ Window_SetIcon_IcoLib( hwndDlg, SKINICON_OTHER_ACCMGR );
+
+ Button_SetIcon_IcoLib(hwndDlg, IDC_ADD, SKINICON_OTHER_ADDCONTACT, LPGEN("New account"));
+ Button_SetIcon_IcoLib(hwndDlg, IDC_EDIT, SKINICON_OTHER_RENAME, LPGEN("Edit"));
+ Button_SetIcon_IcoLib(hwndDlg, IDC_REMOVE, SKINICON_OTHER_DELETE, LPGEN("Remove account"));
+ Button_SetIcon_IcoLib(hwndDlg, IDC_OPTIONS, SKINICON_OTHER_OPTIONS, LPGEN( "Configure..."));
+ Button_SetIcon_IcoLib(hwndDlg, IDC_UPGRADE, SKINICON_OTHER_ACCMGR, LPGEN("Upgrade account"));
+
+ EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVE), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_OPTIONS), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_UPGRADE), FALSE);
+
+ {
+ LOGFONT lf;
+ HDC hdc;
+ HFONT hfnt;
+ TEXTMETRIC tm;
+
+ GetObject((HFONT)SendMessage(hwndDlg, WM_GETFONT, 0, 0), sizeof(lf), &lf);
+ dat->hfntText = CreateFontIndirect(&lf);
+
+ GetObject((HFONT)SendMessage(hwndDlg, WM_GETFONT, 0, 0), sizeof(lf), &lf);
+ lf.lfWeight = FW_BOLD;
+ dat->hfntTitle = CreateFontIndirect(&lf);
+
+ hdc = GetDC(hwndDlg);
+ hfnt = ( HFONT )SelectObject(hdc, dat->hfntTitle);
+ GetTextMetrics(hdc, &tm);
+ dat->titleHeight = tm.tmHeight;
+ SelectObject(hdc, dat->hfntText);
+ GetTextMetrics(hdc, &tm);
+ dat->textHeight = tm.tmHeight;
+ SelectObject(hdc, hfnt);
+ ReleaseDC(hwndDlg, hdc);
+
+ dat->normalHeight = 4 + max(dat->titleHeight, GetSystemMetrics(SM_CYSMICON));
+ dat->selectedHeight = dat->normalHeight + 4 + 2 * dat->textHeight;
+
+ SendDlgItemMessage(hwndDlg, IDC_NAME, WM_SETFONT, (WPARAM)dat->hfntTitle, 0);
+ SendDlgItemMessage(hwndDlg, IDC_TXT_ACCOUNT, WM_SETFONT, (WPARAM)dat->hfntTitle, 0);
+ SendDlgItemMessage(hwndDlg, IDC_TXT_ADDITIONAL, WM_SETFONT, (WPARAM)dat->hfntTitle, 0);
+ }
+
+ dat->iSelected = -1;
+ sttSubclassAccList(GetDlgItem(hwndDlg, IDC_ACCLIST), TRUE);
+ SendMessage( hwndDlg, WM_MY_REFRESH, 0, 0 );
+
+ Utils_RestoreWindowPositionNoSize(hwndDlg, NULL, "AccMgr", "");
+ }
+ return TRUE;
+
+ case WM_CTLCOLORSTATIC:
+ switch ( GetDlgCtrlID(( HWND )lParam )) {
+ case IDC_WHITERECT:
+ case IDC_NAME:
+ SetBkColor(( HDC )wParam, GetSysColor( COLOR_WINDOW ));
+ return ( INT_PTR )GetSysColorBrush( COLOR_WINDOW );
+ }
+ break;
+
+ case WM_MEASUREITEM:
+ {
+ LPMEASUREITEMSTRUCT lps = (LPMEASUREITEMSTRUCT)lParam;
+ PROTOACCOUNT *acc = (PROTOACCOUNT *)lps->itemData;
+
+ if ((lps->CtlID != IDC_ACCLIST) || !acc)
+ break;
+
+ lps->itemWidth = 10;
+ lps->itemHeight = dat->normalHeight;
+ }
+ return TRUE;
+
+ case WM_DRAWITEM:
+ {
+ int tmp, size, length;
+ TCHAR *text;
+ HICON hIcon;
+ HBRUSH hbrBack;
+ SIZE sz;
+
+ int cxIcon = GetSystemMetrics(SM_CXSMICON);
+ int cyIcon = GetSystemMetrics(SM_CYSMICON);
+
+ LPDRAWITEMSTRUCT lps = (LPDRAWITEMSTRUCT)lParam;
+ PROTOACCOUNT *acc = (PROTOACCOUNT *)lps->itemData;
+
+ if ((lps->CtlID != IDC_ACCLIST) || (lps->itemID == -1) || !acc)
+ break;
+
+ SetBkMode(lps->hDC, TRANSPARENT);
+ if (lps->itemState & ODS_SELECTED) {
+ hbrBack = GetSysColorBrush(COLOR_HIGHLIGHT);
+ SetTextColor(lps->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
+ }
+ else {
+ hbrBack = GetSysColorBrush(COLOR_WINDOW);
+ SetTextColor(lps->hDC, GetSysColor(COLOR_WINDOWTEXT));
+ }
+ FillRect(lps->hDC, &lps->rcItem, hbrBack);
+
+ lps->rcItem.left += 2;
+ lps->rcItem.top += 2;
+ lps->rcItem.bottom -= 2;
+
+ if ( acc->bOldProto )
+ tmp = SKINICON_OTHER_ON;
+ else if ( acc->bDynDisabled )
+ tmp = SKINICON_OTHER_OFF;
+ else
+ tmp = acc->bIsEnabled ? SKINICON_OTHER_TICK : SKINICON_OTHER_NOTICK;
+
+ hIcon = LoadSkinnedIcon(tmp);
+ DrawIconEx(lps->hDC, lps->rcItem.left, lps->rcItem.top, hIcon, cxIcon, cyIcon, 0, hbrBack, DI_NORMAL);
+ IconLib_ReleaseIcon(hIcon, 0);
+
+ lps->rcItem.left += cxIcon + 2;
+
+ if (acc->ppro) {
+ hIcon = acc->ppro->GetIcon( PLI_PROTOCOL | PLIF_SMALL );
+ DrawIconEx(lps->hDC, lps->rcItem.left, lps->rcItem.top, hIcon, cxIcon, cyIcon, 0, hbrBack, DI_NORMAL);
+ DestroyIcon(hIcon);
+ }
+ lps->rcItem.left += cxIcon + 2;
+
+ length = SendDlgItemMessage(hwndDlg, IDC_ACCLIST, LB_GETTEXTLEN, lps->itemID, 0);
+ size = max(length+1, 256);
+ text = (TCHAR *)_alloca(sizeof(TCHAR) * size);
+ SendDlgItemMessage(hwndDlg, IDC_ACCLIST, LB_GETTEXT, lps->itemID, (LPARAM)text);
+
+ SelectObject(lps->hDC, dat->hfntTitle);
+ tmp = lps->rcItem.bottom;
+ lps->rcItem.bottom = lps->rcItem.top + max(cyIcon, dat->titleHeight);
+ DrawText(lps->hDC, text, -1, &lps->rcItem, DT_LEFT|DT_NOPREFIX|DT_SINGLELINE|DT_END_ELLIPSIS|DT_VCENTER);
+ lps->rcItem.bottom = tmp;
+ GetTextExtentPoint32(lps->hDC, text, length, &sz);
+ lps->rcItem.top += max(cxIcon, sz.cy) + 2;
+
+ if (lps->itemID == (unsigned)dat->iSelected) {
+ SelectObject(lps->hDC, dat->hfntText);
+ mir_sntprintf(text, size, _T("%s: ") _T(TCHAR_STR_PARAM), TranslateT("Protocol"), acc->szProtoName);
+ length = lstrlen(text);
+ DrawText(lps->hDC, text, -1, &lps->rcItem, DT_LEFT|DT_NOPREFIX|DT_SINGLELINE|DT_END_ELLIPSIS);
+ GetTextExtentPoint32(lps->hDC, text, length, &sz);
+ lps->rcItem.top += sz.cy + 2;
+
+ if (acc->ppro && Proto_IsProtocolLoaded(acc->szProtoName)) {
+ char *szIdName;
+ TCHAR *tszIdName;
+ CONTACTINFO ci = { 0 };
+
+ szIdName = (char *)acc->ppro->GetCaps( PFLAG_UNIQUEIDTEXT, 0 );
+ tszIdName = szIdName ? mir_a2t(szIdName) : mir_tstrdup(TranslateT("Account ID"));
+
+ ci.cbSize = sizeof(ci);
+ ci.hContact = NULL;
+ ci.szProto = acc->szModuleName;
+ ci.dwFlag = CNF_UNIQUEID | CNF_TCHAR;
+ if ( !CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM) & ci)) {
+ switch (ci.type) {
+ case CNFT_ASCIIZ:
+ mir_sntprintf( text, size, _T("%s: %s"), tszIdName, ci.pszVal );
+ mir_free(ci.pszVal);
+ break;
+ case CNFT_DWORD:
+ mir_sntprintf( text, size, _T("%s: %d"), tszIdName, ci.dVal );
+ break;
+ }
+ }
+ else mir_sntprintf(text, size, _T("%s: %s"), tszIdName, TranslateT("<unknown>"));
+ mir_free(tszIdName);
+ }
+ else mir_sntprintf(text, size, TranslateT("Protocol is not loaded."));
+
+ length = lstrlen(text);
+ DrawText(lps->hDC, text, -1, &lps->rcItem, DT_LEFT|DT_NOPREFIX|DT_SINGLELINE|DT_END_ELLIPSIS);
+ GetTextExtentPoint32(lps->hDC, text, length, &sz);
+ lps->rcItem.top += sz.cy + 2;
+ } }
+ return TRUE;
+
+ case WM_MY_REFRESH:
+ {
+ HWND hList = GetDlgItem(hwndDlg, IDC_ACCLIST);
+ int i = ListBox_GetCurSel(hList);
+ PROTOACCOUNT *acc = (i == LB_ERR) ? NULL : (PROTOACCOUNT *)ListBox_GetItemData(hList, i);
+
+ dat->iSelected = -1;
+ SendMessage( hList, LB_RESETCONTENT, 0, 0 );
+ for (i = 0; i < accounts.getCount(); ++i) {
+ int iItem = SendMessage(hList, LB_ADDSTRING, 0, (LPARAM)accounts[i]->tszAccountName);
+ SendMessage(hList, LB_SETITEMDATA, iItem, (LPARAM)accounts[i]);
+
+ if (accounts[i] == acc)
+ ListBox_SetCurSel(hList, iItem);
+ }
+
+ dat->iSelected = ListBox_GetCurSel(hList); // -1 if error => nothing selected in our case
+ if (dat->iSelected >= 0)
+ sttSelectItem(dat, hList, dat->iSelected);
+ else if (acc && acc->hwndAccMgrUI)
+ ShowWindow(acc->hwndAccMgrUI, SW_HIDE);
+
+ sttUpdateAccountInfo(hwndDlg, dat);
+ }
+ break;
+
+ case WM_CONTEXTMENU:
+ if ( GetWindowLongPtr(( HWND )wParam, GWL_ID ) == IDC_ACCLIST ) {
+ HWND hwndList = GetDlgItem( hwndDlg, IDC_ACCLIST );
+ POINT pt = { (signed short)LOWORD( lParam ), (signed short)HIWORD( lParam ) };
+ int iItem = ListBox_GetCurSel( hwndList );
+
+ if (( pt.x == -1 ) && ( pt.y == -1 )) {
+ if (iItem != LB_ERR) {
+ RECT rc;
+ ListBox_GetItemRect( hwndList, iItem, &rc );
+ pt.x = rc.left + GetSystemMetrics(SM_CXSMICON) + 4;
+ pt.y = rc.top + 4 + max(GetSystemMetrics(SM_CXSMICON), dat->titleHeight);
+ ClientToScreen( hwndList, &pt );
+ }
+ }
+ else {
+ // menu was activated with mouse => find item under cursor & set focus to our control.
+ POINT ptItem = pt;
+ ScreenToClient( hwndList, &ptItem );
+ iItem = (short)LOWORD(SendMessage(hwndList, LB_ITEMFROMPOINT, 0, MAKELPARAM(ptItem.x, ptItem.y)));
+ if (iItem != LB_ERR)
+ {
+ ListBox_SetCurSel(hwndList, iItem);
+ sttUpdateAccountInfo(hwndDlg, dat);
+ sttSelectItem(dat, hwndList, iItem);
+ SetFocus(hwndList);
+ }
+ }
+
+ if ( iItem != LB_ERR ) {
+ PROTOACCOUNT* pa = (PROTOACCOUNT*)ListBox_GetItemData(hwndList, iItem);
+ HMENU hMenu = CreatePopupMenu();
+ if ( !pa->bOldProto && !pa->bDynDisabled )
+ AppendMenu(hMenu, MF_STRING, 1, TranslateT("Rename"));
+
+ AppendMenu(hMenu, MF_STRING, 3, TranslateT("Delete"));
+
+ if ( Proto_IsAccountEnabled( pa ))
+ AppendMenu(hMenu, MF_STRING, 4, TranslateT("Configure"));
+
+ if ( pa->bOldProto || pa->bDynDisabled )
+ AppendMenu(hMenu, MF_STRING, 5, TranslateT("Upgrade"));
+
+ AppendMenu(hMenu, MF_SEPARATOR, 0, NULL);
+ AppendMenu(hMenu, MF_STRING, 0, TranslateT("Cancel"));
+ switch (TrackPopupMenu( hMenu, TPM_RETURNCMD, pt.x, pt.y, 0, hwndDlg, NULL )) {
+ case 1:
+ PostMessage(hwndList, WM_MY_RENAME, 0, 0);
+ break;
+
+ case 2:
+ sttClickButton(hwndDlg, IDC_EDIT);
+ break;
+
+ case 3:
+ sttClickButton(hwndDlg, IDC_REMOVE);
+ break;
+
+ case 4:
+ sttClickButton(hwndDlg, IDC_OPTIONS);
+ break;
+
+ case 5:
+ sttClickButton(hwndDlg, IDC_UPGRADE);
+ break;
+ }
+ DestroyMenu( hMenu );
+ }
+ }
+ break;
+
+ case WM_COMMAND:
+ switch( LOWORD(wParam)) {
+ case IDC_ACCLIST:
+ {
+ HWND hwndList = GetDlgItem(hwndDlg, IDC_ACCLIST);
+ switch (HIWORD(wParam)) {
+ case LBN_SELCHANGE:
+ sttUpdateAccountInfo(hwndDlg, dat);
+ sttSelectItem(dat, hwndList, ListBox_GetCurSel(hwndList));
+ SetFocus(hwndList);
+ break;
+
+ case LBN_DBLCLK:
+ PostMessage(hwndList, WM_MY_RENAME, 0, 0);
+ break;
+
+ case LBN_MY_CHECK:
+ {
+ PROTOACCOUNT *pa = (PROTOACCOUNT *)ListBox_GetItemData(hwndList, lParam);
+ if ( pa ) {
+ if ( pa->bOldProto || pa->bDynDisabled)
+ break;
+
+ pa->bIsEnabled = !pa->bIsEnabled;
+ if ( pa->bIsEnabled ) {
+ if ( ActivateAccount( pa )) {
+ pa->ppro->OnEvent( EV_PROTO_ONLOAD, 0, 0 );
+ if (!DBGetContactSettingByte(NULL, "CList", "MoveProtoMenus", FALSE))
+ pa->ppro->OnEvent( EV_PROTO_ONMENU, 0, 0 );
+ }
+ else pa->type = PROTOTYPE_DISPROTO;
+ }
+ else {
+ DWORD dwStatus = CallProtoService(pa->szModuleName, PS_GETSTATUS, 0, 0);
+ if (dwStatus >= ID_STATUS_ONLINE) {
+ if (IDCANCEL == ::MessageBox(hwndDlg,
+ TranslateT("Account is online. Disable account?"),
+ TranslateT("Accounts"), MB_OKCANCEL)) {
+ pa->bIsEnabled = 1; //stay enabled
+ }
+ }
+
+ if ( !pa->bIsEnabled )
+ DeactivateAccount( pa, true, false );
+ }
+
+ WriteDbAccounts();
+ NotifyEventHooks( hAccListChanged, PRAC_CHECKED, ( LPARAM )pa );
+ sttUpdateAccountInfo(hwndDlg, dat);
+ RedrawWindow(hwndList, NULL, NULL, RDW_INVALIDATE);
+ } }
+ break;
+
+ case LBN_MY_RENAME:
+ {
+ int iItem = ListBox_GetCurSel(hwndList);
+ PROTOACCOUNT *pa = (PROTOACCOUNT *)ListBox_GetItemData(hwndList, iItem);
+ if ( pa ) {
+ mir_free(pa->tszAccountName);
+ pa->tszAccountName = (TCHAR*)lParam;
+ WriteDbAccounts();
+ NotifyEventHooks(hAccListChanged, PRAC_CHANGED, (LPARAM)pa);
+
+ ListBox_DeleteString(hwndList, iItem);
+ iItem = ListBox_AddString(hwndList, pa->tszAccountName);
+ ListBox_SetItemData(hwndList, iItem, (LPARAM)pa);
+ ListBox_SetCurSel(hwndList, iItem);
+
+ sttSelectItem(dat, hwndList, iItem);
+
+ RedrawWindow(hwndList, NULL, NULL, RDW_INVALIDATE);
+ }
+ else mir_free((TCHAR*)lParam);
+ }
+ break;
+ } }
+ break;
+
+ case IDC_ADD:
+ {
+ AccFormDlgParam param = { PRAC_ADDED, NULL };
+ if ( IDOK == DialogBoxParam( hMirandaInst, MAKEINTRESOURCE(IDD_ACCFORM), hwndDlg, AccFormDlgProc, (LPARAM)&param ))
+ SendMessage( hwndDlg, WM_MY_REFRESH, 0, 0 );
+ }
+ break;
+
+ case IDC_EDIT:
+ {
+ HWND hList = GetDlgItem( hwndDlg, IDC_ACCLIST );
+ int idx = ListBox_GetCurSel( hList );
+ if ( idx != -1 )
+ PostMessage(hList, WM_MY_RENAME, 0, 0);
+ }
+ break;
+
+ case IDC_REMOVE:
+ {
+ HWND hList = GetDlgItem( hwndDlg, IDC_ACCLIST );
+ int idx = ListBox_GetCurSel( hList );
+ if ( idx != -1 ) {
+ PROTOACCOUNT* pa = ( PROTOACCOUNT* )ListBox_GetItemData( hList, idx );
+ TCHAR buf[ 200 ];
+ mir_sntprintf( buf, SIZEOF(buf), TranslateT( "Account %s is being deleted" ), pa->tszAccountName );
+ if (pa->bOldProto) {
+ MessageBox( NULL, TranslateT( "You need to disable plugin to delete this account" ), buf,
+ MB_ICONERROR | MB_OK );
+ break;
+ }
+ if ( IDYES == MessageBox( NULL, TranslateT( errMsg ), buf, MB_ICONSTOP | MB_DEFBUTTON2 | MB_YESNO )) {
+ // lock controls to avoid changes during remove process
+ ListBox_SetCurSel( hList, -1 );
+ sttUpdateAccountInfo( hwndDlg, dat );
+ EnableWindow( hList, FALSE );
+ EnableWindow( GetDlgItem(hwndDlg, IDC_ADD), FALSE );
+
+ ListBox_SetItemData( hList, idx, 0 );
+
+ accounts.remove( pa );
+
+ CheckProtocolOrder();
+
+ WriteDbAccounts();
+ NotifyEventHooks( hAccListChanged, PRAC_REMOVED, ( LPARAM )pa );
+
+ UnloadAccount( pa, true, true );
+ SendMessage( hwndDlg, WM_MY_REFRESH, 0, 0 );
+
+ EnableWindow( hList, TRUE );
+ EnableWindow( GetDlgItem(hwndDlg, IDC_ADD), TRUE );
+ } } }
+ break;
+
+ case IDC_OPTIONS:
+ {
+ HWND hList = GetDlgItem( hwndDlg, IDC_ACCLIST );
+ int idx = ListBox_GetCurSel( hList );
+ if ( idx != -1 ) {
+ PROTOACCOUNT* pa = ( PROTOACCOUNT* )ListBox_GetItemData( hList, idx );
+ if ( pa->bOldProto ) {
+ OPENOPTIONSDIALOG ood;
+ ood.cbSize = sizeof(ood);
+ ood.pszGroup = "Network";
+ ood.pszPage = pa->szModuleName;
+ ood.pszTab = NULL;
+ CallService( MS_OPT_OPENOPTIONS, 0, (LPARAM)&ood );
+ }
+ else OpenAccountOptions( pa );
+ } }
+ break;
+
+ case IDC_UPGRADE:
+ {
+ HWND hList = GetDlgItem( hwndDlg, IDC_ACCLIST );
+ int idx = ListBox_GetCurSel( hList );
+ if ( idx != -1 ) {
+ AccFormDlgParam param = { PRAC_UPGRADED, ( PROTOACCOUNT* )ListBox_GetItemData( hList, idx ) };
+ DialogBoxParam( hMirandaInst, MAKEINTRESOURCE(IDD_ACCFORM), hwndDlg, AccFormDlgProc, (LPARAM)&param );
+ } }
+ break;
+
+ case IDC_LNK_NETWORK:
+ {
+ PSHNOTIFY pshn = {0};
+ pshn.hdr.code = PSN_APPLY;
+ pshn.hdr.hwndFrom = hwndDlg;
+ SendMessage(hwndDlg, WM_NOTIFY, 0, (LPARAM)&pshn);
+
+ OPENOPTIONSDIALOG ood = {0};
+ ood.cbSize = sizeof(ood);
+ ood.pszPage = "Network";
+ CallService( MS_OPT_OPENOPTIONS, 0, (LPARAM)&ood );
+ break;
+ }
+
+ case IDC_LNK_ADDONS:
+ CallService(MS_UTILS_OPENURL, TRUE, (LPARAM)"http://addons.miranda-im.org/");
+ break;
+
+ case IDOK:
+ {
+ PSHNOTIFY pshn = {0};
+ pshn.hdr.code = PSN_APPLY;
+ pshn.hdr.hwndFrom = hwndDlg;
+ SendMessage(hwndDlg, WM_NOTIFY, 0, (LPARAM)&pshn);
+ DestroyWindow(hwndDlg);
+ break;
+ }
+
+ case IDCANCEL:
+ {
+ PSHNOTIFY pshn = {0};
+ pshn.hdr.code = PSN_RESET;
+ pshn.hdr.hwndFrom = hwndDlg;
+ SendMessage(hwndDlg, WM_NOTIFY, 0, (LPARAM)&pshn);
+ DestroyWindow(hwndDlg);
+ break;
+ }
+ }
+ case PSM_CHANGED:
+ {
+ HWND hList = GetDlgItem( hwndDlg, IDC_ACCLIST );
+ int idx = ListBox_GetCurSel( hList );
+ if ( idx != -1 ) {
+ PROTOACCOUNT *acc = (PROTOACCOUNT *)ListBox_GetItemData(hList, idx);
+ if (acc)
+ {
+ acc->bAccMgrUIChanged = TRUE;
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ }
+ }
+ break;
+ }
+ case WM_NOTIFY:
+ switch(((LPNMHDR)lParam)->idFrom) {
+ case 0:
+ switch (((LPNMHDR)lParam)->code) {
+ case PSN_APPLY:
+ {
+ int i;
+ PSHNOTIFY pshn = {0};
+ pshn.hdr.code = PSN_APPLY;
+ for (i = 0; i < accounts.getCount(); ++i) {
+ if ( accounts[i]->hwndAccMgrUI && accounts[i]->bAccMgrUIChanged ) {
+ pshn.hdr.hwndFrom = accounts[i]->hwndAccMgrUI;
+ SendMessage(accounts[i]->hwndAccMgrUI, WM_NOTIFY, 0, (LPARAM)&pshn);
+ accounts[i]->bAccMgrUIChanged = FALSE;
+ } }
+ return TRUE;
+ }
+ case PSN_RESET:
+ {
+ int i;
+ PSHNOTIFY pshn = {0};
+ pshn.hdr.code = PSN_RESET;
+ for (i = 0; i < accounts.getCount(); ++i) {
+ if ( accounts[i]->hwndAccMgrUI && accounts[i]->bAccMgrUIChanged ) {
+ pshn.hdr.hwndFrom = accounts[i]->hwndAccMgrUI;
+ SendMessage(accounts[i]->hwndAccMgrUI, WM_NOTIFY, 0, (LPARAM)&pshn);
+ accounts[i]->bAccMgrUIChanged = FALSE;
+ } }
+ return TRUE;
+ }
+ }
+ break;
+ }
+ break;
+ case WM_DESTROY:
+ {
+ for (int i = 0; i < accounts.getCount(); ++i) {
+ accounts[i]->bAccMgrUIChanged = FALSE;
+ if (accounts[i]->hwndAccMgrUI) {
+ DestroyWindow(accounts[i]->hwndAccMgrUI);
+ accounts[i]->hwndAccMgrUI = NULL;
+ } } }
+
+ Window_FreeIcon_IcoLib( hwndDlg );
+ Button_FreeIcon_IcoLib( hwndDlg, IDC_ADD );
+ Button_FreeIcon_IcoLib( hwndDlg, IDC_EDIT );
+ Button_FreeIcon_IcoLib( hwndDlg, IDC_REMOVE );
+ Button_FreeIcon_IcoLib( hwndDlg, IDC_OPTIONS );
+ Button_FreeIcon_IcoLib( hwndDlg, IDC_UPGRADE );
+ Utils_SaveWindowPosition( hwndDlg, NULL, "AccMgr", "");
+ sttSubclassAccList(GetDlgItem(hwndDlg, IDC_ACCLIST), FALSE);
+ DeleteObject(dat->hfntTitle);
+ DeleteObject(dat->hfntText);
+ mir_free(dat);
+ hAccMgr = NULL;
+ break;
+ }
+
+ return FALSE;
+}
+
+static INT_PTR OptProtosShow(WPARAM, LPARAM)
+{
+ if ( !hAccMgr )
+ hAccMgr = CreateDialogParam( hMirandaInst, MAKEINTRESOURCE(IDD_ACCMGR), NULL, AccMgrDlgProc, 0 );
+
+ ShowWindow( hAccMgr, SW_RESTORE );
+ SetForegroundWindow( hAccMgr );
+ SetActiveWindow( hAccMgr );
+ return 0;
+}
+
+int OptProtosLoaded(WPARAM, LPARAM)
+{
+ CLISTMENUITEM mi = { 0 };
+ mi.cbSize = sizeof(mi);
+ mi.flags = CMIF_ICONFROMICOLIB;
+ mi.icolibItem = GetSkinIconHandle( SKINICON_OTHER_ACCMGR );
+ mi.position = 1900000000;
+ mi.pszName = LPGEN("&Accounts...");
+ mi.pszService = MS_PROTO_SHOWACCMGR;
+ CallService( MS_CLIST_ADDMAINMENUITEM, 0, ( LPARAM )&mi );
+ return 0;
+}
+
+static int OnAccListChanged( WPARAM eventCode, LPARAM lParam )
+{
+ PROTOACCOUNT* pa = (PROTOACCOUNT*)lParam;
+
+ switch( eventCode ) {
+ case PRAC_CHANGED:
+ if ( pa->ppro ) {
+ mir_free( pa->ppro->m_tszUserName );
+ pa->ppro->m_tszUserName = mir_tstrdup( pa->tszAccountName );
+ pa->ppro->OnEvent( EV_PROTO_ONRENAME, 0, lParam );
+ }
+ }
+
+ return 0;
+}
+
+static int ShutdownAccMgr(WPARAM, LPARAM)
+{
+ if ( IsWindow( hAccMgr ))
+ DestroyWindow( hAccMgr );
+ hAccMgr = NULL;
+ return 0;
+}
+
+int LoadProtoOptions( void )
+{
+ CreateServiceFunction( MS_PROTO_SHOWACCMGR, OptProtosShow );
+
+ HookEvent( ME_SYSTEM_MODULESLOADED, OptProtosLoaded );
+ HookEvent( ME_PROTO_ACCLISTCHANGED, OnAccListChanged );
+ HookEvent( ME_SYSTEM_PRESHUTDOWN, ShutdownAccMgr );
+ return 0;
+}