diff options
| -rw-r--r-- | meta2/core_functions.cpp | 20 | ||||
| -rw-r--r-- | meta2/import.cpp | 283 | ||||
| -rw-r--r-- | meta2/meta2.cpp | 11 | ||||
| -rw-r--r-- | meta2/meta2.rc | 50 | ||||
| -rw-r--r-- | meta2/resource.h | 13 | 
5 files changed, 368 insertions, 9 deletions
diff --git a/meta2/core_functions.cpp b/meta2/core_functions.cpp index 748fddc..6715c8e 100644 --- a/meta2/core_functions.cpp +++ b/meta2/core_functions.cpp @@ -126,6 +126,26 @@ void Meta_Assign(HANDLE hSub, HANDLE hMeta) {  	} else // shouldn't happen, as the menu option is hidden when metas are disabled...
  		DBWriteContactSettingByte(hMeta, "CList", "Hidden", 1);
 +	DBVARIANT dbv;
 +	if(DBGetContactSettingUTF8String(hMeta, "CList", "MyHandle", &dbv)) {
 +		if(!DBGetContactSettingUTF8String(hSub, "CList", "MyHandle", &dbv)) {
 +			DBWriteContactSettingUTF8String(hMeta, "CList", "MyHandle", dbv.pszVal);
 +			DBFreeVariant(&dbv);
 +		}
 +	} else
 +		DBFreeVariant(&dbv);
 +
 +	if(DBGetContactSettingUTF8String(hMeta, MODULE, "Nick", &dbv)) {
 +		char *subProto = ContactProto(hSub);
 +		if(subProto) {
 +			if(!DBGetContactSettingUTF8String(hSub, subProto, "Nick", &dbv)) {
 +				DBWriteContactSettingUTF8String(hMeta, MODULE, "Nick", dbv.pszVal);
 +				DBFreeVariant(&dbv);
 +			}
 +		}
 +	} else
 +		DBFreeVariant(&dbv);
 +
  	FireSubcontactsChanged(hMeta);
  }
 diff --git a/meta2/import.cpp b/meta2/import.cpp index abdab20..7d3204e 100644 --- a/meta2/import.cpp +++ b/meta2/import.cpp @@ -2,8 +2,10 @@  #include "import.h"
  #include "core_functions.h"
  #include "proto.h"
 +#include "resource.h"
 +#include <time.h>
 -void ImportOldMetas() {
 +void CreateNewMetas() {
  	HANDLE hContact = (HANDLE)CallService( MS_DB_CONTACT_FINDFIRST, 0, 0);
  	char *proto;
  	HANDLE hMeta;
 @@ -43,4 +45,283 @@ void ImportOldMetas() {  		hContact = ( HANDLE )CallService( MS_DB_CONTACT_FINDNEXT,( WPARAM )hContact, 0 );
  	}	
 +}
 +
 +BOOL CALLBACK DlgProcImport(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
 +	switch ( msg ) {
 +	case WM_INITDIALOG:
 +		TranslateDialogDefault( hwndDlg );
 +		CheckDlgButton(hwndDlg, IDC_RAD_HISTMETA, TRUE);
 +		break;
 +	case WM_COMMAND:
 +		if ( HIWORD( wParam ) == BN_CLICKED ) {
 +			switch(LOWORD(wParam)) {
 +				case IDOK:
 +					if(IsDlgButtonChecked(hwndDlg, IDC_RAD_HISTMETA))
 +						EndDialog(hwndDlg, IDC_RAD_HISTMETA);
 +					else if(IsDlgButtonChecked(hwndDlg, IDC_RAD_HISTSUB))
 +						EndDialog(hwndDlg, IDC_RAD_HISTSUB);
 +					else if(IsDlgButtonChecked(hwndDlg, IDC_RAD_HISTNONE))
 +						EndDialog(hwndDlg, IDC_RAD_HISTNONE);
 +					return TRUE;
 +				case IDCANCEL:
 +					EndDialog(hwndDlg, IDCANCEL);
 +					return TRUE;
 +			}
 +		}
 +		break;
 +	}
 +	return FALSE;
 +}
 +
 +#define WMU_SETPERCENT			(WM_USER + 0x100)
 +#define WMU_SETCONTACT			(WM_USER + 0x101)
 +BOOL CALLBACK DlgProcProgress(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
 +{
 +	switch(msg) {
 +	case WM_INITDIALOG:
 +		TranslateDialogDefault( hwndDlg );
 +		{			
 +			HWND prog = GetDlgItem(hwndDlg, IDC_PROG);
 +			SendMessage(prog, PBM_SETPOS, 0, 0);
 +		}
 +		break;
 +	case WMU_SETPERCENT:
 +		{
 +			int percent = (int)wParam;
 +			HWND prog = GetDlgItem(hwndDlg, IDC_PROG);
 +			SendMessage(prog, PBM_SETPOS, (WPARAM)percent, 0);	
 +			TCHAR buff[1024];
 +			mir_sntprintf(buff, 1024, TranslateT("History Copy - %d%%"), percent);
 +			SetWindowText(hwndDlg, buff);
 +		}
 +		return TRUE;
 +	case WMU_SETCONTACT:
 +		{
 +			HWND ed = GetDlgItem(hwndDlg, IDC_ED_MESSAGE);
 +			TCHAR buff[1024];
 +			mir_sntprintf(buff, 1024, TranslateT("Current contact: %s"), ContactName((HANDLE)wParam));
 +			SetWindowText(ed, buff);
 +		}
 +		return TRUE;
 +	}
 +	return FALSE;
 +}
 +
 +
 +// function to copy history from one contact to another - courtesy JdGordon (thx)
 +// days == 0 implies copy all history
 +void CopyHistory(HANDLE hContactFrom, HANDLE hContactTo, int days) { 
 +	HANDLE hDbEvent; 
 +	DBEVENTINFO dbei; 
 +	DWORD time_now = time(0);
 +	DWORD earliest_time = time_now - days * 24 * 60 * 60;
 +	BYTE *buffer = 0;
 +	HWND progress_dialog, prog;
 +
 +	if (!hContactFrom || !hContactTo) return; 
 +
 +	CallService(MS_DB_SETSAFETYMODE, (WPARAM)FALSE, 0);
 +	for (hDbEvent = (HANDLE)CallService(MS_DB_EVENT_FINDFIRST,(WPARAM)hContactFrom, 0); 
 +		hDbEvent; 
 +		hDbEvent=(HANDLE)CallService(MS_DB_EVENT_FINDNEXT,(WPARAM)hDbEvent,0)) 
 +	{ 
 +		// get the event 
 +		ZeroMemory(&dbei, sizeof(dbei)); 
 +		dbei.cbSize = sizeof(dbei); 
 +
 +		if((dbei.cbBlob = CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)hDbEvent, 0)) == -1)
 +			break;
 +
 +		buffer = (PBYTE)mir_realloc(buffer, dbei.cbBlob);// + id_length);
 +		dbei.pBlob = buffer; 
 +
 +		if (CallService(MS_DB_EVENT_GET,(WPARAM)hDbEvent,(LPARAM)&dbei)) 
 +			break; 
 +
 +		// i.e. optoins.days_history == 0;
 +		if(time_now == earliest_time) earliest_time = dbei.timestamp;
 +
 +		if(dbei.timestamp < earliest_time)
 +			continue;
 +
 +		dbei.flags &= ~DBEF_FIRST;
 +		CallService(MS_DB_EVENT_ADD, (WPARAM)hContactTo, (LPARAM)&dbei); 
 +	}		
 +	if(buffer) mir_free(buffer);
 +	CallService(MS_DB_SETSAFETYMODE, (WPARAM)TRUE, 0);
 +}
 +
 +
 +void ImportMetaHistory() {
 +	HWND progress_dialog = CreateDialog(hInst, MAKEINTRESOURCE(IDD_COPYPROGRESS), 0, DlgProcProgress);
 +	ShowWindow(progress_dialog, SW_SHOW);
 +
 +	HWND prog = GetDlgItem(progress_dialog, IDC_PROG);
 +
 +	HANDLE hMeta;
 +	int num_contacts = metaMap.size(), count = 0;
 +	HANDLE hContact = (HANDLE)CallService( MS_DB_CONTACT_FINDFIRST, 0, 0);
 +	while(hContact != NULL) {
 +		DWORD id = DBGetContactSettingDword(hContact, "MetaContacts", "MetaID", (DWORD)-1);
 +		if(id != (DWORD)-1) {
 +			hMeta = GetMetaHandle(id);
 +			if(hMeta) {
 +				SendMessage(progress_dialog, WMU_SETPERCENT, (WPARAM)(int)(100.0 * count / num_contacts), 0);	
 +				SendMessage(progress_dialog, WMU_SETCONTACT, (WPARAM)hMeta, 0);	
 +				UpdateWindow(progress_dialog);
 +				CopyHistory(hContact, hMeta, 0);
 +				count++;
 +			}
 +		}
 +
 +
 +		hContact = ( HANDLE )CallService( MS_DB_CONTACT_FINDNEXT,( WPARAM )hContact, 0 );
 +	}
 +
 +	DestroyWindow(progress_dialog);
 +}
 +
 +// import a metacontacts subcontact history, sorting all subcontact events according to timestamp
 +void ImportSubHistory() {
 +	HWND progress_dialog = CreateDialog(hInst, MAKEINTRESOURCE(IDD_COPYPROGRESS), 0, DlgProcProgress);
 +	ShowWindow(progress_dialog, SW_SHOW);
 +
 +	HWND prog = GetDlgItem(progress_dialog, IDC_PROG);
 +
 +	CallService(MS_DB_SETSAFETYMODE, (WPARAM)FALSE, 0);
 +
 +	HANDLE *hEvent;
 +	DWORD *times, *sizes;
 +	int index;
 +	BYTE *buffer = 0;
 +	DBEVENTINFO dbei = {0}; 
 +	dbei.cbSize = sizeof(dbei);
 +	bool done;
 +	int subcount, num_contacts = metaMap.size(), count = 0;
 +	for(MetaMap::Iterator i = metaMap.start(); i.has_val(); i.next()) {
 +		SendMessage(progress_dialog, WMU_SETPERCENT, (WPARAM)(int)(100.0 * count / num_contacts), 0);	
 +		SendMessage(progress_dialog, WMU_SETCONTACT, (WPARAM)i.val().first.handle(), 0);	
 +		UpdateWindow(progress_dialog);
 +
 +		hEvent = new HANDLE[i.val().second.size()];
 +		times = new DWORD[i.val().second.size()];
 +		sizes = new DWORD[i.val().second.size()];
 +		index = 0;
 +		subcount = i.val().second.size();
 +		for(SubcontactList::Iterator j = i.val().second.start(); j.has_val(); j.next()) {
 +			hEvent[index] = (HANDLE)CallService(MS_DB_EVENT_FINDFIRST,(WPARAM)j.val().handle(), 0);
 +			dbei.cbBlob = 0;
 +			if(hEvent[index] && !CallService(MS_DB_EVENT_GET,(WPARAM)hEvent[index],(LPARAM)&dbei)) {
 +				times[index] = dbei.timestamp;
 +				sizes[index] = dbei.cbBlob;
 +			} else
 +				hEvent[index] = 0;
 +			index++;
 +		}
 +
 +		int min_index;
 +		do {
 +			min_index = -1;
 +			for(index = 0; index < subcount; index++) {
 +				if(hEvent[index] && (min_index == -1 || times[index] < times[min_index]))
 +					min_index = index;
 +			}
 +
 +			if(min_index != -1) {
 +				// copy earliest event
 +				dbei.cbBlob = sizes[min_index];
 +				dbei.pBlob = (PBYTE)mir_realloc(buffer, dbei.cbBlob);
 +				if(!CallService(MS_DB_EVENT_GET,(WPARAM)hEvent[min_index],(LPARAM)&dbei)) {
 +					dbei.flags &= ~DBEF_FIRST;
 +					CallService(MS_DB_EVENT_ADD, (WPARAM)i.val().first.handle(), (LPARAM)&dbei); 
 +					
 +					// update arrays
 +					hEvent[min_index] = (HANDLE)CallService(MS_DB_EVENT_FINDNEXT,(WPARAM)hEvent[min_index], 0);
 +					if(hEvent[min_index] == 0 || (dbei.cbBlob = CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)hEvent[min_index], 0)) == -1)
 +						hEvent[min_index] = 0;
 +					dbei.cbBlob = 0;
 +					if(hEvent[min_index] && !CallService(MS_DB_EVENT_GET,(WPARAM)hEvent[min_index],(LPARAM)&dbei)) {
 +						times[min_index] = dbei.timestamp;
 +						sizes[min_index] = dbei.cbBlob;
 +					} else
 +						hEvent[min_index] = 0;
 +				} else
 +					hEvent[min_index] = 0;
 +			}	
 +		} while(min_index != -1);
 +
 +		delete[] hEvent;
 +		delete[] times;
 +		delete[] sizes;
 +
 +		count++;
 +	}
 +	if(buffer) mir_free(buffer);
 +	CallService(MS_DB_SETSAFETYMODE, (WPARAM)TRUE, 0);
 +	DestroyWindow(progress_dialog);
 +}
 +
 +void DeleteAllModuleContacts() {
 +	HANDLE hContact = (HANDLE)CallService( MS_DB_CONTACT_FINDFIRST, 0, 0);
 +	char *proto;
 +	HANDLE hMeta;
 +	while(hContact != NULL) {
 +		if(IsMetacontact(hContact)) {
 +			hMeta = hContact;
 +			hContact = ( HANDLE )CallService( MS_DB_CONTACT_FINDNEXT,( WPARAM )hContact, 0 );
 +			CallService(MS_DB_CONTACT_DELETE, (WPARAM)hMeta, 0);
 +		} else
 +			hContact = ( HANDLE )CallService( MS_DB_CONTACT_FINDNEXT,( WPARAM )hContact, 0 );
 +	}
 +}
 +
 +void DeleteOldMetas() {
 +	HANDLE hContact = (HANDLE)CallService( MS_DB_CONTACT_FINDFIRST, 0, 0);
 +	char *proto;
 +	HANDLE hMeta;
 +	while(hContact != NULL) {
 +		if(DBGetContactSettingDword(hContact, "MetaContacts", "MetaID", (DWORD)-1) != (DWORD)-1) {
 +			hMeta = hContact;
 +			hContact = ( HANDLE )CallService( MS_DB_CONTACT_FINDNEXT,( WPARAM )hContact, 0 );
 +			CallService(MS_DB_CONTACT_DELETE, (WPARAM)hMeta, 0);
 +		} else
 +			hContact = ( HANDLE )CallService( MS_DB_CONTACT_FINDNEXT,( WPARAM )hContact, 0 );
 +	}
 +}
 +
 +bool OldMetasExist() {
 +	HANDLE hContact = (HANDLE)CallService( MS_DB_CONTACT_FINDFIRST, 0, 0);
 +	char *proto;
 +	HANDLE hMeta;
 +	while(hContact != NULL) {
 +		if(DBGetContactSettingDword(hContact, "MetaContacts", "MetaID", (DWORD)-1) != (DWORD)-1) {
 +			return true;
 +		} else
 +			hContact = ( HANDLE )CallService( MS_DB_CONTACT_FINDNEXT,( WPARAM )hContact, 0 );
 +	}
 +	return false;
 +}
 +
 +void ImportOldMetas() {
 +	if(OldMetasExist()) {
 +		DeleteAllModuleContacts();
 +		next_meta_id = 0;
 +
 +		int ret;
 +		if((ret = DialogBox(hInst, MAKEINTRESOURCE(IDD_HISTIMPORT), 0, DlgProcImport)) != IDCANCEL) {
 +			CreateNewMetas();
 +			switch(ret) {
 +				case IDC_RAD_HISTMETA:
 +					ImportMetaHistory();
 +					break;
 +				case IDC_RAD_HISTSUB:
 +					ImportSubHistory();
 +					break;
 +			}
 +		}
 +
 +		if(MessageBox(0, TranslateT("Do you wish to remove your old metacontacts from your profile?"), TranslateT("Delete Old MetaContacts"), MB_YESNO) == IDYES)
 +			DeleteOldMetas();
 +	}
  }
\ No newline at end of file diff --git a/meta2/meta2.cpp b/meta2/meta2.cpp index 520183e..d4effe5 100644 --- a/meta2/meta2.cpp +++ b/meta2/meta2.cpp @@ -87,11 +87,6 @@ int ModulesLoaded(WPARAM wParam, LPARAM lParam) {  	InitIcons();
  	InitMenu();
 -	if(DBGetContactSettingByte(0, MODULE, "FirstRun", 1) == 1) {
 -		ImportOldMetas();
 -		DBWriteContactSettingByte(0, MODULE, "FirstRun", 0);
 -	}
 -
  	return 0;
  }
 @@ -117,6 +112,12 @@ extern "C" __declspec (dllexport) int Load(PLUGINLINK *link) {  	InitProto();
  	InitAPI();
 +
 +	if(DBGetContactSettingByte(0, MODULE, "FirstRun", 1) == 1) {
 +		ImportOldMetas();
 +		DBWriteContactSettingByte(0, MODULE, "FirstRun", 0);
 +	}
 +
  	InitSettings(link);
  	// hook modules loaded
 diff --git a/meta2/meta2.rc b/meta2/meta2.rc index 018a2fe..2fac00d 100644 --- a/meta2/meta2.rc +++ b/meta2/meta2.rc @@ -140,6 +140,56 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_AUS  /////////////////////////////////////////////////////////////////////////////
  //
 +// Dialog
 +//
 +
 +IDD_HISTIMPORT DIALOGEX 0, 0, 279, 201
 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
 +CAPTION "Import Contacts"
 +FONT 8, "MS Shell Dlg", 400, 0, 0x1
 +BEGIN
 +    DEFPUSHBUTTON   "OK",IDOK,90,180,50,14
 +    PUSHBUTTON      "Cancel",IDCANCEL,147,180,50,14
 +    LTEXT           "Old-style MetaContacts have been detected in your database. Press 'OK' to import these contacts, or press cancel to ignore them.\n\nImporting history may take a while.",IDC_STATIC,53,23,178,63
 +    CONTROL         "Import history from old MetaContacts into new ones",IDC_RAD_HISTMETA,
 +                    "Button",BS_AUTORADIOBUTTON,52,106,212,10
 +    CONTROL         "Merge subcontact history into new MetaContact history",IDC_RAD_HISTSUB,
 +                    "Button",BS_AUTORADIOBUTTON,52,126,212,10
 +    CONTROL         "Do not import history",IDC_RAD_HISTNONE,"Button",BS_AUTORADIOBUTTON,52,147,212,10
 +END
 +
 +IDD_COPYPROGRESS DIALOGEX 0, 0, 186, 90
 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION
 +CAPTION "History Copy"
 +FONT 8, "MS Shell Dlg", 0, 0, 0x0
 +BEGIN
 +    CONTROL         "Progress1",IDC_PROG,"msctls_progress32",0x0,28,53,130,13
 +    CTEXT           "Please wait while the contact's history is copied.",IDC_STATIC,9,13,167,8
 +    CTEXT           "",IDC_ED_MESSAGE,10,30,167,8
 +END
 +
 +
 +/////////////////////////////////////////////////////////////////////////////
 +//
 +// DESIGNINFO
 +//
 +
 +#ifdef APSTUDIO_INVOKED
 +GUIDELINES DESIGNINFO 
 +BEGIN
 +    IDD_HISTIMPORT, DIALOG
 +    BEGIN
 +        LEFTMARGIN, 7
 +        RIGHTMARGIN, 272
 +        TOPMARGIN, 7
 +        BOTTOMMARGIN, 194
 +    END
 +END
 +#endif    // APSTUDIO_INVOKED
 +
 +
 +/////////////////////////////////////////////////////////////////////////////
 +//
  // Icon
  //
 diff --git a/meta2/resource.h b/meta2/resource.h index eca2737..0c6ab82 100644 --- a/meta2/resource.h +++ b/meta2/resource.h @@ -14,6 +14,8 @@  #define IDD_PRIORITIES                  128
  #define IDD_METASELECT                  129
  #define IDD_METAEDIT                    130
 +#define IDD_HISTIMPORT                  131
 +#define IDD_COPYPROGRESS                132
  #define IDC_ED_PRIORITY                 1001
  #define IDC_SP_PRIORITY                 1002
  #define IDC_CMB_STATUS                  1003
 @@ -27,16 +29,21 @@  #define IDC_BTN_SETDEFAULT              1011
  #define IDC_ED_NAME                     1012
  #define IDC_LST_CONTACTS                1013
 -#define IDC_CHECK1                      1014
 +#define IDC_RAD_HISTMETA                1016
 +#define IDC_HISTSUB                     1017
 +#define IDC_RAD_HISTSUB                 1017
 +#define IDC_RAD_HISTNONE                1018
 +#define IDC_PROG                        1019
 +#define IDC_ED_MESSAGE                  1020
  #define IDC_STATIC                      -1
  // Next default values for new objects
  // 
  #ifdef APSTUDIO_INVOKED
  #ifndef APSTUDIO_READONLY_SYMBOLS
 -#define _APS_NEXT_RESOURCE_VALUE        131
 +#define _APS_NEXT_RESOURCE_VALUE        133
  #define _APS_NEXT_COMMAND_VALUE         40001
 -#define _APS_NEXT_CONTROL_VALUE         1015
 +#define _APS_NEXT_CONTROL_VALUE         1021
  #define _APS_NEXT_SYMED_VALUE           101
  #endif
  #endif
  | 
