From 0a1ec91589a265b41210068b8d21fa469e750a08 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Thu, 14 Aug 2014 12:12:35 +0000 Subject: account creation code extracted to the separate service function, MS_PROTO_CREATEACCOUNT git-svn-id: http://svn.miranda-ng.org/main/trunk@10181 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- include/delphi/m_protocols.inc | 25 ++- include/m_protocols.h | 265 +++++++++++++++++--------------- src/core/miranda.h | 8 +- src/modules/protocols/protocols.cpp | 15 ++ src/modules/protocols/protoopts.cpp | 292 +++++++++++++++++++----------------- 5 files changed, 331 insertions(+), 274 deletions(-) diff --git a/include/delphi/m_protocols.inc b/include/delphi/m_protocols.inc index 9cf6007b4f..ef17ae9dff 100644 --- a/include/delphi/m_protocols.inc +++ b/include/delphi/m_protocols.inc @@ -273,20 +273,29 @@ type end; tagACCOUNT = TPROTOACCOUNT; -const //account enumeration service //wParam=(WPARAM)(int)piNumAccounts //lParam=(LPARAM)(PROTOACCOUNT**)paAccounts +const MS_PROTO_ENUMACCOUNTS:PAnsiChar = 'Proto/EnumAccounts'; - MS_PROTO_ENUMPROTOS :PAnsiChar = 'Proto/EnumProtos'; // MIRANDA_VER >= $800 -// MS_PROTO_ENUMPROTOCOLS:PAnsiChar = 'Proto/EnumProtocols';// MIRANDA_VER < $800 + MS_PROTO_ENUMPROTOS:PAnsiChar = 'Proto/EnumProtos'; // MIRANDA_VER >= $800 + +type + PACC_CREATE = ^ACC_CREATE; + ACC_CREATE = record + pszBaseProto :PAnsiChar; + pszInternal :PAnsiChar; + ptszAccountName:PWideChar; + end; + +const +// creates new account +// wParam = 0 +// lParam = (LPARAM)(ACC_CREATE*) account definition +// return value = PROTOACCOUNT* or NULL + MS_PROTO_CREATEACCOUNT:PAnsiChar = 'Proto/CreateAccount'; -(* -__inline int ProtoEnumAccounts( int* accNumber, PROTOACCOUNT*** accArray ) -{ return CallService( MS_PROTO_ENUMACCOUNTS, ( WPARAM )accNumber, (LPARAM)accArray ); -} -*) //retrieves an account's interface by its physical name (database module) //wParam=0 //lParam=(LPARAM)(AnsiChar*)szAccountName diff --git a/include/m_protocols.h b/include/m_protocols.h index 54533cee57..fc21f8d9a4 100644 --- a/include/m_protocols.h +++ b/include/m_protocols.h @@ -2,7 +2,7 @@ Miranda NG: the free IM client for Microsoft* Windows* -Copyright (c) 2012-14 Miranda NG project (http://miranda-ng.org) +Copyright (c) 2012-14 Miranda NG project (http:// miranda-ng.org) Copyright (c) 2000-08 Miranda ICQ/IM project, all portions of this codebase are copyrighted to the people listed in contributors.txt. @@ -22,7 +22,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -//this module was created in v0.1.1.0 +// this module was created in v0.1.1.0 #ifndef M_PROTOCOLS_H__ #define M_PROTOCOLS_H__ 1 @@ -31,34 +31,34 @@ struct PROTO_INTERFACE; #include "statusmodes.h" -//send a general request through the protocol chain for a contact -//wParam = 0 -//lParam = (LPARAM)(CCSDATA*)&ccs -//returns the value as documented in the PS_ definition (m_protosvc.h) +// send a general request through the protocol chain for a contact +// wParam = 0 +// lParam = (LPARAM)(CCSDATA*)&ccs +// returns the value as documented in the PS_ definition (m_protosvc.h) typedef struct { MCONTACT hContact; - const char *szProtoService; //a PS_ constant + const char *szProtoService; // a PS_ constant WPARAM wParam; LPARAM lParam; } CCSDATA; #define MS_PROTO_CALLCONTACTSERVICE "Proto/CallContactService" -//a general network 'ack' -//wParam = 0 -//lParam = (LPARAM)(ACKDATA*)&ack -//Note that just because definitions are here doesn't mean they will be sent. -//Read the documentation for the function you are calling to see what replies -//you will receive. +// a general network 'ack' +// wParam = 0 +// lParam = (LPARAM)(ACKDATA*)&ack +// Note that just because definitions are here doesn't mean they will be sent. +// Read the documentation for the function you are calling to see what replies +// you will receive. typedef struct { int cbSize; - const char *szModule; //the name of the protocol module which initiated this ack + const char *szModule; // the name of the protocol module which initiated this ack MCONTACT hContact; - int type; //an ACKTYPE_ constant - int result; //an ACKRESULT_ constant - HANDLE hProcess; //a caller-defined process code - LPARAM lParam; //caller-defined extra info + int type; // an ACKTYPE_ constant + int result; // an ACKRESULT_ constant + HANDLE hProcess; // a caller-defined process code + LPARAM lParam; // caller-defined extra info } ACKDATA; #define ACKTYPE_MESSAGE 0 #define ACKTYPE_URL 1 @@ -73,26 +73,26 @@ typedef struct { #define ACKTYPE_SEARCH 10 #define ACKTYPE_NEWUSER 11 #define ACKTYPE_STATUS 12 -#define ACKTYPE_CONTACTS 13 //send/recv of contacts -#define ACKTYPE_AVATAR 14 //send/recv of avatars from a protocol -#define ACKTYPE_EMAIL 15 //notify if the unread emails changed +#define ACKTYPE_CONTACTS 13 // send/recv of contacts +#define ACKTYPE_AVATAR 14 // send/recv of avatars from a protocol +#define ACKTYPE_EMAIL 15 // notify if the unread emails changed #define ACKRESULT_SUCCESS 0 #define ACKRESULT_FAILED 1 -//'in progress' result codes: +// 'in progress' result codes: #define ACKRESULT_CONNECTING 100 #define ACKRESULT_CONNECTED 101 #define ACKRESULT_INITIALISING 102 -#define ACKRESULT_SENTREQUEST 103 //waiting for reply... -#define ACKRESULT_DATA 104 //blob of file data sent/recved, or search result -#define ACKRESULT_NEXTFILE 105 //file transfer went to next file -#define ACKRESULT_FILERESUME 106 //a file is about to be received, see PS_FILERESUME -#define ACKRESULT_DENIED 107 //a file send has been denied -#define ACKRESULT_STATUS 108 //an ack or a series of acks to do with a task have a status change -#define ACKRESULT_LISTENING 109 //waiting for connection -#define ACKRESULT_CONNECTPROXY 110 //connecting to file proxy -#define ACKRESULT_SEARCHRESULT 111 //result of extended search +#define ACKRESULT_SENTREQUEST 103 // waiting for reply... +#define ACKRESULT_DATA 104 // blob of file data sent/recved, or search result +#define ACKRESULT_NEXTFILE 105 // file transfer went to next file +#define ACKRESULT_FILERESUME 106 // a file is about to be received, see PS_FILERESUME +#define ACKRESULT_DENIED 107 // a file send has been denied +#define ACKRESULT_STATUS 108 // an ack or a series of acks to do with a task have a status change +#define ACKRESULT_LISTENING 109 // waiting for connection +#define ACKRESULT_CONNECTPROXY 110 // connecting to file proxy +#define ACKRESULT_SEARCHRESULT 111 // result of extended search #define ME_PROTO_ACK "Proto/Ack" @@ -101,8 +101,8 @@ typedef struct { // long to be delivered". If no error message is specified, lParam must be NULL. // Right now only explanations from ACKTYPE_MESSAGE is shown. -//when type == ACKTYPE_FILE && (result == ACKRESULT_DATA || result == ACKRESULT_FILERESUME), -//lParam points to this +// when type == ACKTYPE_FILE && (result == ACKRESULT_DATA || result == ACKRESULT_FILERESUME), +// lParam points to this #define FNAMECHAR TCHAR @@ -148,30 +148,30 @@ typedef struct tagPROTOFILETRANSFERSTATUS unsigned __int64 currentFileSize; unsigned __int64 currentFileProgress; - unsigned __int64 currentFileTime; //as seconds since 1970 + unsigned __int64 currentFileTime; // as seconds since 1970 } PROTOFILETRANSFERSTATUS; -//Enumerate the currently running protocols -//wParam = (WPARAM)(int*)&numberOfProtocols -//lParam = (LPARAM)(PROTOCOLDESCRIPTOR***)&ppProtocolDescriptors -//Returns 0 on success, nonzero on failure -//Neither wParam nor lParam may be NULL -//The list returned by this service is the protocol modules currently installed -//and running. It is not the complete list of all protocols that have ever been -//installed. -//IMPORTANT NOTE #1: the list returned is not static, it may be changed in the -//program's lifetime. Do not use this list in the global context, copy protocols -//names otherwise. -//IMPORTANT NOTE #2: in version 0.8 this service is mapped to the MS_PROTO_ENUMACCOUNTS -//service to provide the compatibility with old plugins (first three members of -//PROTOACCOUNT are equal to the old PROTOCOLDESCRIPTOR format). If you declare the -//MIRANDA_VER macro with value greater or equal to 0x800, use MS_PROTO_ENUMPROTOS -//service instead to obtain the list of running protocols instead of accounts. -//Note that a protocol module need not be an interface to an Internet server, -//they can be encryption and loads of other things, too. -//And yes, before you ask, that is triple indirection. Deal with it. -//Access members using ppProtocolDescriptors[index]->element +// Enumerate the currently running protocols +// wParam = (WPARAM)(int*)&numberOfProtocols +// lParam = (LPARAM)(PROTOCOLDESCRIPTOR***)&ppProtocolDescriptors +// Returns 0 on success, nonzero on failure +// Neither wParam nor lParam may be NULL +// The list returned by this service is the protocol modules currently installed +// and running. It is not the complete list of all protocols that have ever been +// installed. +// IMPORTANT NOTE #1: the list returned is not static, it may be changed in the +// program's lifetime. Do not use this list in the global context, copy protocols +// names otherwise. +// IMPORTANT NOTE #2: in version 0.8 this service is mapped to the MS_PROTO_ENUMACCOUNTS +// service to provide the compatibility with old plugins (first three members of +// PROTOACCOUNT are equal to the old PROTOCOLDESCRIPTOR format). If you declare the +// MIRANDA_VER macro with value greater or equal to 0x800, use MS_PROTO_ENUMPROTOS +// service instead to obtain the list of running protocols instead of accounts. +// Note that a protocol module need not be an interface to an Internet server, +// they can be encryption and loads of other things, too. +// And yes, before you ask, that is triple indirection. Deal with it. +// Access members using ppProtocolDescriptors[index]->element #define PROTOCOLDESCRIPTOR_V3_SIZE (sizeof(size_t)+sizeof(INT_PTR)+sizeof(char*)) @@ -197,12 +197,12 @@ typedef struct { PROTOCOLDESCRIPTOR; // v0.3.3+: -// +// // For recv, it will go from lower to higher, so in this case: // check ignore, decrypt (encryption), translate -// +// // For send, it will go translate, encrypt, ignore(??), send -// +// // The DB will store higher numbers here, LOWER in the protocol chain, and lower numbers // here HIGHER in the protocol chain @@ -216,61 +216,61 @@ typedef struct { #define MS_PROTO_ENUMPROTOS "Proto/EnumProtos" -//determines if a protocol module is loaded or not -//wParam = 0 -//lParam = (LPARAM)(const char*)szName -//Returns a pointer to the PROTOACCOUNT if the protocol is loaded, or -//NULL if it isn't. +// determines if a protocol module is loaded or not +// wParam = 0 +// lParam = (LPARAM)(const char*)szName +// Returns a pointer to the PROTOACCOUNT if the protocol is loaded, or +// NULL if it isn't. #define MS_PROTO_ISPROTOCOLLOADED "Proto/IsProtocolLoaded" -//gets the network-level protocol associated with a contact -//wParam = (MCONTACT)hContact -//lParam = 0 -//Returns a char* pointing to the asciiz name of the protocol or NULL if the -//contact has no protocol. There is no need to free() it or anything. -//This is the name of the module that actually accesses the network for that -//contact. +// gets the network-level protocol associated with a contact +// wParam = (MCONTACT)hContact +// lParam = 0 +// Returns a char* pointing to the asciiz name of the protocol or NULL if the +// contact has no protocol. There is no need to free() it or anything. +// This is the name of the module that actually accesses the network for that +// contact. #define MS_PROTO_GETCONTACTBASEPROTO "Proto/GetContactBaseProto" __forceinline char* GetContactProto(MCONTACT hContact) { return (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, hContact, 0); } -//determines whether the specified contact has the given protocol in its chain -//wParam = (MCONTACT)hContact -//lParam = (LPARAM)(const char*)szName -//Returns -1 if it is base protocol, positive number if it is filter and 0 if it doesn't +// determines whether the specified contact has the given protocol in its chain +// wParam = (MCONTACT)hContact +// lParam = (LPARAM)(const char*)szName +// Returns -1 if it is base protocol, positive number if it is filter and 0 if it doesn't #define MS_PROTO_ISPROTOONCONTACT "Proto/IsProtoOnContact" #define PROTOTYPE_SELFTYPING_OFF 0 #define PROTOTYPE_SELFTYPING_ON 1 -//This service is for notifying protocols that the user is typing a message v0.3.3+ -//in a message dialog. -//This is typically sent by a message dialog when a user in the clist is typing. -//wParam = (MCONTACT)hContact -//lParam = (LPARAM)(int)typing state -//NOTE: Only protocols should generally call this service +// This service is for notifying protocols that the user is typing a message v0.3.3+ +// in a message dialog. +// This is typically sent by a message dialog when a user in the clist is typing. +// wParam = (MCONTACT)hContact +// lParam = (LPARAM)(int)typing state +// NOTE: Only protocols should generally call this service #define MS_PROTO_SELFISTYPING "Proto/SelfIsTyping" #define PROTOTYPE_CONTACTTYPING_OFF 0 #define PROTOTYPE_CONTACTTYPING_INFINITE 2147483647 -//This service is for notifying message dialogs/other plugins of a user typing. v0.3.3+ -//This is typically sent by a protocol when a user in the clist is typing. -//wParam = (MCONTACT)hContact -//lParam = (LPARAM)(int)time (secs) -//NOTE: The time in seconds is used to tell a message dialog (or other plugin) -//how long to display its notification. If time is 0, then notification -//of typing ends. -//NOTE: Only protocols should generally call this service +// This service is for notifying message dialogs/other plugins of a user typing. v0.3.3+ +// This is typically sent by a protocol when a user in the clist is typing. +// wParam = (MCONTACT)hContact +// lParam = (LPARAM)(int)time (secs) +// NOTE: The time in seconds is used to tell a message dialog (or other plugin) +// how long to display its notification. If time is 0, then notification +// of typing ends. +// NOTE: Only protocols should generally call this service #define MS_PROTO_CONTACTISTYPING "Proto/ContactIsTyping" -//This hook notifies when a user is typing. If a message dialog supports sending v0.3.3+ -//typing notifications it should hook this event and fire the -//ProtoService PSS_USERISTYPING to the contacts protocol *after* verifying -//that the hContact is not NULL and the the user wishes to send notifications -//to this user (checked visibility, individual typing blocking, etc). -//wParam = (MCONTACT)hContact -//lParam = (LPARAM)(int)typing state +// This hook notifies when a user is typing. If a message dialog supports sending v0.3.3+ +// typing notifications it should hook this event and fire the +// ProtoService PSS_USERISTYPING to the contacts protocol *after* verifying +// that the hContact is not NULL and the the user wishes to send notifications +// to this user (checked visibility, individual typing blocking, etc). +// wParam = (MCONTACT)hContact +// lParam = (LPARAM)(int)typing state #define ME_PROTO_CONTACTISTYPING "Proto/ContactIsTypingEvent" // -------------- accounts support --------------------- 0.8.0+ @@ -295,28 +295,46 @@ typedef struct tagACCOUNT } PROTOACCOUNT; -//account enumeration service -//wParam = (WPARAM)(int*)piNumAccounts -//lParam = (LPARAM)(PROTOACCOUNT**)paAccounts +// account enumeration service +// wParam = (WPARAM)(int*)piNumAccounts +// lParam = (LPARAM)(PROTOACCOUNT**)paAccounts #define MS_PROTO_ENUMACCOUNTS "Proto/EnumAccounts" __forceinline INT_PTR ProtoEnumAccounts(int* accNumber, PROTOACCOUNT*** accArray) { return CallService(MS_PROTO_ENUMACCOUNTS, (WPARAM)accNumber, (LPARAM)accArray); } -//retrieves an account's interface by its physical name (database module) -//wParam = 0 -//lParam = (LPARAM)(char*)szAccountName -//return value = PROTOACCOUNT* or NULL +// creates new account +// wParam = 0 +// lParam = (LPARAM)(ACC_CREATE*) account definition +// return value = PROTOACCOUNT* or NULL +#define MS_PROTO_CREATEACCOUNT "Proto/CreateAccount" + +typedef struct tagACC_CREATE +{ + const char *pszBaseProto; + const char *pszInternal; + const TCHAR *ptszAccountName; +} ACC_CREATE; + +__forceinline PROTOACCOUNT* ProtoCreateAccount(ACC_CREATE *pAccountDef) +{ return (PROTOACCOUNT*)CallService(MS_PROTO_CREATEACCOUNT, 0, (LPARAM)pAccountDef); +} + +// retrieves an account's interface by its physical name (database module) +// wParam = 0 +// lParam = (LPARAM)(char*)szAccountName +// return value = PROTOACCOUNT* or NULL #define MS_PROTO_GETACCOUNT "Proto/GetAccount" __forceinline PROTOACCOUNT* ProtoGetAccount(const char* accName) -{ return (PROTOACCOUNT*)CallService(MS_PROTO_GETACCOUNT, 0, (LPARAM)accName); +{ + return (PROTOACCOUNT*)CallService(MS_PROTO_GETACCOUNT, 0, (LPARAM)accName); } -//this event is fired when the accounts list gets changed -//wParam = event type (1 - added, 2 - changed, 3 - deleted, 4 - upgraded, 5 - enabled/disabled) -//lParam = (LPARAM)(PROTOACCOUNT*) - account being changed +// this event is fired when the accounts list gets changed +// wParam = event type (1 - added, 2 - changed, 3 - deleted, 4 - upgraded, 5 - enabled/disabled) +// lParam = (LPARAM)(PROTOACCOUNT*) - account being changed #define PRAC_ADDED 1 #define PRAC_CHANGED 2 @@ -324,18 +342,17 @@ __forceinline PROTOACCOUNT* ProtoGetAccount(const char* accName) #define PRAC_UPGRADED 4 #define PRAC_CHECKED 5 - #define ME_PROTO_ACCLISTCHANGED "Proto/AccListChanged" -//displays the Account Manager -//wParam = 0 -//lParam = 0 +// displays the Account Manager +// wParam = 0 +// lParam = 0 #define MS_PROTO_SHOWACCMGR "Protos/ShowAccountManager" -//determines if an account is enabled or not -//wParam = 0 -//lParam = (LPARAM)(PROTOACCOUNT*) -//Returns 1 if an account is valid and enabled, 0 otherwise +// determines if an account is enabled or not +// wParam = 0 +// lParam = (LPARAM)(PROTOACCOUNT*) +// Returns 1 if an account is valid and enabled, 0 otherwise #define MS_PROTO_ISACCOUNTENABLED "Proto/IsAccountEnabled" __forceinline int IsAccountEnabled(const PROTOACCOUNT *pa) @@ -343,20 +360,20 @@ __forceinline int IsAccountEnabled(const PROTOACCOUNT *pa) return (int)CallService(MS_PROTO_ISACCOUNTENABLED, 0, (LPARAM)pa); } -//determines if an account is locked or not -//wParam = 0 -//lParam = (LPARAM)(char*)szAccountName -//Returns 1 if an account is locked and not supposed to change status, 0 otherwise +// determines if an account is locked or not +// wParam = 0 +// lParam = (LPARAM)(char*)szAccountName +// Returns 1 if an account is locked and not supposed to change status, 0 otherwise #define MS_PROTO_ISACCOUNTLOCKED "Proto/IsAccountLocked" -//gets the account associated with a contact -//wParam = (MCONTACT)hContact -//lParam = 0 -//Returns a char* pointing to the asciiz name of the protocol or NULL if the -//contact has no protocol. There is no need to mir_free() it or anything. -//This is the name of the module that actually accesses the network for that -//contact. +// gets the account associated with a contact +// wParam = (MCONTACT)hContact +// lParam = 0 +// Returns a char* pointing to the asciiz name of the protocol or NULL if the +// contact has no protocol. There is no need to mir_free() it or anything. +// This is the name of the module that actually accesses the network for that +// contact. #define MS_PROTO_GETCONTACTBASEACCOUNT "Proto/GetContactBaseAccount" /* -------------- avatar support --------------------- diff --git a/src/core/miranda.h b/src/core/miranda.h index 29c3e48a5b..ccac4fc323 100644 --- a/src/core/miranda.h +++ b/src/core/miranda.h @@ -144,14 +144,16 @@ void KillModuleMenus(int hLangpack); extern LIST accounts; -PROTOACCOUNT* __fastcall Proto_GetAccount(const char* accName); +PROTOACCOUNT* Proto_CreateAccount(const char *szProtoName, const char *szBaseProto, const TCHAR *tszAccountName); + +PROTOACCOUNT* __fastcall Proto_GetAccount(const char *accName); PROTOACCOUNT* __fastcall Proto_GetAccount(MCONTACT hContact); -PROTOCOLDESCRIPTOR* __fastcall Proto_IsProtocolLoaded(const char* szProtoName); +PROTOCOLDESCRIPTOR* __fastcall Proto_IsProtocolLoaded(const char *szProtoName); bool __fastcall Proto_IsAccountEnabled(PROTOACCOUNT *pa); bool __fastcall Proto_IsAccountLocked(PROTOACCOUNT *pa); -PROTO_INTERFACE* AddDefaultAccount(const char* szProtoName); +PROTO_INTERFACE* AddDefaultAccount(const char *szProtoName); int FreeDefaultAccount(PROTO_INTERFACE* ppi); BOOL ActivateAccount(PROTOACCOUNT *pa); diff --git a/src/modules/protocols/protocols.cpp b/src/modules/protocols/protocols.cpp index 6d57eb10e9..f45378d173 100644 --- a/src/modules/protocols/protocols.cpp +++ b/src/modules/protocols/protocols.cpp @@ -319,6 +319,20 @@ PROTOACCOUNT* __fastcall Proto_GetAccount(const char* accName) return accounts[idx]; } +static INT_PTR srvProto_CreateAccount(WPARAM, LPARAM lParam) +{ + ACC_CREATE *p = (ACC_CREATE*)lParam; + if (p == NULL) + return NULL; + + PROTOACCOUNT *pa = Proto_CreateAccount(p->pszBaseProto, p->pszInternal, p->ptszAccountName); + if (pa) { + WriteDbAccounts(); + NotifyEventHooks(hAccListChanged, PRAC_ADDED, (LPARAM)pa); + } + return (INT_PTR)pa; +} + static INT_PTR srvProto_GetAccount(WPARAM, LPARAM lParam) { return (INT_PTR)Proto_GetAccount((char*)lParam); @@ -682,6 +696,7 @@ int LoadProtocolsModule(void) CreateServiceFunction("Proto/EnumProtocols", Proto_EnumAccounts); CreateServiceFunction(MS_PROTO_ENUMACCOUNTS, Proto_EnumAccounts); + CreateServiceFunction(MS_PROTO_CREATEACCOUNT, srvProto_CreateAccount); CreateServiceFunction(MS_PROTO_GETACCOUNT, srvProto_GetAccount); CreateServiceFunction(MS_PROTO_ISACCOUNTENABLED, srvProto_IsAccountEnabled); diff --git a/src/modules/protocols/protoopts.cpp b/src/modules/protocols/protoopts.cpp index 724684609a..54ec8ceed4 100644 --- a/src/modules/protocols/protoopts.cpp +++ b/src/modules/protocols/protoopts.cpp @@ -59,16 +59,121 @@ extern HANDLE hAccListChanged; int UnloadPlugin(TCHAR* buf, int bufLen); +PROTOACCOUNT* Proto_CreateAccount(const char *szModuleName, const char *szBaseProto, const TCHAR *tszAccountName) +{ + PROTOACCOUNT *pa = (PROTOACCOUNT*)mir_calloc(sizeof(PROTOACCOUNT)); + if (pa == NULL) + return NULL; + + pa->cbSize = sizeof(PROTOACCOUNT); + pa->bIsEnabled = pa->bIsVisible = true; + pa->iOrder = accounts.getCount(); + pa->szProtoName = mir_strdup(szBaseProto); + + // if the internal name is empty, generate new one + if (lstrlenA(szModuleName) == 0) { + char buf[100]; + int count = 1; + while (true) { + mir_snprintf(buf, SIZEOF(buf), "%s_%d", szBaseProto, count++); + if (ptrA(db_get_sa(NULL, buf, "AM_BaseProto")) == NULL) + break; + } + pa->szModuleName = mir_strdup(buf); + } + else pa->szModuleName = mir_strdup(szModuleName); + + pa->tszAccountName = mir_tstrdup(tszAccountName); + + db_set_s(NULL, pa->szModuleName, "AM_BaseProto", szBaseProto); + accounts.insert(pa); + + if (ActivateAccount(pa)) { + pa->ppro->OnEvent(EV_PROTO_ONLOAD, 0, 0); + if (!db_get_b(NULL, "CList", "MoveProtoMenus", true)) + pa->ppro->OnEvent(EV_PROTO_ONMENU, 0, 0); + } + + return pa; +} + /////////////////////////////////////////////////////////////////////////////////////////////////// // Account edit form // Gets PROTOACCOUNT* as a parameter, or NULL to edit a new one -typedef struct +struct AccFormDlgParam { int action; PROTOACCOUNT *pa; +}; + +static bool FindAccountByName(const char *szModuleName) +{ + if (!lstrlenA(szModuleName)) + return false; + + for (int i = 0; i < accounts.getCount(); i++) + if (_stricmp(szModuleName, accounts[i]->szModuleName) == 0) + return true; + + return false; +} + +static bool OnCreateAccount(HWND hwndDlg) +{ + AccFormDlgParam* param = (AccFormDlgParam*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + PROTOACCOUNT *pa = param->pa; + + TCHAR tszAccName[256]; + GetDlgItemText(hwndDlg, IDC_ACCNAME, tszAccName, SIZEOF(tszAccName)); + rtrimt(tszAccName); + if (tszAccName[0] == 0) { + MessageBox(hwndDlg, TranslateT("Account name must be filled."), TranslateT("Account error"), MB_ICONERROR | MB_OK); + return false; + } + + if (param->action == PRAC_ADDED) { + char buf[200]; + GetDlgItemTextA(hwndDlg, IDC_ACCINTERNALNAME, buf, SIZEOF(buf)); + if (FindAccountByName(rtrim(buf))) { + MessageBox(hwndDlg, TranslateT("Account name has to be unique. Please enter unique name."), TranslateT("Account error"), MB_ICONERROR | MB_OK); + return false; + } + } + + if (param->action == PRAC_UPGRADED) { + BOOL oldProto = pa->bOldProto; + TCHAR szPlugin[MAX_PATH]; + mir_sntprintf(szPlugin, SIZEOF(szPlugin), _T("%s.dll"), StrConvT(pa->szProtoName)); + int 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); + } + param->action = PRAC_ADDED; + } + + if (param->action == PRAC_ADDED) { + char buf[200]; + GetDlgItemTextA(hwndDlg, IDC_PROTOTYPECOMBO, buf, SIZEOF(buf)); + char *szBaseProto = NEWSTR_ALLOCA(buf); + + GetDlgItemTextA(hwndDlg, IDC_ACCINTERNALNAME, buf, SIZEOF(buf)); + rtrim(buf); + + pa = Proto_CreateAccount(buf, szBaseProto, tszAccName); + } + else replaceStrT(pa->tszAccountName, tszAccName); + + WriteDbAccounts(); + NotifyEventHooks(hAccListChanged, param->action, (LPARAM)pa); + + SendMessage(GetParent(hwndDlg), WM_MY_REFRESH, 0, 0); + return true; } - AccFormDlgParam; static INT_PTR CALLBACK AccFormDlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam) { @@ -116,95 +221,8 @@ static INT_PTR CALLBACK AccFormDlgProc(HWND hwndDlg, UINT message, WPARAM wParam 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) { - MessageBox(hwndDlg, TranslateT("Account name has to be unique. Please enter unique name."), TranslateT("Account error"), MB_ICONERROR | MB_OK); - return FALSE; - } - } - } - - switch(param->action) { - case PRAC_UPGRADED: - { - BOOL oldProto = pa->bOldProto; - TCHAR szPlugin[MAX_PATH]; - mir_sntprintf(szPlugin, SIZEOF(szPlugin), _T("%s.dll"), StrConvT(pa->szProtoName)); - int 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(); - 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 (db_get_s(NULL, buf, "AM_BaseProto", &dbv)) - break; - db_free(&dbv); - } - } - pa->szModuleName = mir_strdup(buf); - - if (!pa->tszAccountName[0]) { - mir_free(pa->tszAccountName); - pa->tszAccountName = mir_a2t(buf); - } - - db_set_s(NULL, pa->szModuleName, "AM_BaseProto", pa->szProtoName); - accounts.insert(pa); - - if ( ActivateAccount(pa)) { - pa->ppro->OnEvent(EV_PROTO_ONLOAD, 0, 0); - if (!db_get_b(NULL, "CList", "MoveProtoMenus", TRUE)) - pa->ppro->OnEvent(EV_PROTO_ONMENU, 0, 0); - } - } - - WriteDbAccounts(); - NotifyEventHooks(hAccListChanged, param->action, (LPARAM)pa); - - SendMessage(GetParent(hwndDlg), WM_MY_REFRESH, 0, 0); - } - - EndDialog(hwndDlg, TRUE); + if (OnCreateAccount(hwndDlg)) + EndDialog(hwndDlg, TRUE); break; case IDCANCEL: @@ -463,59 +481,57 @@ INT_PTR CALLBACK AccMgrDlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM 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; - GetObject((HFONT)SendMessage(hwndDlg, WM_GETFONT, 0, 0), sizeof(lf), &lf); - dat->hfntText = CreateFontIndirect(&lf); + TranslateDialogDefault(hwndDlg); + Window_SetIcon_IcoLib(hwndDlg, SKINICON_OTHER_ACCMGR); - GetObject((HFONT)SendMessage(hwndDlg, WM_GETFONT, 0, 0), sizeof(lf), &lf); - lf.lfWeight = FW_BOLD; - dat->hfntTitle = CreateFontIndirect(&lf); + dat = (TAccMgrData *)mir_alloc(sizeof(TAccMgrData)); + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)dat); - HDC hdc = GetDC(hwndDlg); - HFONT hfnt = (HFONT)SelectObject(hdc, dat->hfntTitle); + 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")); - TEXTMETRIC tm; - GetTextMetrics(hdc, &tm); - dat->titleHeight = tm.tmHeight; - SelectObject(hdc, dat->hfntText); + 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; + GetObject((HFONT)SendMessage(hwndDlg, WM_GETFONT, 0, 0), sizeof(lf), &lf); + dat->hfntText = CreateFontIndirect(&lf); - GetTextMetrics(hdc, &tm); - dat->textHeight = tm.tmHeight; - SelectObject(hdc, hfnt); - ReleaseDC(hwndDlg, hdc); + GetObject((HFONT)SendMessage(hwndDlg, WM_GETFONT, 0, 0), sizeof(lf), &lf); + lf.lfWeight = FW_BOLD; + dat->hfntTitle = CreateFontIndirect(&lf); - dat->normalHeight = 4 + max(dat->titleHeight, GetSystemMetrics(SM_CYSMICON)); - dat->selectedHeight = dat->normalHeight + 4 + 2 * dat->textHeight; + HDC hdc = GetDC(hwndDlg); + HFONT hfnt = (HFONT)SelectObject(hdc, dat->hfntTitle); - 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); - } + TEXTMETRIC tm; + GetTextMetrics(hdc, &tm); + dat->titleHeight = tm.tmHeight; + SelectObject(hdc, dat->hfntText); - dat->iSelected = -1; - sttSubclassAccList( GetDlgItem(hwndDlg, IDC_ACCLIST), TRUE); - SendMessage(hwndDlg, WM_MY_REFRESH, 0, 0); + GetTextMetrics(hdc, &tm); + dat->textHeight = tm.tmHeight; + SelectObject(hdc, hfnt); + ReleaseDC(hwndDlg, hdc); - Utils_RestoreWindowPositionNoSize(hwndDlg, NULL, "AccMgr", ""); + 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: @@ -542,8 +558,6 @@ INT_PTR CALLBACK AccMgrDlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM case WM_DRAWITEM: { - int tmp; - TCHAR *text; HBRUSH hbrBack; SIZE sz; @@ -552,7 +566,6 @@ INT_PTR CALLBACK AccMgrDlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM LPDRAWITEMSTRUCT lps = (LPDRAWITEMSTRUCT)lParam; PROTOACCOUNT *acc = (PROTOACCOUNT *)lps->itemData; - if ((lps->CtlID != IDC_ACCLIST) || (lps->itemID == -1) || !acc) break; @@ -571,6 +584,7 @@ INT_PTR CALLBACK AccMgrDlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lps->rcItem.top += 2; lps->rcItem.bottom -= 2; + int tmp; if (acc->bOldProto) tmp = SKINICON_OTHER_ON; else if (acc->bDynDisabled) @@ -593,7 +607,7 @@ INT_PTR CALLBACK AccMgrDlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM int length = SendDlgItemMessage(hwndDlg, IDC_ACCLIST, LB_GETTEXTLEN, lps->itemID, 0); int size = max(length+1, 256); - text = (TCHAR *)_alloca(sizeof(TCHAR) * size); + TCHAR *text = (TCHAR *)_alloca(sizeof(TCHAR) * size); SendDlgItemMessage(hwndDlg, IDC_ACCLIST, LB_GETTEXT, lps->itemID, (LPARAM)text); SelectObject(lps->hDC, dat->hfntTitle); -- cgit v1.2.3