Example #1
0
void ShowError(wchar_t *msg) {
	wchar_t buffer[512];
	ErrorDisplay disp = options.err_method;
	// funny logic :) ... try to avoid message boxes
	// if want popups but no popups, try baloons
	if(disp == ED_POP && !options.bHavePopups)
		disp = ED_BAL;

	mir_snwprintf(buffer, L"%s Error", _A2W(MODULENAME));

	wchar_t *message;
	switch (disp) {
	case ED_POP:
		{
			int size = int(mir_wstrlen(msg) + 515);
			message = new wchar_t[size]; // newline and null terminator
			mir_snwprintf(message, size, L"%s\r\n%s", buffer, msg);
			PUShowMessageT(message, SM_WARNING);
			delete[] message;
		}
		break;
	case ED_MB:
		MessageBox(nullptr, msg, buffer, MB_OK | MB_ICONERROR);
		break;
	case ED_BAL:
		Clist_TrayNotifyW(MODULENAME, buffer, msg, NIIF_ERROR, 10000);
		break;
	}
}
Example #2
0
void PackerJob::updateStats()
{
	DWORD dwNewTick = GetTickCount();
	if (m_uiReaded && (time(0) > m_startTS) && (dwNewTick > m_lastUpdateTick + 100)) {
		m_lastUpdateTick = dwNewTick;

		double speed = ((double)m_uiReaded / 1024) / (time(0) - m_startTS);
		mir_snwprintf(m_tab->m_stzSpeed, TranslateT("%0.1f kB/s"), speed);

		double perc = m_uiFileSize ? ((double)m_uiReaded / m_uiFileSize) * 100 : 0;
		mir_snwprintf(m_tab->m_stzComplet, TranslateT("%0.1f%% (%d kB/%d kB)"), perc, (int)m_uiReaded / 1024, (int)m_uiFileSize / 1024);

		wchar_t buff[256];
		long s = (m_uiFileSize - m_uiReaded) / (long)(speed * 1024);
		int d = (s / 60 / 60 / 24);
		int h = (s - d * 60 * 60 * 24) / 60 / 60;
		int m = (s - d * 60 * 60 * 24 - h * 60 * 60) / 60;
		s = s - (d * 24 * 60 * 60) - (h * 60 * 60) - (m * 60);

		if (d > 0) mir_snwprintf(buff, L"%dd %02d:%02d:%02d", d, h, m, s);
		else mir_snwprintf(buff, L"%02d:%02d:%02d", h, m, s);
		mir_snwprintf(m_tab->m_stzRemain, TranslateT("%s (%d kB/%d kB)"), buff, (m_uiFileSize - m_uiReaded) / 1024, m_uiFileSize / 1024);

		refreshTab(false);
	}
}
void ShowPopup(SHOWPOPUP_DATA *sd)
{
	TCString PopupText;
	if (sd->PopupOptPage->GetValue(IDC_POPUPOPTDLG_SHOWPREVCLIENT)) {
		mir_snwprintf(PopupText.GetBuffer(MAX_MSG_LEN), MAX_MSG_LEN, TranslateT("changed client to %s (was %s)"), (const wchar_t*)sd->MirVer, (const wchar_t*)sd->OldMirVer);
		PopupText.ReleaseBuffer();
	}
	else {
		mir_snwprintf(PopupText.GetBuffer(MAX_MSG_LEN), MAX_MSG_LEN, TranslateT("changed client to %s"), (const wchar_t*)sd->MirVer);
		PopupText.ReleaseBuffer();
	}

	PLUGIN_DATA *pdata = (PLUGIN_DATA*)calloc(1, sizeof(PLUGIN_DATA));
	POPUPDATAT ppd = { 0 };
	ppd.lchContact = sd->hContact;
	char *szProto = GetContactProto(sd->hContact);
	pdata->hIcon = ppd.lchIcon = Finger_GetClientIcon(sd->MirVer, false);
	_ASSERT(ppd.lchIcon);
	if (!ppd.lchIcon || (INT_PTR)ppd.lchIcon == CALLSERVICE_NOTFOUND) {
		// if we didn't succeed retrieving client icon, show the usual status icon instead
		ppd.lchIcon = Skin_LoadProtoIcon(szProto, db_get_w(sd->hContact, szProto, "Status", ID_STATUS_OFFLINE));
		pdata->hIcon = nullptr;
	}
	wcsncpy(ppd.lptzContactName, Clist_GetContactDisplayName(sd->hContact), _countof(ppd.lptzContactName) - 1);
	wcsncpy(ppd.lptzText, PopupText, _countof(ppd.lptzText) - 1);
	ppd.colorBack = (sd->PopupOptPage->GetValue(IDC_POPUPOPTDLG_DEFBGCOLOUR) ? 0 : sd->PopupOptPage->GetValue(IDC_POPUPOPTDLG_BGCOLOUR));
	ppd.colorText = (sd->PopupOptPage->GetValue(IDC_POPUPOPTDLG_DEFTEXTCOLOUR) ? 0 : sd->PopupOptPage->GetValue(IDC_POPUPOPTDLG_TEXTCOLOUR));
	ppd.PluginWindowProc = PopupWndProc;
	pdata->PopupLClickAction = sd->PopupOptPage->GetValue(IDC_POPUPOPTDLG_LCLICK_ACTION);
	pdata->PopupRClickAction = sd->PopupOptPage->GetValue(IDC_POPUPOPTDLG_RCLICK_ACTION);
	ppd.iSeconds = sd->PopupOptPage->GetValue(IDC_POPUPOPTDLG_POPUPDELAY);
	ppd.PluginData = pdata;
	PUAddPopupT(&ppd);
}
Example #4
0
void CMraProto::MraPopupShowFromContactW(HANDLE hContact, DWORD dwType, DWORD dwFlags, LPCWSTR lpszMessage)
{
	WCHAR szTitle[MAX_CONTACTNAME];
	CMStringW szNick, szEmail;
	mraGetStringW(hContact, "Nick", szNick);
	mraGetStringW(hContact, "e-mail", szEmail);
	if (hContact)
		mir_snwprintf(szTitle, SIZEOF(szTitle), L"%s <%s>", szNick, szEmail);
	else
		mir_snwprintf(szTitle, SIZEOF(szTitle), L"%s:  %s <%s>", m_tszUserName, szNick, szEmail);

	MraPopupShowW(hContact, dwType, dwFlags, szTitle, lpszMessage);
}
Example #5
0
static int HookDBEventAdded(WPARAM hContact, LPARAM hDbEvent)
{
	//process the event
	DBEVENTINFO dbe = {};
	db_event_get(hDbEvent, &dbe);
	//check if we should process the event
	if (dbe.flags & (DBEF_SENT | DBEF_READ) || dbe.eventType != EVENTTYPE_CONTACTS) return 0;
	//get event contents
	dbe.cbBlob = db_event_getBlobSize(hDbEvent);
	if (dbe.cbBlob != -1)
		dbe.pBlob = (PBYTE)_alloca(dbe.cbBlob);
	db_event_get(hDbEvent, &dbe);
	//play received sound
	Skin_PlaySound("RecvContacts");
	{
		//add event to the contact list
		wchar_t caToolTip[128];
		mir_snwprintf(caToolTip, L"%s %s", TranslateT("Contacts received from"), Clist_GetContactDisplayName(hContact));

		CLISTEVENT cle = {};
		cle.hContact = hContact;
		cle.hDbEvent = hDbEvent;
		cle.hIcon = LoadIcon(g_plugin.getInst(), MAKEINTRESOURCE(IDI_CONTACTS));
		cle.pszService = MS_CONTACTS_RECEIVE;
		cle.szTooltip.w = caToolTip;
		cle.flags |= CLEF_UNICODE;
		g_clistApi.pfnAddEvent(&cle);
	}
	return 0; //continue processing by other hooks
}
Example #6
0
void CSAMWindow::checkFieldLimit(WORD action, WORD item)
{
	BOOL type = (item == IDC_MESSAGE) ? TRUE : FALSE;
	unsigned int limit = type ? EXTRASTATUS_MESSAGE_LIMIT : EXTRASTATUS_TITLE_LIMIT;

	if (action == EN_CHANGE)
	{
		wchar_t* ptszInputText = (wchar_t*)mir_alloc((limit + 8) * sizeof(wchar_t));

		GetDlgItemText(m_handle, item, ptszInputText, limit + 8);

		if (mir_wstrlen(ptszInputText) > limit)
		{
			wchar_t tszPopupTip[MAX_PATH];
			EDITBALLOONTIP ebt = { 0 };
			ebt.cbStruct = sizeof(ebt);
			ebt.pszTitle = TranslateT("Warning");
			mir_snwprintf(tszPopupTip, TranslateT("This field doesn't accept string longer than %d characters. The string will be truncated."), limit);
			ebt.pszText = tszPopupTip;
			ebt.ttiIcon = TTI_WARNING;
			SendDlgItemMessage(m_handle, item, EM_SHOWBALLOONTIP, 0, (LPARAM)&ebt);

			wchar_t* ptszOutputText = (wchar_t*)mir_alloc((limit + 1) * sizeof(wchar_t));
			GetDlgItemText(m_handle, item, ptszOutputText, limit + 1);
			SetDlgItemText(m_handle, item, ptszOutputText);
			mir_free(ptszOutputText);
		}
		mir_free(ptszInputText);
	}
}
Example #7
0
void PackerJob::getZipFilePath()
{
	wchar_t buff[256], stzFileName[256] = { 0 };
	wchar_t *pch;

	if (m_files.size() == 1) {
		wcsncpy_s(stzFileName, Utils::getFileNameFromPath(m_files[0]), _TRUNCATE);
		pch = wcsrchr(stzFileName, '.');
		if (pch) *pch = 0;
	}
	else {
		wcsncpy_s(buff, m_files[0], _TRUNCATE);
		pch = wcsrchr(buff, '\\');
		if (pch) {
			*pch = 0;
			pch = wcsrchr(buff, '\\');
			if (pch)
				wcsncpy_s(stzFileName, pch + 1, _TRUNCATE);
		}
	}

	if (stzFileName[0] == '\0')
		wcsncpy_s(stzFileName, L"archive", _TRUNCATE);

	GetTempPath(_countof(buff), buff);

	mir_snwprintf(m_tszFilePath, L"%s%s.zip", buff, stzFileName);
	wcsncpy_s(m_tszFileName, Utils::getFileNameFromPath(m_tszFilePath), _TRUNCATE);

	if (opt.bSetZipName)
		Utils::setFileNameDlg(m_tszFileName);
}
Example #8
0
void Cache_GetFirstLineText(ClcData *dat, ClcContact *contact)
{
	if (GetCurrentThreadId() != g_dwMainThreadID)
		return;

	ClcCacheEntry *pdnce = contact->pce;
	wchar_t *name = Clist_GetContactDisplayName(contact->hContact);
	if (dat->first_line_append_nick && !dat->bForceInDialog) {
		DBVARIANT dbv = { 0 };
		if (!db_get_ws(pdnce->hContact, pdnce->szProto, "Nick", &dbv)) {
			wchar_t nick[_countof(contact->szText)];
			mir_wstrncpy(nick, dbv.ptszVal, _countof(contact->szText));
			db_free(&dbv);

			// They are the same -> use the name to keep the case
			if (mir_wstrcmpi(name, nick) == 0)
				mir_wstrncpy(contact->szText, name, _countof(contact->szText));
			else // Append then
				mir_snwprintf(contact->szText, L"%s - %s", name, nick);
		}
		else mir_wstrncpy(contact->szText, name, _countof(contact->szText));
	}
	else mir_wstrncpy(contact->szText, name, _countof(contact->szText));

	if (!dat->bForceInDialog)
		contact->ssText.ReplaceSmileys(dat, pdnce, contact->szText, dat->first_line_draw_smileys);
}
Example #9
0
void VerifyFingerprintMessage(ConnContext *context, bool verify) {
	MCONTACT hContact = (UINT_PTR)context->app_data;

	wchar_t msg[1024];
	mir_snwprintf(msg, (verify) ? TranslateW(LANG_FINGERPRINT_VERIFIED) : TranslateW(LANG_FINGERPRINT_NOT_VERIFIED), contact_get_nameT(hContact));
	ShowMessage(hContact, msg);
	SetEncryptionStatus(hContact, otr_context_get_trust(context));
}
Example #10
0
void ShowPopup(const wchar_t* line1, const wchar_t* line2, int timeout, const MCONTACT hContact) {
	if(Miranda_IsTerminated()) return;

	if ( !options.bHavePopups) {	
		wchar_t title[256];
		mir_snwprintf(title, L"%s Message", _A2W(MODULENAME));

		if(line1 && line2) {
			int size = int(mir_wstrlen(line1) + mir_wstrlen(line2) + 3);
			wchar_t *message = new wchar_t[size]; // newline and null terminator
			mir_snwprintf(message, size, L"%s\r\n%s", line1, line2);
			MessageBox( nullptr, message, title, MB_OK | MB_ICONINFORMATION );
			delete[] message;
		} else if(line1) {
			MessageBox( nullptr, line1, title, MB_OK | MB_ICONINFORMATION );
		} else if(line2) {
			MessageBox( nullptr, line2, title, MB_OK | MB_ICONINFORMATION );
		}
		return;
	}

	POPUPDATAT ppd = {0};
	//memset((void *)&ppd, 0, sizeof(POPUPDATAT));

	ppd.lchContact = hContact;
	ppd.lchIcon = nullptr;

	if(line1 && line2) {
		wcsncpy( ppd.lptzContactName, line1, MAX_CONTACTNAME-1 );
		wcsncpy( ppd.lptzText, line2, MAX_SECONDLINE-1 );
	} else if(line1)
		wcsncpy( ppd.lptzText, line1, MAX_SECONDLINE-1 );
	else if(line2)
		wcsncpy( ppd.lptzText, line2, MAX_SECONDLINE-1 );

	ppd.iSeconds = timeout;

	ppd.PluginWindowProc = nullptr;
	ppd.PluginData = nullptr;

	PUAddPopupT(&ppd);

}
Example #11
0
void ShowMessageInline(const MCONTACT hContact, const wchar_t *msg) {
	wchar_t buff[1024];
	mir_snwprintf(buff, L"%s%s", _A2W(LANG_INLINE_PREFIX), msg);
	T2Utf utf(buff);

	PROTORECVEVENT pre = {0};
	pre.timestamp = time(0);
	pre.szMessage = utf;
	pre.flags = PREF_BYPASS_OTR;
	ProtoChainRecvMsg(hContact, &pre);	
}
Example #12
0
/**
 * Checks - whether user has been gone for specified number of days
 */
bool isContactGoneFor(MCONTACT hContact, int days)
{
	time_t lastSeen = getLastSeen(hContact);
	time_t lastInputMsg = getLastInputMsg(hContact);
	time_t currentTime = time(0);

	int daysSinceOnline = -1;
	if (lastSeen != -1) daysSinceOnline = (int)((currentTime - lastSeen) / (60 * 60 * 24));

	int daysSinceMessage = -1;
	if (lastInputMsg != -1) daysSinceMessage = (int)((currentTime - lastInputMsg) / (60 * 60 * 24));

	if (options.hideInactive)
		if (daysSinceMessage >= options.iSilencePeriod)
			if (!db_get_b(hContact, "CList", "Hidden", 0) && !db_get_b(hContact, MODULENAME, "NeverHide", 0)) {
				POPUPDATAT_V2 ppd = { 0 };
				ppd.cbSize = sizeof(ppd);
				ppd.lchContact = hContact;
				ppd.lchIcon = IcoLib_GetIcon("enabled_icon");

				mir_snwprintf(ppd.lptzContactName, TranslateT("Hiding %s (%S)"), Clist_GetContactDisplayName(hContact), GetContactProto(hContact));
				mir_snwprintf(ppd.lptzText, TranslateT("%d days since last message"), daysSinceMessage);

				if (!options.iUsePopupColors) {
					ppd.colorBack = options.iPopupColorBack;
					ppd.colorText = options.iPopupColorFore;
				}
				ppd.PluginWindowProc = HidePopupDlgProc;
				ppd.iSeconds = -1;

				hideactions[0].flags = hideactions[1].flags = PAF_ENABLED;
				ppd.lpActions = hideactions;
				ppd.actionCount = 2;

				CallService(MS_POPUP_ADDPOPUPT, (WPARAM)&ppd, APF_NEWDATA);

				Skin_PlaySound("buddyExpectatorHide");
			}

	return (daysSinceOnline >= days && (daysSinceMessage == -1 || daysSinceMessage >= days));
}
Example #13
0
static INT_PTR CALLBACK AddModDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg) {
	case WM_INITDIALOG:
		SetWindowLongPtr(hwnd, GWLP_USERDATA, lParam);
		TranslateDialogDefault(hwnd);

		wchar_t msg[MSG_SIZE], name[NAME_SIZE];
		GetContactName((MCONTACT)lParam, nullptr, name, _countof(name));

		mir_snwprintf(msg, TranslateT("Add module to \"%s\""), name);
		SetWindowText(hwnd, msg);
		break;

	case WM_COMMAND:
		switch (LOWORD(wParam)) {
		case IDOK:
			if (GetWindowTextLength(GetDlgItem(hwnd, IDC_MODNAME))) {
				char modulename[FLD_SIZE];
				GetDlgItemTextA(hwnd, IDC_MODNAME, modulename, _countof(modulename));
				if (IsDlgButtonChecked(hwnd, CHK_ADD2ALL)) {
					// null contact
					db_set_b(NULL, modulename, "(Default)", 0);
					for (auto &hContact : Contacts())
						db_set_b(hContact, modulename, "(Default)", 0);
				}
				else db_set_b((MCONTACT)GetWindowLongPtr(hwnd, GWLP_USERDATA), modulename, "(Default)", 0);

				refreshTree(1);
			}
			__fallthrough;

		case IDCANCEL:
			DestroyWindow(hwnd);
			break;
		}
	}
	return 0;
}
Example #14
0
void ReturnNotify(MCONTACT hContact, wchar_t *message)
{
	if (db_get_b(hContact, "CList", "NotOnList", 0) == 1 || db_get_b(hContact, "CList", "Hidden", 0) == 1)
		return;

	Skin_PlaySound("buddyExpectatorReturn");

	if (options.iShowPopup > 0) {
		// Display Popup
		POPUPDATAT ppd = { 0 };
		ppd.lchContact = hContact;
		ppd.lchIcon = hIcon;
		wcsncpy(ppd.lptzContactName, Clist_GetContactDisplayName(hContact), MAX_CONTACTNAME);
		wcsncpy(ppd.lptzText, message, MAX_SECONDLINE);
		if (!options.iUsePopupColors) {
			ppd.colorBack = options.iPopupColorBack;
			ppd.colorText = options.iPopupColorFore;
		}
		ppd.PluginWindowProc = PopupDlgProc;
		ppd.PluginData = nullptr;
		ppd.iSeconds = options.iPopupDelay;
		PUAddPopupT(&ppd);
	}

	if (options.iShowEvent > 0) {
		CLISTEVENT cle = {};
		cle.hContact = hContact;
		cle.hIcon = hIcon;
		cle.pszService = "BuddyExpectator/actionReturned";
		cle.flags = CLEF_UNICODE;

		wchar_t* nick = Clist_GetContactDisplayName(hContact);
		wchar_t tmpMsg[512];
		mir_snwprintf(tmpMsg, L"%s %s", nick, message);
		cle.szTooltip.w = tmpMsg;
		g_clistApi.pfnAddEvent(&cle);
	}
}
Example #15
0
void GetStatusText(MCONTACT hContact, WORD newStatus, WORD oldStatus, wchar_t *stzStatusText)
{
	if (opt.UseAlternativeText) {
		switch (GetGender(hContact)) {
		case GENDER_MALE:
			wcsncpy(stzStatusText, StatusList[Index(newStatus)].lpzMStatusText, MAX_STATUSTEXT);
			break;
		case GENDER_FEMALE:
			wcsncpy(stzStatusText, StatusList[Index(newStatus)].lpzFStatusText, MAX_STATUSTEXT);
			break;
		case GENDER_UNSPECIFIED:
			wcsncpy(stzStatusText, StatusList[Index(newStatus)].lpzUStatusText, MAX_STATUSTEXT);
			break;
		}
	}
	else
		wcsncpy(stzStatusText, StatusList[Index(newStatus)].lpzStandardText, MAX_STATUSTEXT);

	if (opt.ShowPreviousStatus) {
		wchar_t buff[MAX_STATUSTEXT];
		mir_snwprintf(buff, TranslateW(STRING_SHOWPREVIOUSSTATUS), StatusList[Index(oldStatus)].lpzStandardText);
		mir_wstrcat(mir_wstrcat(stzStatusText, L" "), buff);
	}
}
Example #16
0
bool TwitterProto::NegotiateConnection()
{
	debugLogA( _T("***** Negotiating connection with Twitter"));
	disconnectionCount = 0;

	// saving the current status to a temp var
	int old_status = m_iStatus;
	DBVARIANT dbv;

	wstring oauthToken;
	wstring oauthTokenSecret;	
	wstring oauthAccessToken;
	wstring oauthAccessTokenSecret;
	string screenName;

	INT_PTR dbTOK = db_get_ws(0,m_szModuleName,TWITTER_KEY_OAUTH_TOK,&dbv);
	if (!dbTOK) {
		oauthToken = dbv.pwszVal;
		db_free(&dbv);
		//debugLogW("**NegotiateConnection - we have an oauthToken already in the db - %s", oauthToken);
	}
 
	INT_PTR dbTOKSec = db_get_ws(0,m_szModuleName,TWITTER_KEY_OAUTH_TOK_SECRET,&dbv);
	if (!dbTOKSec) {
		oauthTokenSecret = dbv.pwszVal;
		db_free(&dbv);
		//debugLogW("**NegotiateConnection - we have an oauthTokenSecret already in the db - %s", oauthTokenSecret);
	}

	INT_PTR dbName = db_get_s(0,m_szModuleName,TWITTER_KEY_NICK,&dbv);
	if (!dbName) {
		screenName = dbv.pszVal;
		db_free(&dbv);
		//debugLogW("**NegotiateConnection - we have a username already in the db - %s", screenName);
	}
	else {
		dbName = db_get_s(0,m_szModuleName,TWITTER_KEY_UN,&dbv);
		if (!dbName) {
			screenName = dbv.pszVal;
			db_set_s(0,m_szModuleName,TWITTER_KEY_NICK,dbv.pszVal);
			db_free(&dbv);
			//debugLogW("**NegotiateConnection - we have a username already in the db - %s", screenName);
		}
	}

 	// twitter changed the base URL in v1.1 of the API, I don't think users will need to modify it, so
	// i'll be forcing it to the new API URL here. After a while I can get rid of this as users will
	// have either had this run at least once, or have reset their miranda profile. 14/10/2012
	if(db_get_b(0,m_szModuleName,"UpgradeBaseURL",1)) {
		db_set_s(0,m_szModuleName,TWITTER_KEY_BASEURL,"https://api.twitter.com/");
		db_set_b(0,m_szModuleName,"UpgradeBaseURL",0);
	}

	if((oauthToken.size() <= 1) || (oauthTokenSecret.size() <= 1)) {
		// first, reset all the keys so we can start fresh
		resetOAuthKeys();
		debugLogA( _T("**NegotiateConnection - Reset OAuth Keys"));

		//twit_.set_credentials(ConsumerKey, ConsumerSecret, oauthAccessToken, oauthAccessTokenSecret, L"", false);
		// i think i was doin the wrong thing here.. i was setting the credentials as oauthAccessToken instead of oauthToken
		// have to test..
		debugLogA( _T("**NegotiateConnection - Setting Consumer Keys..."));
		/*debugLogW("**NegotiateConnection - sending set_cred: consumerKey is %s", ConsumerKey);
		debugLogW("**NegotiateConnection - sending set_cred: consumerSecret is %s", ConsumerSecret);
		debugLogW("**NegotiateConnection - sending set_cred: oauthToken is %s", oauthToken);
		debugLogW("**NegotiateConnection - sending set_cred: oauthTokenSecret is %s", oauthTokenSecret);
		debugLogA("**NegotiateConnection - sending set_cred: no pin");*/
		twit_.set_credentials("", ConsumerKey, ConsumerSecret, oauthToken, oauthTokenSecret, L"", false);
		debugLogA( _T("**NegotiateConnection - Requesting oauthTokens"));
		http::response resp = twit_.request_token();

		//wstring rdata_WSTR(resp.data.length(),L' ');
		//std::copy(resp.data.begin(), resp.data.end(), rdata_WSTR.begin());
		wstring rdata_WSTR = UTF8ToWide(resp.data);

		//debugLogW("**NegotiateConnection - REQUEST TOKEN IS %s", rdata_WSTR);
		OAuthParameters response = twit_.ParseQueryString(rdata_WSTR);
		oauthToken = response[L"oauth_token"];
		oauthTokenSecret = response[L"oauth_token_secret"];
		//debugLogW("**NegotiateConnection - oauthToken is %s", oauthToken);
		//debugLogW("**NegotiateConnection - oauthTokenSecret is %s", oauthTokenSecret);

		if (oauthToken.length() < 1) {
			ShowPopup("OAuth Tokens not received, check your internet connection?", 1);
			debugLogA( _T("**NegotiateConnection - OAuth tokens not received, stopping before we open the web browser.."));
			return false;
		}

		//write those bitches to the db foe latta
		db_set_ws(0,m_szModuleName,TWITTER_KEY_OAUTH_TOK,oauthToken.c_str());
		db_set_ws(0,m_szModuleName,TWITTER_KEY_OAUTH_TOK_SECRET,oauthTokenSecret.c_str());
		
		// this looks like bad code.. can someone clean this up please?  or confirm that it's ok
		wchar_t buf[1024] = {};
		mir_snwprintf(buf, SIZEOF(buf), AuthorizeUrl.c_str(), oauthToken.c_str());

		debugLogW( _T("**NegotiateConnection - Launching %s"), buf);
		ShellExecute(NULL, L"open", buf, NULL, NULL, SW_SHOWNORMAL);
		
		ShowPinDialog();
	}

	if (!db_get_ts(NULL,m_szModuleName,TWITTER_KEY_GROUP,&dbv)) {
		CallService(MS_CLIST_GROUPCREATE, 0, (LPARAM)dbv.ptszVal );
		db_free(&dbv);	
	}

	bool realAccessTok = false;
	bool realAccessTokSecret = false;

	// remember, dbTOK is 0 (false) if the db setting has returned something
	dbTOK = db_get_ws(0,m_szModuleName,TWITTER_KEY_OAUTH_ACCESS_TOK,&dbv);
	if (!dbTOK) { 
		oauthAccessToken = dbv.pwszVal;
		db_free(&dbv);
		// this bit is saying "if we have found the db key, but it contains no data, then set dbTOK to 1"
		if (oauthAccessToken.size() > 1) { 
			realAccessTok = true; 
			//debugLogW("**NegotiateConnection - we have an oauthAccessToken already in the db - %s", oauthAccessToken); 
		}
		else { debugLogA( _T("**NegotiateConnection - oauthAccesToken too small? this is.. weird.")); }
	}

	dbTOKSec = db_get_ws(0,m_szModuleName,TWITTER_KEY_OAUTH_ACCESS_TOK_SECRET,&dbv);
	if (!dbTOKSec) { 
		oauthAccessTokenSecret = dbv.pwszVal;
		db_free(&dbv);
		if (oauthAccessTokenSecret.size() > 1) { 
			realAccessTokSecret = true; 
			//debugLogW("**NegotiateConnection - we have an oauthAccessTokenSecret already in the db - %s", oauthAccessTokenSecret); 
		}
		else { debugLogA( _T("**NegotiateConnection - oauthAccessTokenSecret too small? weird")); }
	}

	if (!realAccessTok || !realAccessTokSecret) {  // if we don't have one of these beasties then lets go get 'em!
		wstring pin;
		debugLogA( _T("**NegotiateConnection - either the accessToken or accessTokenSecret was not there.."));
		if (!db_get_ws(0,m_szModuleName,TWITTER_KEY_OAUTH_PIN,&dbv)) {
			pin = dbv.pwszVal;
			//debugLogW("**NegotiateConnection - we have an pin already in the db - %s", pin);
			db_free(&dbv);
		}
		else {
			ShowPopup(TranslateT("OAuth variables are out of sequence, they have been reset. Please reconnect and reauthorize Miranda to Twitter.com (do the PIN stuff again)"));
			debugLogA( _T("**NegotiateConnection - We don't have a PIN?  this doesn't make sense.  Resetting OAuth keys and setting offline."));
			resetOAuthKeys();

			ProtoBroadcastAck(0,ACKTYPE_STATUS,ACKRESULT_FAILED,(HANDLE)old_status,m_iStatus);

			// Set to offline
			old_status = m_iStatus;
			m_iDesiredStatus = m_iStatus = ID_STATUS_OFFLINE;
			ProtoBroadcastAck(0,ACKTYPE_STATUS,ACKRESULT_SUCCESS,(HANDLE)old_status,m_iStatus);

			return false;
		}

		debugLogA( _T("**NegotiateConnection - Setting Consumer Keys and PIN..."));
		/*debugLogW("**NegotiateConnection - sending set_cred: consumerKey is %s", ConsumerKey);
		debugLogW("**NegotiateConnection - sending set_cred: consumerSecret is %s", ConsumerSecret);
		debugLogW("**NegotiateConnection - sending set_cred: oauthToken is %s", oauthToken);
		debugLogW("**NegotiateConnection - sending set_cred: oauthTokenSecret is %s", oauthTokenSecret);
		debugLogW("**NegotiateConnection - sending set_cred: pin is %s", pin);*/

		twit_.set_credentials("", ConsumerKey, ConsumerSecret, oauthToken, oauthTokenSecret, pin, false);

		debugLogA( _T("**NegotiateConnection - requesting access tokens..."));
		http::response accessResp = twit_.request_access_tokens();
		if (accessResp.code != 200) {
			debugLogA( _T("**NegotiateConnection - Failed to get Access Tokens, HTTP response code is: %d"), accessResp.code);
			ShowPopup(TranslateT("Failed to get Twitter Access Tokens, please go offline and try again. If this keeps happening, check your internet connection."));

			resetOAuthKeys();

			ProtoBroadcastAck(0,ACKTYPE_STATUS,ACKRESULT_FAILED,(HANDLE)old_status,m_iStatus);

			// Set to offline
			old_status = m_iStatus;
			m_iDesiredStatus = m_iStatus = ID_STATUS_OFFLINE;
			ProtoBroadcastAck(0,ACKTYPE_STATUS,ACKRESULT_SUCCESS,(HANDLE)old_status,m_iStatus);

			return false;
		}
		else {
			debugLogA( _T("**NegotiateConnection - Successfully retrieved Access Tokens"));

			wstring rdata_WSTR2 = UTF8ToWide(accessResp.data);
			//debugLogW("**NegotiateConnection - accessToken STring is %s", rdata_WSTR2);
		
			OAuthParameters accessTokenParameters = twit_.ParseQueryString(rdata_WSTR2);

			oauthAccessToken = accessTokenParameters[L"oauth_token"];
			//debugLogW("**NegotiateConnection - oauthAccessToken is %s", oauthAccessToken);

			oauthAccessTokenSecret = accessTokenParameters[L"oauth_token_secret"];
			//debugLogW("**NegotiateConnection - oauthAccessTokenSecret is %s", oauthAccessTokenSecret);

			screenName = WideToUTF8(accessTokenParameters[L"screen_name"]);
			debugLogA( _T("**NegotiateConnection - screen name is %s"), screenName.c_str());
	
			//save em
			db_set_ws(0,m_szModuleName,TWITTER_KEY_OAUTH_ACCESS_TOK,oauthAccessToken.c_str());
			db_set_ws(0,m_szModuleName,TWITTER_KEY_OAUTH_ACCESS_TOK_SECRET,oauthAccessTokenSecret.c_str());
			db_set_s(0,m_szModuleName,TWITTER_KEY_NICK,screenName.c_str());
			db_set_s(0,m_szModuleName,TWITTER_KEY_UN,screenName.c_str());
		}
	}

/*	if( !db_get_s(0,m_szModuleName,TWITTER_KEY_PASS,&dbv)) {
		CallService(MS_DB_CRYPT_DECODESTRING,strlen(dbv.pszVal)+1,
			reinterpret_cast<LPARAM>(dbv.pszVal));
		pass = dbv.pszVal;
		db_free(&dbv);
	}
	else {
		ShowPopup(TranslateT("Please enter a password."));
		return false;
	}*/

	if( !db_get_s(0,m_szModuleName,TWITTER_KEY_BASEURL,&dbv))
	{
		ScopedLock s(twitter_lock_);
		twit_.set_base_url(dbv.pszVal);
		db_free(&dbv);
	}

	debugLogA( _T("**NegotiateConnection - Setting Consumer Keys and verifying creds..."));
	/*debugLogW("**NegotiateConnection - sending set_cred: consumerKey is %s", ConsumerKey);
	debugLogW("**NegotiateConnection - sending set_cred: consumerSecret is %s", ConsumerSecret);
	debugLogW("**NegotiateConnection - sending set_cred: oauthAccessToken is %s", oauthAccessToken);
	debugLogW("**NegotiateConnection - sending set_cred: oauthAccessTokenSecret is %s", oauthAccessTokenSecret);
	debugLogA("**NegotiateConnection - sending set_cred: no pin");*/

	if (screenName.empty()) {
		ShowPopup(TranslateT("You're missing the Nick key in the database. This isn't really a big deal, but you'll notice some minor quirks (self contact in list, no group chat outgoing message highlighting, etc). To fix it either add it manually or reset your Twitter account in the Miranda account options"));
		debugLogA( _T("**NegotiateConnection - Missing the Nick key in the database.  Everything will still work, but it's nice to have"));
	}

	bool success;
	{		
		ScopedLock s(twitter_lock_);

		success = twit_.set_credentials(screenName, ConsumerKey, ConsumerSecret, oauthAccessToken, oauthAccessTokenSecret, L"", true);
	}

	if(!success) {
		//ShowPopup(TranslateT("Something went wrong with authorisation, OAuth keys have been reset.  Please try to reconnect.  If problems persist, please se your doctor"));
		debugLogA( _T("**NegotiateConnection - Verifying credentials failed!  No internet maybe?"));

		//resetOAuthKeys();
		ProtoBroadcastAck(0,ACKTYPE_STATUS,ACKRESULT_FAILED,(HANDLE)old_status,m_iStatus);

		// Set to offline
		old_status = m_iStatus;
		m_iDesiredStatus = m_iStatus = ID_STATUS_OFFLINE;
		ProtoBroadcastAck(0,ACKTYPE_STATUS,ACKRESULT_SUCCESS,(HANDLE)old_status,m_iStatus);

		return false;
	}
	else {
		m_iStatus = m_iDesiredStatus;

		ProtoBroadcastAck(0,ACKTYPE_STATUS,ACKRESULT_SUCCESS,(HANDLE)old_status,m_iStatus);
		return true;
	}
}
Example #17
0
INT_PTR CALLBACK copyModDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	ModuleAndContact *mac = (ModuleAndContact *)GetWindowLongPtr(hwnd,GWLP_USERDATA);
	if (msg == WM_INITDIALOG)
	{
		int index, loaded;
		char szProto[256];
		for (MCONTACT hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) {
			if (GetValue(hContact,"Protocol","p",szProto,SIZEOF(szProto)))
				loaded = IsProtocolLoaded(szProto);
			else
				loaded = 0;

			// filter
			if ((loaded && Mode == MODE_UNLOADED) || (!loaded && Mode == MODE_LOADED))
				continue;

			// contacts name
			DBVARIANT dbv ={0};
			WCHAR nick[256];
			WCHAR protoW[256]; // unicode proto

			if (szProto[0])
				a2u(szProto, protoW, SIZEOF(protoW));
			else
				protoW[0] = 0;

			if (!szProto[0] || !loaded) {
				if (protoW) {
					if (Order)
						mir_snwprintf(nick, SIZEOF(nick), L"(%s) %s %s", protoW, GetContactName(hContact, szProto, 1), L"(UNLOADED)");
					else
						mir_snwprintf(nick, SIZEOF(nick), L"%s (%s) %s", GetContactName(hContact, szProto, 1), protoW, L"(UNLOADED)");
				}
				else wcscpy(nick, nick_unknownW);
			}
			else {
				if (Order)
					mir_snwprintf(nick, SIZEOF(nick), L"(%s) %s", protoW, GetContactName(hContact, szProto, 1));
				else
					mir_snwprintf(nick, SIZEOF(nick), L"%s (%s)", GetContactName(hContact, szProto, 1), protoW);
			}

			index = SendMessageW(GetDlgItem(hwnd, IDC_CONTACTS), CB_ADDSTRING, 0, (LPARAM)nick);
			SendMessageW(GetDlgItem(hwnd, IDC_CONTACTS), CB_SETITEMDATA, index, hContact);
		}

		index = (int)SendMessage(GetDlgItem(hwnd, IDC_CONTACTS), CB_INSERTSTRING, 0, (LPARAM)(char*)Translate("Settings"));
		SendMessage(GetDlgItem(hwnd, IDC_CONTACTS), CB_SETITEMDATA, index, 0);
		SendMessage(GetDlgItem(hwnd, IDC_CONTACTS), CB_SETCURSEL, index, 0);

		SetWindowLongPtr(hwnd,GWLP_USERDATA,lParam);
		TranslateDialogDefault(hwnd);
	}
	else if (msg == WM_COMMAND)
	{
		switch(LOWORD(wParam)) {
		case CHK_COPY2ALL:
			EnableWindow(GetDlgItem(hwnd, IDC_CONTACTS),!IsDlgButtonChecked(hwnd,CHK_COPY2ALL));
			break;

		case IDOK:
			if (!IsDlgButtonChecked(hwnd,CHK_COPY2ALL)) {
				MCONTACT hContact = (MCONTACT)SendMessage(GetDlgItem(hwnd, IDC_CONTACTS), CB_GETITEMDATA, SendMessage(GetDlgItem(hwnd, IDC_CONTACTS), CB_GETCURSEL, 0, 0), 0);
				copyModule(mac->module, mac->hContact, hContact);
			}
			else {
				SetCursor(LoadCursor(NULL,IDC_WAIT));
				for (MCONTACT hContact = db_find_first(); hContact; hContact = db_find_next(hContact))
					copyModule(mac->module, mac->hContact, hContact);

				SetCursor(LoadCursor(NULL,IDC_ARROW));
			}
			mir_free(mac);
			refreshTree(1);
			DestroyWindow(hwnd);
			break;

		case IDCANCEL:
			mir_free(mac);
			DestroyWindow(hwnd);
			break;
		}
	}
	return 0;
}
Example #18
0
int doContacts(HWND hwnd2Tree, HTREEITEM contactsRoot, ModuleSettingLL *modlist, MCONTACT hSelectedContact, char *SelectedModule, char *SelectedSetting)
{
	TVINSERTSTRUCT tvi;
	HTREEITEM contact;
	ModuleTreeInfoStruct *lParam;
	ModSetLinkLinkItem *module;
	int count = CallService(MS_DB_CONTACT_GETCOUNT, 0, 0);
	int itemscount = 0;
	int loaded, i = 0, icon = 0;
	HWND hwnd = GetParent(hwnd2Tree);
	int hItem = -1;

	SetWindowText(hwnd2mainWindow, Translate("Loading contacts..."));

	tvi.hInsertAfter = TVI_SORT;
	tvi.item.cChildren = 1;

	for (MCONTACT hContact = db_find_first(); hContact && hwnd2mainWindow; hContact = db_find_next(hContact)) {
		char szProto[100];
		if (DBGetContactSettingStringStatic(hContact, "Protocol", "p", szProto, SIZEOF(szProto))) {
			icon = GetProtoIcon(szProto);
			loaded = (icon != DEF_ICON);
		}
		else {
			icon = DEF_ICON;
			loaded = 0;
		}

		i++;

		// filter
		if ((loaded && Mode == MODE_UNLOADED) || (!loaded && Mode == MODE_LOADED))
			continue;

		// add the contact
		lParam = (ModuleTreeInfoStruct *)mir_calloc(sizeof(ModuleTreeInfoStruct));
		lParam->hContact = hContact;
		lParam->type = CONTACT;
		tvi.item.mask = TVIF_TEXT | TVIF_CHILDREN | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
		tvi.item.lParam = (LPARAM)lParam;
		tvi.hParent = contactsRoot;

		if (hSelectedContact != hContact)
			lParam->type |= EMPTY;

		// contacts name
		DBVARIANT dbv = {0};
		WCHAR nick[256];
		WCHAR protoW[256]; // unicode proto

		if (szProto)
			a2u(szProto, protoW, SIZEOF(protoW));
		else
			protoW[0] = 0;

		if (!szProto || !loaded) {
			tvi.item.iSelectedImage = (tvi.item.iImage = 4);

			if (protoW) {
				if (Order)
					mir_snwprintf(nick, SIZEOF(nick), L"(%s) %s %s", protoW, GetContactName(hContact, szProto, 1), L"(UNLOADED)");
				else
					mir_snwprintf(nick, SIZEOF(nick), L"%s (%s) %s", GetContactName(hContact, szProto, 1), protoW, L"(UNLOADED)");
			}
			else
				wcscpy(nick, nick_unknownW);
		}
		else {
			tvi.item.iSelectedImage = (tvi.item.iImage = icon); //GetProtoIcon(szProto, 7));
			if (Order)
				mir_snwprintf(nick, SIZEOF(nick), L"(%s) %s", protoW, GetContactName(hContact, szProto, 1));
			else
				mir_snwprintf(nick, SIZEOF(nick), L"%s (%s)", GetContactName(hContact, szProto, 1), protoW);
		}

		tvi.item.pszText = (char *)nick;
		contact = TreeView_InsertItemW(hwnd2Tree, &tvi);

		itemscount++;

		if (hSelectedContact == hContact) {
			module = modlist->first;
			while (module && hwnd2mainWindow) {
				if (module->name[0] && !IsModuleEmpty(hContact, module->name)) {
					tvi.hParent = contact;
					tvi.hInsertAfter = TVI_SORT;
					tvi.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM;
					tvi.item.pszText = module->name;

					lParam = (ModuleTreeInfoStruct *)mir_calloc(sizeof(ModuleTreeInfoStruct));
					lParam->hContact = hContact;

					tvi.item.iImage = 1;
					tvi.item.iSelectedImage = 2;
					lParam->type = KNOWN_MODULE;

					tvi.item.lParam = (LPARAM)lParam;
					TreeView_InsertItem(hwnd2Tree, &tvi);
				}
				module = (ModSetLinkLinkItem *)module->next;
			}

			hItem = findItemInTree(hwnd2Tree, hSelectedContact, SelectedModule);
		}
	}

	if (hItem != -1) {
		TreeView_SelectItem(hwnd2Tree, (HTREEITEM)hItem);
		TreeView_Expand(hwnd2Tree, hItem, TVE_EXPAND);
		if (SelectedSetting[0])
			SelectSetting(SelectedSetting);
	}

	return itemscount;
}
Example #19
0
int ProcessStatusMessage(DBCONTACTWRITESETTING *cws, MCONTACT hContact)
{
	STATUSMSGINFO smi;
	bool bEnablePopup = true, bEnableSound = true;
	char *szProto = GetContactProto(hContact);

	smi.proto = szProto;
	smi.hContact = hContact;
	smi.compare = CompareStatusMsg(&smi, cws, "LastStatusMsg");
	if (smi.compare == COMPARE_SAME)
		goto skip_notify;

	if (cws->value.type == DBVT_DELETED)
		db_unset(hContact, "UserOnline", "LastStatusMsg");
	else
		db_set(hContact, "UserOnline", "LastStatusMsg", &cws->value);

	//don't show popup when mradio connecting and disconnecting
	if (_stricmp(szProto, "mRadio") == 0 && !cws->value.type == DBVT_DELETED) {
		wchar_t buf[MAX_PATH];
		mir_snwprintf(buf, L" (%s)", TranslateT("connecting"));
		T2Utf pszUtf(buf);
		mir_snwprintf(buf, L" (%s)", TranslateT("aborting"));
		T2Utf pszUtf2(buf);
		mir_snwprintf(buf, L" (%s)", TranslateT("playing"));
		T2Utf pszUtf3(buf);
		if (_stricmp(cws->value.pszVal, pszUtf) == 0 || _stricmp(cws->value.pszVal, pszUtf2) == 0 || _stricmp(cws->value.pszVal, pszUtf3) == 0)
			goto skip_notify;
	}

	// check per-contact ignored events
	if (db_get_b(hContact, MODULE, "EnableSMsgNotify", 1) == 0)
		bEnableSound = bEnablePopup = false;

	// we're offline or just connecting
	int myStatus = Proto_GetStatus(szProto);
	if (myStatus == ID_STATUS_OFFLINE)
		goto skip_notify;

	char dbSetting[64];
	mir_snprintf(dbSetting, "%s_enabled", szProto);
	// this proto is not set for status message notifications
	if (db_get_b(NULL, MODULE, dbSetting, 1) == 0)
		goto skip_notify;
	mir_snprintf(dbSetting, "%d", IDC_CHK_STATUS_MESSAGE);
	// status message change notifications are disabled
	if (db_get_b(NULL, MODULE, dbSetting, 1) == 0)
		goto skip_notify;

	if (SkipHiddenContact(hContact))
		goto skip_notify;

	// check if our status isn't on autodisable list
	if (opt.AutoDisable) {
		char statusIDs[12], statusIDp[12];
		mir_snprintf(statusIDs, "s%d", myStatus);
		mir_snprintf(statusIDp, "p%d", myStatus);
		bEnableSound = db_get_b(0, MODULE, statusIDs, 1) ? FALSE : bEnableSound;
		bEnablePopup = db_get_b(0, MODULE, statusIDp, 1) ? FALSE : bEnablePopup;
	}

	// check flags
	if ((!(templates.PopupSMsgFlags & NOTIFY_REMOVE_MESSAGE) && (smi.compare == COMPARE_DEL))
		|| (!(templates.PopupSMsgFlags & NOTIFY_NEW_MESSAGE) && (smi.compare == COMPARE_DIFF)))
		bEnablePopup = false;

	if (db_get_b(0, MODULE, szProto, 1) == 0 && !opt.PSMsgOnConnect)
		bEnablePopup = false;

	if (bEnablePopup && db_get_b(hContact, MODULE, "EnablePopups", 1) && !opt.TempDisabled) {
		// cut message if needed
		wchar_t *copyText = nullptr;
		if (opt.PSMsgTruncate && (opt.PSMsgLen > 0) && smi.newstatusmsg && (mir_wstrlen(smi.newstatusmsg) > opt.PSMsgLen)) {
			wchar_t buff[MAX_TEXT_LEN + 3];
			copyText = mir_wstrdup(smi.newstatusmsg);
			wcsncpy(buff, smi.newstatusmsg, opt.PSMsgLen);
			buff[opt.PSMsgLen] = 0;
			mir_wstrcat(buff, L"...");
			replaceStrW(smi.newstatusmsg, buff);
		}

		wchar_t *str;
		if (smi.compare == COMPARE_DEL) {
			char protoname[MAX_PATH];
			mir_snprintf(protoname, "%s_TPopupSMsgRemoved", szProto);
			DBVARIANT dbVar = { 0 };
			if (db_get_ws(NULL, MODULE, protoname, &dbVar)) {
				str = GetStr(&smi, DEFAULT_POPUP_SMSGREMOVED);
			}
			else {
				str = GetStr(&smi, dbVar.ptszVal);
				db_free(&dbVar);
			}
		}
		else {
			char protoname[MAX_PATH];
			mir_snprintf(protoname, "%s_TPopupSMsgChanged", szProto);
			DBVARIANT dbVar = { 0 };
			if (db_get_ws(NULL, MODULE, protoname, &dbVar)) {
				str = GetStr(&smi, DEFAULT_POPUP_SMSGCHANGED);
			}
			else {
				str = GetStr(&smi, dbVar.ptszVal);
				db_free(&dbVar);
			}
		}

		ShowChangePopup(hContact,
			Skin_LoadProtoIcon(szProto, db_get_w(hContact, szProto, "Status", ID_STATUS_ONLINE)),
			ID_STATUS_STATUSMSG, str);

		mir_free(str);

		if (copyText) {
			mir_free(smi.newstatusmsg);
			smi.newstatusmsg = copyText;
		}
	}

	if (opt.BlinkIcon && opt.BlinkIcon_ForMsgs && !opt.TempDisabled) {
		HICON hIcon = opt.BlinkIcon_Status ? Skin_LoadProtoIcon(szProto, db_get_w(hContact, szProto, "Status", ID_STATUS_ONLINE)) : Skin_LoadIcon(SKINICON_OTHER_USERONLINE);
		wchar_t str[256];
		mir_snwprintf(str, TranslateT("%s changed status message to %s"), Clist_GetContactDisplayName(hContact), smi.newstatusmsg);
		BlinkIcon(hContact, hIcon, str);
	}

	if (bEnableSound && db_get_b(0, "Skin", "UseSound", TRUE) && db_get_b(hContact, MODULE, "EnableSounds", 1) && !opt.TempDisabled) {
		if (smi.compare == COMPARE_DEL)
			PlayChangeSound(hContact, StatusListEx[ID_STATUS_SMSGREMOVED].lpzSkinSoundName);
		else
			PlayChangeSound(hContact, StatusListEx[ID_STATUS_SMSGCHANGED].lpzSkinSoundName);
	}

	BOOL bEnableLog = opt.SMsgLogToDB && db_get_b(hContact, MODULE, "EnableSMsgLogging", 1);
	if (bEnableLog && (!opt.SMsgLogToDB_WinOpen || CheckMsgWnd(hContact)))
		LogSMsgToDB(&smi, smi.compare == COMPARE_DEL ? templates.LogSMsgRemoved : templates.LogSMsgChanged);

	if (opt.SMsgLogToFile && db_get_b(hContact, MODULE, "EnableSMsgLogging", 1)) {
		wchar_t stzDate[MAX_STATUSTEXT], stzTime[MAX_STATUSTEXT], stzText[MAX_TEXT_LEN];

		GetTimeFormat(LOCALE_USER_DEFAULT, 0, nullptr, L"HH':'mm", stzTime, _countof(stzTime));
		GetDateFormat(LOCALE_USER_DEFAULT, 0, nullptr, L"dd/MM/yyyy", stzDate, _countof(stzDate));

		wchar_t *str;
		if (smi.compare == COMPARE_DEL)
			str = GetStr(&smi, templates.LogSMsgRemoved);
		else
			str = GetStr(&smi, templates.LogSMsgChanged);

		mir_snwprintf(stzText, L"%s, %s. %s %s\r\n", stzDate, stzTime, Clist_GetContactDisplayName(hContact), str);

		LogToFile(stzText);
		mir_free(str);
	}

skip_notify:
	replaceStrW(smi.newstatusmsg, nullptr);
	replaceStrW(smi.oldstatusmsg, nullptr);
	return 1;
}
Example #20
0
int ContactStatusChanged(MCONTACT hContact, WORD oldStatus, WORD newStatus)
{
	if (opt.LogToDB && (!opt.LogToDB_WinOpen || CheckMsgWnd(hContact))) {
		wchar_t stzStatusText[MAX_SECONDLINE] = { 0 };
		GetStatusText(hContact, newStatus, oldStatus, stzStatusText);
		T2Utf blob(stzStatusText);

		DBEVENTINFO dbei = {};
		dbei.cbBlob = (DWORD)mir_strlen(blob) + 1;
		dbei.pBlob = (PBYTE)blob;
		dbei.eventType = EVENTTYPE_STATUSCHANGE;
		dbei.flags = DBEF_READ | DBEF_UTF;

		dbei.timestamp = (DWORD)time(0);
		dbei.szModule = MODULE;
		MEVENT hDBEvent = db_event_add(hContact, &dbei);

		if (opt.LogToDB_WinOpen && opt.LogToDB_Remove) {
			DBEVENT *dbevent = (DBEVENT *)mir_alloc(sizeof(DBEVENT));
			dbevent->hContact = hContact;
			dbevent->hDBEvent = hDBEvent;
			eventListStatus.insert(dbevent);
		}
	}

	bool bEnablePopup = true, bEnableSound = true;
	char *szProto = GetContactProto(hContact);
	int myStatus = Proto_GetStatus(szProto);

	if (!mir_strcmp(szProto, META_PROTO)) { //this contact is Meta
		MCONTACT hSubContact = db_mc_getMostOnline(hContact);
		char *szSubProto = GetContactProto(hSubContact);
		if (szSubProto == nullptr)
			return 0;

		if (newStatus == ID_STATUS_OFFLINE) {
			// read last online proto for metacontact if exists,
			// to avoid notifying when meta went offline but default contact's proto still online
			DBVARIANT dbv;
			if (!db_get_s(hContact, szProto, "LastOnline", &dbv)) {
				szSubProto = NEWSTR_ALLOCA(dbv.pszVal);
				db_free(&dbv);
			}
		}
		else
			db_set_s(hContact, szProto, "LastOnline", szSubProto);

		if (db_get_b(0, MODULE, szSubProto, 1) == 0)
			return 0;

		szProto = szSubProto;
	}
	else {
		if (myStatus == ID_STATUS_OFFLINE || db_get_b(0, MODULE, szProto, 1) == 0)
			return 0;
	}

	if (!opt.FromOffline || oldStatus != ID_STATUS_OFFLINE) { // Either it wasn't a change from Offline or we didn't enable that.
		char buff[8];
		mir_snprintf(buff, "%d", newStatus);
		if (db_get_b(0, MODULE, buff, 1) == 0)
			return 0; // "Notify when a contact changes to one of..." is unchecked
	}

	if (SkipHiddenContact(hContact))
		return 0;

	// check if that proto from which we received statuschange notification, isn't in autodisable list
	if (opt.AutoDisable) {
		char statusIDs[12], statusIDp[12];
		mir_snprintf(statusIDs, "s%d", myStatus);
		mir_snprintf(statusIDp, "p%d", myStatus);
		bEnableSound = db_get_b(0, MODULE, statusIDs, 1) ? FALSE : TRUE;
		bEnablePopup = db_get_b(0, MODULE, statusIDp, 1) ? FALSE : TRUE;
	}

	if (bEnablePopup && db_get_b(hContact, MODULE, "EnablePopups", 1) && !opt.TempDisabled) {
		int wStatus = Proto_GetStatus(szProto);
		wchar_t str[MAX_SECONDLINE] = { 0 };
		if (opt.ShowStatus)
			GetStatusText(hContact, newStatus, oldStatus, str);

		if (opt.ReadAwayMsg && wStatus != ID_STATUS_INVISIBLE && StatusHasAwayMessage(szProto, newStatus))
			db_set_ws(hContact, MODULE, "LastPopupText", str);

		PLUGINDATA *pdp = (PLUGINDATA *)mir_calloc(sizeof(PLUGINDATA));
		pdp->oldStatus = oldStatus;
		pdp->newStatus = newStatus;
		pdp->hAwayMsgHook = nullptr;
		pdp->hAwayMsgProcess = nullptr;
		ShowChangePopup(hContact, Skin_LoadProtoIcon(szProto, newStatus), newStatus, str, pdp);
	}

	if (opt.BlinkIcon && !opt.TempDisabled) {
		HICON hIcon = opt.BlinkIcon_Status ? Skin_LoadProtoIcon(szProto, newStatus) : Skin_LoadIcon(SKINICON_OTHER_USERONLINE);
		wchar_t str[256];
		mir_snwprintf(str, TranslateT("%s is now %s"), Clist_GetContactDisplayName(hContact), StatusList[Index(newStatus)].lpzStandardText);
		BlinkIcon(hContact, hIcon, str);
	}

	if (bEnableSound && db_get_b(0, "Skin", "UseSound", TRUE) && db_get_b(hContact, MODULE, "EnableSounds", 1) && !opt.TempDisabled) {
		if (oldStatus == ID_STATUS_OFFLINE)
			PlayChangeSound(hContact, StatusListEx[ID_STATUS_FROMOFFLINE].lpzSkinSoundName);
		else
			PlayChangeSound(hContact, StatusList[Index(newStatus)].lpzSkinSoundName);
	}

	if (opt.LogToFile) {
		wchar_t stzDate[MAX_STATUSTEXT], stzTime[MAX_STATUSTEXT], stzText[MAX_TEXT_LEN];

		GetTimeFormat(LOCALE_USER_DEFAULT, 0, nullptr, L"HH':'mm", stzTime, _countof(stzTime));
		GetDateFormat(LOCALE_USER_DEFAULT, 0, nullptr, L"dd/MM/yyyy", stzDate, _countof(stzDate));
		mir_snwprintf(stzText, TranslateT("%s, %s. %s changed status to %s (was %s)\r\n"),
			stzDate, stzTime, Clist_GetContactDisplayName(hContact), StatusList[Index(newStatus)].lpzStandardText,
			StatusList[Index(oldStatus)].lpzStandardText);
		LogToFile(stzText);
	}

	return 0;
}
Example #21
0
int ContactSettingChanged(WPARAM hContact, LPARAM lParam)
{
	DBCONTACTWRITESETTING *cws = (DBCONTACTWRITESETTING*)lParam;
	if (strcmp(cws->szSetting, DB_MIRVER))
		return 0;

	SHOWPOPUP_DATA sd = { 0 };
	char *szProto = GetContactProto(hContact);
	if (g_PreviewOptPage)
		sd.MirVer = L"Miranda NG ICQ 0.93.5.3007";
	else {
		if (!hContact) // exit if hContact == NULL and it's not a popup preview
			return 0;

		_ASSERT(szProto);
		if (!strcmp(szProto, META_PROTO)) // workaround for metacontacts
			return 0;

		sd.MirVer = db_get_s(hContact, szProto, DB_MIRVER, L"");
		if (sd.MirVer.IsEmpty())
			return 0;
	}
	sd.OldMirVer = db_get_s(hContact, MODULENAME, DB_OLDMIRVER, L"");
	db_set_ws(hContact, MODULENAME, DB_OLDMIRVER, sd.MirVer); // we have to write it here, because we modify sd.OldMirVer and sd.MirVer to conform our settings later
	if (sd.OldMirVer.IsEmpty())  // looks like it's the right way to do
		return 0;

	COptPage PopupOptPage;
	if (g_PreviewOptPage)
		PopupOptPage = *g_PreviewOptPage;
	else {
		PopupOptPage = g_PopupOptPage;
		PopupOptPage.DBToMem();
	}

	MCONTACT hContactOrMeta = (hContact) ? db_mc_getMeta(hContact) : 0;
	if (!hContactOrMeta)
		hContactOrMeta = hContact;

	if (hContact && db_get_b(hContactOrMeta, "CList", "Hidden", 0))
		return 0;

	int PerContactSetting = hContact ? db_get_b(hContact, MODULENAME, DB_CCN_NOTIFY, NOTIFY_USEGLOBAL) : NOTIFY_ALWAYS; // NOTIFY_ALWAYS for preview
	if (PerContactSetting == NOTIFY_USEGLOBAL && hContactOrMeta != hContact) // subcontact setting has a priority over a metacontact setting
		PerContactSetting = db_get_b(hContactOrMeta, MODULENAME, DB_CCN_NOTIFY, NOTIFY_USEGLOBAL);

	if (PerContactSetting && (PerContactSetting == NOTIFY_ALMOST_ALWAYS || PerContactSetting == NOTIFY_ALWAYS || !PopupOptPage.GetValue(IDC_POPUPOPTDLG_USESTATUSNOTIFYFLAG) || !(db_get_dw(hContactOrMeta, "Ignore", "Mask1", 0) & 0x8))) { // check if we need to notify at all
		sd.hContact = hContact;
		sd.PopupOptPage = &PopupOptPage;
		if (!PopupOptPage.GetValue(IDC_POPUPOPTDLG_VERCHGNOTIFY) || !PopupOptPage.GetValue(IDC_POPUPOPTDLG_SHOWVER)) {
			if (bFingerprintExists) {
				LPCTSTR ptszOldClient = Finger_GetClientDescr(sd.OldMirVer);
				LPCTSTR ptszClient = Finger_GetClientDescr(sd.MirVer);
				if (ptszOldClient && ptszClient) {
					if (PerContactSetting != NOTIFY_ALMOST_ALWAYS && PerContactSetting != NOTIFY_ALWAYS && !PopupOptPage.GetValue(IDC_POPUPOPTDLG_VERCHGNOTIFY) && !wcscmp(ptszClient, ptszOldClient))
						return 0;

					if (!PopupOptPage.GetValue(IDC_POPUPOPTDLG_SHOWVER)) {
						sd.MirVer = ptszClient;
						sd.OldMirVer = ptszOldClient;
					}
				}
			}
		}
		if (sd.MirVer == (const wchar_t*)sd.OldMirVer) {
			_ASSERT(hContact);
			return 0;
		}
		if (PerContactSetting == NOTIFY_ALWAYS || (PopupOptPage.GetValue(IDC_POPUPOPTDLG_POPUPNOTIFY) && (g_PreviewOptPage || PerContactSetting == NOTIFY_ALMOST_ALWAYS || -1 == PcreCheck(sd.MirVer)))) {
			ShowPopup(&sd);
			Skin_PlaySound(CLIENTCHANGED_SOUND);
		}
	}

	if (hContact) {
		TCString ClientName;
		if (PopupOptPage.GetValue(IDC_POPUPOPTDLG_SHOWPREVCLIENT) && sd.OldMirVer.GetLen()) {
			mir_snwprintf(ClientName.GetBuffer(MAX_MSG_LEN), MAX_MSG_LEN, TranslateT("%s (was %s)"), (const wchar_t*)sd.MirVer, (const wchar_t*)sd.OldMirVer);
			ClientName.ReleaseBuffer();
		}
		else ClientName = sd.MirVer;
	}
	_ASSERT(sd.MirVer.GetLen()); // save the last known MirVer value even if the new one is empty
	return 0;
}
Example #22
0
CListEvent* cli_AddEvent(CLISTEVENT *cle)
{
	CListEvent *p = corecli.pfnAddEvent(cle);
	if (p == nullptr)
		return nullptr;

	if (p->hContact != 0 && p->hDbEvent != 1 && !(p->flags & CLEF_ONLYAFEW)) {
		MENUITEMINFO mii = { 0 };
		mii.cbSize = sizeof(mii);
		mii.fMask = MIIM_DATA | MIIM_BITMAP | MIIM_ID;
		if (p->pszService &&
			(!strncmp(MS_MSG_READMESSAGE, p->pszService, _countof(MS_MSG_READMESSAGE)) ||
			 !strncmp("GChat/DblClickEvent", p->pszService, _countof("GChat/DblClickEvent")))) {
			// dup check only for msg events
			for (int j = 0; j < GetMenuItemCount(g_CluiData.hMenuNotify); j++) {
				if (GetMenuItemInfo(g_CluiData.hMenuNotify, j, TRUE, &mii) != 0) {
					NotifyMenuItemExData *nmi = (struct NotifyMenuItemExData *) mii.dwItemData;
					if (nmi != nullptr && (HANDLE)nmi->hContact == (HANDLE)p->hContact && nmi->iIcon == p->imlIconIndex)
						return p;
				}
			}
		}

		char *szProto = GetContactProto(p->hContact);
		wchar_t *szName = Clist_GetContactDisplayName(p->hContact);
		if (szProto && szName) {
			NotifyMenuItemExData *nmi = (struct NotifyMenuItemExData *) malloc(sizeof(struct NotifyMenuItemExData));
			if (nmi) {
				wchar_t szBuffer[128];
				wchar_t* szStatus = Clist_GetStatusModeDescription(db_get_w(p->hContact, szProto, "Status", ID_STATUS_OFFLINE), 0);
				wchar_t szwProto[64];
				MultiByteToWideChar(CP_ACP, 0, szProto, -1, szwProto, 64);
				szwProto[63] = 0;
				mir_snwprintf(szBuffer, L"%s: %s (%s)", szwProto, szName, szStatus);
				szBuffer[127] = 0;
				AppendMenu(g_CluiData.hMenuNotify, MF_BYCOMMAND | MF_STRING, g_CluiData.wNextMenuID, szBuffer);
				mii.hbmpItem = HBMMENU_CALLBACK;
				nmi->hContact = p->hContact;
				nmi->iIcon = p->imlIconIndex;
				nmi->hIcon = p->hIcon;
				nmi->hDbEvent = p->hDbEvent;
				mii.dwItemData = (ULONG_PTR)nmi;
				mii.wID = g_CluiData.wNextMenuID;
				SetMenuItemInfo(g_CluiData.hMenuNotify, g_CluiData.wNextMenuID, FALSE, &mii);
				p->menuId = g_CluiData.wNextMenuID;
				g_CluiData.wNextMenuID++;
				if (g_CluiData.wNextMenuID > 0x7fff)
					g_CluiData.wNextMenuID = 1;
				g_CluiData.iIconNotify = p->imlIconIndex;
			}
		}
	}
	else if (p->hContact != 0 && (p->flags & CLEF_ONLYAFEW)) {
		g_CluiData.iIconNotify = p->imlIconIndex;
		g_CluiData.hUpdateContact = p->hContact;
	}

	if (g_clistApi.events->getCount() > 0) {
		g_CluiData.bEventAreaEnabled = true;
		if (g_CluiData.bNotifyActive == false) {
			g_CluiData.bNotifyActive = true;
			EventArea_HideShowNotifyFrame();
		}
	}

	cliInvalidateRect(g_CluiData.hwndEventFrame, nullptr, FALSE);
	return p;
}
Example #23
0
/**
 * Format the full name for the contact.
 *
 * @params	ci			- CONTACTINFO structure
 *
 * @retval	0 - if setting was found and read correctly
 * @retval	1 - if any error occured or setting was not found
 **/
static FORCEINLINE INT_PTR GCIFirstLast(CONTACTINFO *ci)
{
	DBVARIANT dbvf, dbvl;
	size_t cbf, cbl;

	BYTE type = CI_TCHAR(ci);

	if (DB::Setting::GetEx(ci->hContact, USERINFO, ci->szProto, SET_CONTACT_FIRSTNAME, &dbvf, type))
	{
		dbvf.type = DBVT_DELETED;
	}
	if (DB::Setting::GetEx(ci->hContact, USERINFO, ci->szProto, SET_CONTACT_LASTNAME, &dbvl, type))
	{
		dbvl.type = DBVT_DELETED;
	}

	if (type == DBVT_WCHAR)
	{
		// both firstname and lastname are valid
		if (dbvf.type == DBVT_WCHAR && dbvl.type == DBVT_WCHAR)
		{
			cbf = mir_wcslen(dbvf.pwszVal);
			cbl = mir_wcslen(dbvl.pwszVal);

			ci->pszVal = (LPTSTR) mir_alloc((cbf + cbl + 2) * sizeof(WCHAR));
			if (ci->pszVal)
			{
				mir_snwprintf((LPWSTR) ci->pszVal, cbf + cbl + 2, L"%s %s", dbvf.pwszVal, dbvl.pwszVal);
			}
			DB::Variant::Free(&dbvf);
			DB::Variant::Free(&dbvl);
		}
		// set firstname as result
		else if (dbvf.type == DBVT_WCHAR)
		{
			ci->pszVal = (LPTSTR) dbvf.pwszVal;
			DB::Variant::Free(&dbvl);
		}
		// set lastname as result
		else if (dbvl.type == DBVT_WCHAR)
		{
			ci->pszVal = (LPTSTR) dbvl.pwszVal;
			DB::Variant::Free(&dbvf);
		}
		else
		{
			ci->pszVal = NULL;
			DB::Variant::Free(&dbvf);
			DB::Variant::Free(&dbvl);
		}
	}
	else
	{
		// both firstname and lastname are valid
		if (dbvf.type == DBVT_ASCIIZ && dbvl.type == DBVT_ASCIIZ)
		{
			cbf = mir_strlen(dbvf.pszVal);
			cbl = mir_strlen(dbvl.pszVal);

			ci->pszVal = (LPTSTR) mir_alloc((cbf + cbl + 2) * sizeof(CHAR));
			if (ci->pszVal)
			{
				mir_snprintf((LPSTR) ci->pszVal, cbf + cbl + 2, "%s %s", dbvf.pszVal, dbvl.pszVal);
			}
			DB::Variant::Free(&dbvf);
			DB::Variant::Free(&dbvl);
		}
		// set firstname as result
		else if (dbvf.type == DBVT_ASCIIZ)
		{
			ci->pszVal = (LPTSTR) dbvf.pszVal;
			DB::Variant::Free(&dbvl);
		}
		// set lastname as result
		else if (dbvl.type == DBVT_ASCIIZ)
		{
			ci->pszVal = (LPTSTR) dbvl.pszVal;
			DB::Variant::Free(&dbvf);
		}
		else
		{
			ci->pszVal = NULL;
			DB::Variant::Free(&dbvf);
			DB::Variant::Free(&dbvl);
		}
	}
	ci->type = (ci->pszVal != NULL) ? CNFT_ASCIIZ : 0;
	return ci->type == 0;
}
Example #24
0
int Cache_GetLineText(ClcCacheEntry *pdnce, int type, LPTSTR text, int text_size, ClcLineInfo &line)
{
	if (text == nullptr)
		return TEXT_EMPTY;
	text[0] = '\0';

	switch (type) {
	case TEXT_STATUS:
LBL_Status:
		if (GetStatusName(text, text_size, pdnce, line.xstatus_has_priority) == -1 && line.use_name_and_message_for_xstatus) {
			// Try to get XStatusMsg
			ptrW tszXStatusMsg(db_get_wsa(pdnce->hContact, pdnce->szProto, "XStatusMsg"));
			if (tszXStatusMsg != nullptr && tszXStatusMsg[0] != 0) {
				wchar_t *tmp = NEWWSTR_ALLOCA(text);
				mir_snwprintf(text, text_size, L"%s: %s", tmp, tszXStatusMsg);
				CopySkipUnprintableChars(text, text, text_size - 1);
			}
		}
		return TEXT_STATUS;

	case TEXT_NICKNAME:
		if (pdnce->hContact && pdnce->szProto) {
			ptrW tszNick(db_get_wsa(pdnce->hContact, pdnce->szProto, "Nick"));
			if (tszNick != nullptr) {
				mir_wstrncpy(text, tszNick, text_size);
				CopySkipUnprintableChars(text, text, text_size - 1);
			}
		}
		return TEXT_NICKNAME;

	case TEXT_STATUS_MESSAGE:
		if (GetStatusMessage(text, text_size, pdnce, line.xstatus_has_priority) == -1 && line.use_name_and_message_for_xstatus) {
			// Try to get XStatusName
			ptrW tszXStatusName(db_get_wsa(pdnce->hContact, pdnce->szProto, "XStatusName"));
			if (tszXStatusName != nullptr && tszXStatusName[0] != 0) {
				wchar_t *tmp = NEWWSTR_ALLOCA(text);
				mir_snwprintf(text, text_size, L"%s: %s", tszXStatusName, tmp);
				CopySkipUnprintableChars(text, text, text_size - 1);
			}
		}
		else if (line.use_name_and_message_for_xstatus && line.xstatus_has_priority) {
			// Try to get XStatusName
			ptrW tszXStatusName(db_get_wsa(pdnce->hContact, pdnce->szProto, "XStatusName"));
			if (tszXStatusName != nullptr && tszXStatusName[0] != 0) {
				mir_wstrncpy(text, tszXStatusName, text_size);
				CopySkipUnprintableChars(text, text, text_size - 1);
			}
		}

		if (text[0] == '\0') {
			if (line.show_listening_if_no_away) {
				GetListeningTo(text, text_size, pdnce);
				if (text[0] != '\0')
					return TEXT_LISTENING_TO;
			}

			if (line.show_status_if_no_away) // re-request status if no away
				goto LBL_Status;
		}
		return TEXT_STATUS_MESSAGE;

	case TEXT_LISTENING_TO:
		GetListeningTo(text, text_size, pdnce);
		return TEXT_LISTENING_TO;

	case TEXT_TEXT:
		{
			ptrW tmp(variables_parsedup(line.text, pdnce->tszName, pdnce->hContact));
			mir_wstrncpy(text, tmp, text_size);
			CopySkipUnprintableChars(text, text, text_size - 1);
		}
		return TEXT_TEXT;

	case TEXT_CONTACT_TIME:
		if (pdnce->hTimeZone) {
			// Get pdnce time
			text[0] = 0;
			TimeZone_PrintDateTime(pdnce->hTimeZone, L"t", text, text_size, 0);
		}
		return TEXT_CONTACT_TIME;
	}

	return TEXT_EMPTY;
}
Example #25
0
void __cdecl FindSettings(LPVOID param)
{
	FindInfo* fi = (FindInfo*)param;
	HWND hwndParent = GetParent(fi->hwnd);

	ModuleSettingLL ModuleList, SettingList;
	ModSetLinkLinkItem *module, *setting;

	MCONTACT hContact;
	DBVARIANT dbv = { 0 };

	int foundCount = 0, replaceCount = 0, deleteCount = 0;

	DWORD numsearch = 0, numreplace = 0;
	int NULLContactDone = 0;

	if (!fi->search || !EnumModules(&ModuleList)) {
		fi_free(fi);
		return;
	}

	_T2A search(fi->search);
	_T2A replace(fi->replace);

	// skip modules and setting names on unicode search or replace
	if (IsRealUnicode(fi->search) || IsRealUnicode(fi->replace)) {
		fi->options &= ~(F_SETNAME | F_MODNAME);
		fi->options |= F_UNICODE;
	}

	if (!(fi->options & F_UNICODE) && (fi->options & F_SETVAL)) {
		char val[16];
		numsearch = strtoul(search, nullptr, 10);
		_ultoa(numsearch, val, 10);
		if (!mir_strcmp(search, val)) {
			fi->options |= F_NUMSRCH;
			// replace numeric values only entirely
			if (replace && (fi->options & F_ENTIRE)) {
				numreplace = strtoul(replace, nullptr, 10);
				_ultoa(numreplace, val, 10);
				if (!replace[0] || !mir_strcmp(replace, val))
					fi->options |= F_NUMREPL;
			}
		}
	}

	SendDlgItemMessage(hwndParent, IDC_SBAR, SB_SETTEXT, 0, (LPARAM)TranslateT("Searching..."));

	hContact = 0;

	while (GetWindowLongPtr(GetDlgItem(hwndParent, IDC_SEARCH), GWLP_USERDATA)) {

		if (!hContact) {
			if (NULLContactDone)
				break;
			else {
				NULLContactDone = 1;
				hContact = db_find_first();
			}
		}
		else hContact = db_find_next(hContact);

		for (module = ModuleList.first; module; module = module->next) {

			if (IsModuleEmpty(hContact, module->name))
				continue;

			if (fi->options & (F_SETVAL | F_SETNAME)) {

				if (!EnumSettings(hContact, module->name, &SettingList)) {
					fi_free(fi);
					FreeModuleSettingLL(&ModuleList);
					return;
				}

				for (setting = SettingList.first; setting; setting = setting->next) {

					dbv.type = 0;
					if (db_get_s(hContact, module->name, setting->name, &dbv, 0))
						continue;

					// check in settings value				
					if (fi->options & F_SETVAL) {

						wchar_t *value = nullptr;

						switch (dbv.type) {

						case DBVT_BYTE:
						case DBVT_WORD:
						case DBVT_DWORD:
							if ((fi->options & F_NUMSRCH) && numsearch == getNumericValue(&dbv)) {
								wchar_t *val = fi->search;
								int flag = F_SETVAL;

								if (fi->options & F_NUMREPL) {
									if (replace[0]) {
										db_unset(hContact, module->name, setting->name);
										flag |= F_DELETED;
										deleteCount++;
									}
									else
										if (setNumericValue(hContact, module->name, setting->name, numreplace, dbv.type)) {
											val = fi->replace;
											flag |= F_REPLACED;
											replaceCount++;
										}
								}

								ItemFound(fi->hwnd, hContact, module->name, setting->name, val, flag);
							}
							break;

						case DBVT_WCHAR:
							if (!value) value = mir_wstrdup(dbv.pwszVal);
						case DBVT_UTF8:
							if (!value) value = mir_utf8decodeW(dbv.pszVal);
						case DBVT_ASCIIZ:
							if (!value) value = mir_a2u(dbv.pszVal);

							if (FindMatchT(value, fi->search, fi->options)) {
								foundCount++;
								ptrW ptr;
								wchar_t *newValue = value;
								int flag = F_SETVAL;

								if (fi->replace) {
									newValue = (fi->options & F_ENTIRE) ? fi->replace : ptr = multiReplaceT(value, fi->search, fi->replace, fi->options & F_CASE);
									// !!!! delete or make empty ?
									if (!newValue[0]) {
										db_unset(hContact, module->name, setting->name);
										flag |= F_DELETED;
										newValue = value;
										deleteCount++;
									}
									else {
#ifdef _UNICODE
										// save as unicode if needed
										if (dbv.type != DBVT_ASCIIZ || IsRealUnicode(newValue))
											db_set_ws(hContact, module->name, setting->name, newValue);
										else
#endif
											db_set_s(hContact, module->name, setting->name, _T2A(newValue));
										flag |= F_REPLACED;
										replaceCount++;
									}
								}

								ItemFound(fi->hwnd, hContact, module->name, setting->name, newValue, flag);
							}
							mir_free(value);
							break;
						} // switch
					}

					// check in setting name
					if ((fi->options & F_SETNAME) && FindMatchA(setting->name, search, fi->options)) {
						foundCount++;
						ptrA ptr;
						char *newSetting = setting->name;
						int flag = F_SETNAME;

						if (replace) {
							newSetting = (fi->options & F_ENTIRE) ? replace : ptr = multiReplaceA(setting->name, search, replace, fi->options & F_CASE);

							if (!newSetting[0]) {
								db_unset(hContact, module->name, setting->name);
								flag |= F_DELETED;
								newSetting = setting->name;
								deleteCount++;
							}
							else {
								DBVARIANT dbv2;
								// skip if exist
								if (!db_get_s(hContact, module->name, newSetting, &dbv2, 0))
									db_free(&dbv2);
								else if (!db_set(hContact, module->name, newSetting, &dbv)) {
									db_unset(hContact, module->name, setting->name);
									flag |= F_REPLACED;
									replaceCount++;
								}
							}
						}

						ItemFound(fi->hwnd, hContact, module->name, newSetting, nullptr, flag);
					}

					db_free(&dbv);

				} // for(setting)

				FreeModuleSettingLL(&SettingList);
			}

			// check in module name
			if ((fi->options & F_MODNAME) && FindMatchA(module->name, search, fi->options)) {
				foundCount++;
				char *newModule = module->name;
				int flag = F_MODNAME;
				ptrA ptr;

				if (replace) {
					newModule = (fi->options & F_ENTIRE) ? replace : ptr = multiReplaceA(module->name, search, replace, fi->options & F_CASE);

					if (!newModule[0]) {
						deleteModule(hContact, module->name, 0);
						replaceTreeItem(hContact, module->name, nullptr);
						flag |= F_DELETED;
						newModule = module->name;
						deleteCount++;
					}
					else if (renameModule(hContact, module->name, newModule)) {
						replaceTreeItem(hContact, module->name, nullptr);
						flag |= F_REPLACED;
						replaceCount++;
					}
				}

				ItemFound(fi->hwnd, hContact, newModule, nullptr, nullptr, flag);
			}

		} // for(module)
	}

	wchar_t msg[MSG_SIZE];
	mir_snwprintf(msg, TranslateT("Finished. Items found: %d / replaced: %d / deleted: %d"), foundCount, replaceCount, deleteCount);
	SendDlgItemMessage(hwndParent, IDC_SBAR, SB_SETTEXT, 0, (LPARAM)msg);

	if (fi->replace) {
		EnableWindow(GetDlgItem(hwndParent, IDC_SEARCH), 1);
		SetDlgItemText(hwndParent, IDOK, TranslateT("&Replace"));
	}
	else {
		SetDlgItemText(hwndParent, IDC_SEARCH, TranslateT("&Search"));
		EnableWindow(GetDlgItem(hwndParent, IDOK), 1);
	}

	fi_free(fi);
	FreeModuleSettingLL(&ModuleList);

	SetWindowLongPtr(GetDlgItem(hwndParent, IDC_SEARCH), GWLP_USERDATA, 0);
	EnableWindow(GetDlgItem(hwndParent, IDCANCEL), 1);
}
Example #26
0
void PackerJob::createToolTip()
{
	mir_snwprintf(uDlg->m_tszToolTipText, TranslateT("Status: %s\r\nFile: %s\r\nServer: %S"),
		getStatusString(), m_tszFileName, m_ftp->m_szServer);
}
Example #27
0
// dialog procedure for handling the contact ignore dialog (available from the contact menu
static INT_PTR CALLBACK IgnoreDialogProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	MCONTACT hContact = (MCONTACT)GetWindowLongPtr(hWnd, GWLP_USERDATA);

	switch (msg) {
	case WM_INITDIALOG:
		{
			DWORD dwMask;
			ClcContact *contact = nullptr;
			int pCaps;
			HWND hwndAdd;

			hContact = lParam;
			SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)hContact);
			dwMask = db_get_dw(hContact, "Ignore", "Mask1", 0);
			SendMessage(hWnd, WM_USER + 100, hContact, dwMask);
			SendMessage(hWnd, WM_USER + 120, 0, 0);
			TranslateDialogDefault(hWnd);
			hwndAdd = GetDlgItem(hWnd, IDC_IGN_ADDPERMANENTLY); // CreateWindowEx(0, L"CLCButtonClass", L"FOO", WS_VISIBLE | BS_PUSHBUTTON | WS_CHILD | WS_TABSTOP, 200, 276, 106, 24, hWnd, (HMENU)IDC_IGN_ADDPERMANENTLY, g_plugin.getInst(), NULL);
			CustomizeButton(hwndAdd, false, true, false);

			SendMessage(hwndAdd, BM_SETIMAGE, IMAGE_ICON, (LPARAM)Skin_LoadIcon(SKINICON_OTHER_ADDCONTACT));
			SetWindowText(hwndAdd, TranslateT("Add permanently"));
			EnableWindow(hwndAdd, db_get_b(hContact, "CList", "NotOnList", 0));

			hwndAdd = GetDlgItem(hWnd, IDC_DSP_LOADDEFAULT); // CreateWindowEx(0, L"CLCButtonClass", L"FOO", WS_VISIBLE | BS_PUSHBUTTON | WS_CHILD | WS_TABSTOP, 200, 276, 106, 24, hWnd, (HMENU)IDC_IGN_ADDPERMANENTLY, g_plugin.getInst(), NULL);
			CustomizeButton(hwndAdd, false, true, false);

			SendMessage(hwndAdd, BM_SETIMAGE, IMAGE_ICON, (LPARAM)Skin_LoadIcon(SKINICON_OTHER_DELETE));
			SetWindowText(hwndAdd, TranslateT("Revert to default"));
			EnableWindow(hwndAdd, TRUE);

			SendDlgItemMessage(hWnd, IDC_AVATARDISPMODE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Default (global setting)"));
			SendDlgItemMessage(hWnd, IDC_AVATARDISPMODE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Show always when available"));
			SendDlgItemMessage(hWnd, IDC_AVATARDISPMODE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Hide always"));

			SendDlgItemMessage(hWnd, IDC_SECONDLINEMODE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Default (global setting)"));
			SendDlgItemMessage(hWnd, IDC_SECONDLINEMODE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Never"));
			SendDlgItemMessage(hWnd, IDC_SECONDLINEMODE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Always"));
			SendDlgItemMessage(hWnd, IDC_SECONDLINEMODE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("When space is available"));
			SendDlgItemMessage(hWnd, IDC_SECONDLINEMODE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("When needed by status message"));

			if (cfg::clcdat) {
				Clist_FindItem(g_clistApi.hwndContactTree, cfg::clcdat, hContact, &contact, nullptr, nullptr);
				if (contact && contact->type != CLCIT_CONTACT) {
					DestroyWindow(hWnd);
					return FALSE;
				}
				else {
					wchar_t szTitle[512];
					DWORD dwFlags = db_get_dw(hContact, "CList", "CLN_Flags", 0);
					BYTE bSecondLine = db_get_b(hContact, "CList", "CLN_2ndline", -1);

					mir_snwprintf(szTitle, TranslateT("Contact list display and ignore options for %s"), contact ? contact->szText : Clist_GetContactDisplayName(hContact));

					SetWindowText(hWnd, szTitle);
					Window_SetSkinIcon_IcoLib(hWnd, SKINICON_OTHER_MIRANDA);
					pCaps = CallProtoService(contact ? contact->proto : GetContactProto(hContact), PS_GETCAPS, PFLAGNUM_1, 0);
					Utils::enableDlgControl(hWnd, IDC_IGN_ALWAYSONLINE, pCaps & PF1_INVISLIST ? TRUE : FALSE);
					Utils::enableDlgControl(hWnd, IDC_IGN_ALWAYSOFFLINE, pCaps & PF1_VISLIST ? TRUE : FALSE);
					CheckDlgButton(hWnd, IDC_IGN_PRIORITY, db_get_b(hContact, "CList", "Priority", 0) ? BST_CHECKED : BST_UNCHECKED);
					Utils::enableDlgControl(hWnd, IDC_IGN_PRIORITY, TRUE);
					Utils::enableDlgControl(hWnd, IDC_AVATARDISPMODE, TRUE);
					Utils::enableDlgControl(hWnd, IDC_SECONDLINEMODE, TRUE);
					if (dwFlags & ECF_FORCEAVATAR)
						SendDlgItemMessage(hWnd, IDC_AVATARDISPMODE, CB_SETCURSEL, 1, 0);
					else if (dwFlags & ECF_HIDEAVATAR)
						SendDlgItemMessage(hWnd, IDC_AVATARDISPMODE, CB_SETCURSEL, 2, 0);
					else
						SendDlgItemMessage(hWnd, IDC_AVATARDISPMODE, CB_SETCURSEL, 0, 0);

					if (dwFlags & ECF_FORCEOVERLAY)
						CheckDlgButton(hWnd, IDC_OVERLAYICON, BST_CHECKED);
					else if (dwFlags & ECF_HIDEOVERLAY)
						CheckDlgButton(hWnd, IDC_OVERLAYICON, BST_UNCHECKED);
					else
						CheckDlgButton(hWnd, IDC_OVERLAYICON, BST_INDETERMINATE);

					if (dwFlags & ECF_FORCELOCALTIME)
						CheckDlgButton(hWnd, IDC_SHOWLOCALTIME1, BST_CHECKED);
					else if (dwFlags & ECF_HIDELOCALTIME)
						CheckDlgButton(hWnd, IDC_SHOWLOCALTIME1, BST_UNCHECKED);
					else
						CheckDlgButton(hWnd, IDC_SHOWLOCALTIME1, BST_INDETERMINATE);

					if (bSecondLine == 0xff)
						SendDlgItemMessage(hWnd, IDC_SECONDLINEMODE, CB_SETCURSEL, 0, 0);
					else
						SendDlgItemMessage(hWnd, IDC_SECONDLINEMODE, CB_SETCURSEL, (WPARAM)(bSecondLine + 1), 0);
				}
			}
			WindowList_Add(hWindowListIGN, hWnd, hContact);
			ShowWindow(hWnd, SW_SHOWNORMAL);
		}
		return TRUE;

	case WM_COMMAND:
		switch (LOWORD(wParam)) {
		case IDC_IGN_PRIORITY:
			SendMessage(g_clistApi.hwndContactTree, CLM_TOGGLEPRIORITYCONTACT, hContact, 0);
			return 0;

		case IDC_IGN_ALL:
			SendMessage(hWnd, WM_USER + 100, hContact, (LPARAM)0xffffffff);
			return 0;

		case IDC_IGN_NONE:
			SendMessage(hWnd, WM_USER + 100, hContact, 0);
			return 0;

		case IDC_IGN_ALWAYSONLINE:
			if (IsDlgButtonChecked(hWnd, IDC_IGN_ALWAYSONLINE))
				CheckDlgButton(hWnd, IDC_IGN_ALWAYSOFFLINE, BST_UNCHECKED);
			break;

		case IDC_IGN_ALWAYSOFFLINE:
			if (IsDlgButtonChecked(hWnd, IDC_IGN_ALWAYSOFFLINE))
				CheckDlgButton(hWnd, IDC_IGN_ALWAYSONLINE, BST_UNCHECKED);
			break;

		case IDC_HIDECONTACT:
			db_set_b(hContact, "CList", "Hidden", (BYTE)(IsDlgButtonChecked(hWnd, IDC_HIDECONTACT) ? 1 : 0));
			break;

		case IDC_IGN_ADDPERMANENTLY:
			Contact_Add(hContact, hWnd);
			Utils::enableDlgControl(hWnd, IDC_IGN_ADDPERMANENTLY, db_get_b(hContact, "CList", "NotOnList", 0));
			break;

		case IDC_DSP_LOADDEFAULT:
			SendDlgItemMessage(hWnd, IDC_AVATARDISPMODE, CB_SETCURSEL, 0, 0);
			SendDlgItemMessage(hWnd, IDC_SECONDLINEMODE, CB_SETCURSEL, 0, 0);
			CheckDlgButton(hWnd, IDC_OVERLAYICON, BST_INDETERMINATE);
			CheckDlgButton(hWnd, IDC_LOCALTIME, BST_INDETERMINATE);
			break;

		case IDOK:
			{
				DWORD newMask = 0;
				ClcContact *contact = nullptr;

				SendMessage(hWnd, WM_USER + 110, 0, (LPARAM)&newMask);
				db_set_dw(hContact, "Ignore", "Mask1", newMask);
				SendMessage(hWnd, WM_USER + 130, 0, 0);

				if (cfg::clcdat) {
					LRESULT iSel = SendDlgItemMessage(hWnd, IDC_AVATARDISPMODE, CB_GETCURSEL, 0, 0);
					DWORD dwFlags = db_get_dw(hContact, "CList", "CLN_Flags", 0), dwXMask = 0;
					LRESULT  checked = 0;

					Clist_FindItem(g_clistApi.hwndContactTree, cfg::clcdat, hContact, &contact, nullptr, nullptr);
					if (iSel != CB_ERR) {
						dwFlags &= ~(ECF_FORCEAVATAR | ECF_HIDEAVATAR);

						if (iSel == 1)
							dwFlags |= ECF_FORCEAVATAR;
						else if (iSel == 2)
							dwFlags |= ECF_HIDEAVATAR;
						if (contact)
							LoadAvatarForContact(contact);
					}

					dwFlags &= ~(ECF_FORCEOVERLAY | ECF_HIDEOVERLAY | ECF_FORCELOCALTIME | ECF_HIDELOCALTIME);

					checked = IsDlgButtonChecked(hWnd, IDC_OVERLAYICON);
					if (checked == BST_CHECKED)
						dwFlags |= ECF_FORCEOVERLAY;
					else if (checked == BST_UNCHECKED)
						dwFlags |= ECF_HIDEOVERLAY;

					checked = IsDlgButtonChecked(hWnd, IDC_SHOWLOCALTIME1);
					if (checked == BST_CHECKED)
						dwFlags |= ECF_FORCELOCALTIME;
					else if (checked == BST_UNCHECKED)
						dwFlags |= ECF_HIDELOCALTIME;

					db_set_dw(hContact, "CList", "CLN_Flags", dwFlags);

					if ((iSel = SendDlgItemMessage(hWnd, IDC_SECONDLINEMODE, CB_GETCURSEL, 0, 0)) != CB_ERR) {
						if (iSel == 0) {
							db_unset(hContact, "CList", "CLN_2ndline");
							if (contact)
								contact->bSecondLine = cfg::dat.dualRowMode;
						}
						else {
							db_set_b(hContact, "CList", "CLN_2ndline", (BYTE)(iSel - 1));
							if (contact)
								contact->bSecondLine = (BYTE)(iSel - 1);
						}
					}
					db_set_dw(hContact, "CList", "CLN_xmask", dwXMask);
					if (contact) {
						if (contact->pExtra)
							contact->pExtra->dwDFlags = dwFlags;
					}
					else {
						TExtraCache *p = cfg::getCache(hContact, nullptr);
						if (p)
							p->dwDFlags = dwFlags;
					}
					db_set_b(hContact, "CList", "Priority", (BYTE)(IsDlgButtonChecked(hWnd, IDC_IGN_PRIORITY) ? 1 : 0));
					Clist_Broadcast(CLM_AUTOREBUILD, 0, 0);
				}
			}
		case IDCANCEL:
			DestroyWindow(hWnd);
			break;
		}
		break;

	case WM_USER + 100:	// fill dialog (wParam = hContact, lParam = mask)
		CheckDlgButton(hWnd, IDC_IGN_MSGEVENTS, lParam & (1 << (IGNOREEVENT_MESSAGE - 1)) ? BST_CHECKED : BST_UNCHECKED);
		CheckDlgButton(hWnd, IDC_IGN_FILEEVENTS, lParam & (1 << (IGNOREEVENT_FILE - 1)) ? BST_CHECKED : BST_UNCHECKED);
		CheckDlgButton(hWnd, IDC_IGN_URLEVENTS, lParam & (1 << (IGNOREEVENT_URL - 1)) ? BST_CHECKED : BST_UNCHECKED);
		CheckDlgButton(hWnd, IDC_IGN_AUTH, lParam & (1 << (IGNOREEVENT_AUTHORIZATION - 1)) ? BST_CHECKED : BST_UNCHECKED);
		CheckDlgButton(hWnd, IDC_IGN_ADD, lParam & (1 << (IGNOREEVENT_YOUWEREADDED - 1)) ? BST_CHECKED : BST_UNCHECKED);
		CheckDlgButton(hWnd, IDC_IGN_ONLINE, lParam & (1 << (IGNOREEVENT_USERONLINE - 1)) ? BST_CHECKED : BST_UNCHECKED);
		return 0;

	case WM_USER + 110:	// retrieve value
		{
			DWORD *dwNewMask = (DWORD *)lParam, dwMask = 0;
			dwMask = (IsDlgButtonChecked(hWnd, IDC_IGN_MSGEVENTS) ? (1 << (IGNOREEVENT_MESSAGE - 1)) : 0) |
				(IsDlgButtonChecked(hWnd, IDC_IGN_FILEEVENTS) ? (1 << (IGNOREEVENT_FILE - 1)) : 0) |
				(IsDlgButtonChecked(hWnd, IDC_IGN_URLEVENTS) ? (1 << (IGNOREEVENT_URL - 1)) : 0) |
				(IsDlgButtonChecked(hWnd, IDC_IGN_AUTH) ? (1 << (IGNOREEVENT_AUTHORIZATION - 1)) : 0) |
				(IsDlgButtonChecked(hWnd, IDC_IGN_ADD) ? (1 << (IGNOREEVENT_YOUWEREADDED - 1)) : 0) |
				(IsDlgButtonChecked(hWnd, IDC_IGN_ONLINE) ? (1 << (IGNOREEVENT_USERONLINE - 1)) : 0);

			if (dwNewMask)
				*dwNewMask = dwMask;
		}
		return 0;

	case WM_USER + 120:	// set visibility status
		{
			ClcContact *contact = nullptr;
			if (Clist_FindItem(g_clistApi.hwndContactTree, cfg::clcdat, hContact, &contact, nullptr, nullptr)) {
				if (contact) {
					WORD wApparentMode = db_get_w(contact->hContact, contact->proto, "ApparentMode", 0);

					CheckDlgButton(hWnd, IDC_IGN_ALWAYSOFFLINE, wApparentMode == ID_STATUS_OFFLINE ? BST_CHECKED : BST_UNCHECKED);
					CheckDlgButton(hWnd, IDC_IGN_ALWAYSONLINE, wApparentMode == ID_STATUS_ONLINE ? BST_CHECKED : BST_UNCHECKED);
				}
			}
		}
		return 0;

	case WM_USER + 130:	// update apparent mode
		{
			ClcContact *contact = nullptr;

			if (Clist_FindItem(g_clistApi.hwndContactTree, cfg::clcdat, hContact, &contact, nullptr, nullptr)) {
				if (contact) {
					WORD wApparentMode = 0;

					if (IsDlgButtonChecked(hWnd, IDC_IGN_ALWAYSONLINE))
						wApparentMode = ID_STATUS_ONLINE;
					else if (IsDlgButtonChecked(hWnd, IDC_IGN_ALWAYSOFFLINE))
						wApparentMode = ID_STATUS_OFFLINE;

					ProtoChainSend(hContact, PSS_SETAPPARENTMODE, (WPARAM)wApparentMode, 0);
					SendMessage(hWnd, WM_USER + 120, 0, 0);
				}
			}
		}
		return 0;

	case WM_DESTROY:
		SetWindowLongPtr(hWnd, GWLP_USERDATA, 0);
		WindowList_Remove(hWindowListIGN, hWnd);
		break;
	}
	return FALSE;
}
Example #28
0
INT_PTR CALLBACK DlgSkinOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg) {
	case WM_DESTROY:
		if (hPreviewBitmap)
			ske_UnloadGlyphImage(hPreviewBitmap);
		break;

	case WM_INITDIALOG:
		TranslateDialogDefault(hwndDlg);
		SetDlgItemText(hwndDlg, IDC_SKINFOLDERLABEL, SkinsFolder);
		{
			HTREEITEM it = FillAvailableSkinList(hwndDlg);
			TreeView_SelectItem(GetDlgItem(hwndDlg, IDC_TREE1), it);
		}
		return 0;

	case WM_COMMAND:
		switch (LOWORD(wParam)) {
		case IDC_COLOUR_MENUNORMAL:
		case IDC_COLOUR_MENUSELECTED:
		case IDC_COLOUR_FRAMES:
		case IDC_COLOUR_STATUSBAR:
			SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
			break;

		case IDC_BUTTON_INFO:
			{
				HTREEITEM hti = TreeView_GetSelection(GetDlgItem(hwndDlg, IDC_TREE1));
				if (hti == nullptr)
					return 0;

				TVITEM tvi = { 0 };
				tvi.hItem = hti;
				tvi.mask = TVIF_HANDLE | TVIF_PARAM;
				TreeView_GetItem(GetDlgItem(hwndDlg, IDC_TREE1), &tvi);
				SkinListData *sd = (SkinListData*)(tvi.lParam);
				if (!sd)
					return 0;

				wchar_t Author[255], URL[MAX_PATH], Contact[255], Description[400], text[2000];
				if (!wcschr(sd->File, '%')) {
					GetPrivateProfileString(L"Skin_Description_Section", L"Author", TranslateT("( unknown )"), Author, _countof(Author), sd->File);
					GetPrivateProfileString(L"Skin_Description_Section", L"URL", L"", URL, _countof(URL), sd->File);
					GetPrivateProfileString(L"Skin_Description_Section", L"Contact", L"", Contact, _countof(Contact), sd->File);
					GetPrivateProfileString(L"Skin_Description_Section", L"Description", L"", Description, _countof(Description), sd->File);
					mir_snwprintf(text, TranslateT("%s\n\n%s\n\nAuthor(s):\t %s\nContact:\t %s\nWeb:\t %s\n\nFile:\t %s"),
						sd->Name, Description, Author, Contact, URL, sd->File);
				}
				else {
					mir_snwprintf(text, TranslateT("%s\n\n%s\n\nAuthor(s): %s\nContact:\t %s\nWeb:\t %s\n\nFile:\t %s"),
						TranslateT("reVista for Modern v0.5"),
						TranslateT("This is second default Modern Contact list skin in Vista Aero style"),
						TranslateT("Angeli-Ka (graphics), FYR (template)"),
						L"JID: [email protected]",
						L"fyr.mirandaim.ru",
						TranslateT("Inside library"));
				}
				MessageBox(hwndDlg, text, TranslateT("Skin information"), MB_OK | MB_ICONINFORMATION);
			}
			break;

		case IDC_BUTTON_APPLY_SKIN:
			if (HIWORD(wParam) == BN_CLICKED) {
				HTREEITEM hti = TreeView_GetSelection(GetDlgItem(hwndDlg, IDC_TREE1));
				if (hti == nullptr)
					return 0;

				TVITEM tvi = { 0 };
				tvi.hItem = hti;
				tvi.mask = TVIF_HANDLE | TVIF_PARAM;
				TreeView_GetItem(GetDlgItem(hwndDlg, IDC_TREE1), &tvi);
				SkinListData *sd = (SkinListData*)(tvi.lParam);
				if (!sd)
					return 0;

				ske_LoadSkinFromIniFile(sd->File, FALSE);
				ske_LoadSkinFromDB();
				Clist_Broadcast(INTM_RELOADOPTIONS, 0, 0);
				Sync(CLUIFrames_OnClistResize_mod, 0, 0);
				ske_RedrawCompleteWindow();
				Sync(CLUIFrames_OnClistResize_mod, 0, 0);

				RECT rc = {};
				GetWindowRect(g_clistApi.hwndContactList, &rc);
				Sync(CLUIFrames_OnMoving, g_clistApi.hwndContactList, &rc);

				if (g_hCLUIOptionsWnd) {
					SendDlgItemMessage(g_hCLUIOptionsWnd, IDC_LEFTMARGINSPIN, UDM_SETPOS, 0, db_get_b(0, "CLUI", "LeftClientMargin", SETTING_LEFTCLIENTMARIGN_DEFAULT));
					SendDlgItemMessage(g_hCLUIOptionsWnd, IDC_RIGHTMARGINSPIN, UDM_SETPOS, 0, db_get_b(0, "CLUI", "RightClientMargin", SETTING_RIGHTCLIENTMARIGN_DEFAULT));
					SendDlgItemMessage(g_hCLUIOptionsWnd, IDC_TOPMARGINSPIN, UDM_SETPOS, 0, db_get_b(0, "CLUI", "TopClientMargin", SETTING_TOPCLIENTMARIGN_DEFAULT));
					SendDlgItemMessage(g_hCLUIOptionsWnd, IDC_BOTTOMMARGINSPIN, UDM_SETPOS, 0, db_get_b(0, "CLUI", "BottomClientMargin", SETTING_BOTTOMCLIENTMARIGN_DEFAULT));
				}
			}
			break;

		case IDC_GETSKINS:
			if (HIWORD(wParam) == BN_CLICKED)
				Utils_OpenUrl("https://miranda-ng.org/addons/category/17");
			break;


		case IDC_BUTTON_RESCAN:
			if (HIWORD(wParam) == BN_CLICKED) {
				HTREEITEM it = FillAvailableSkinList(hwndDlg);
				HWND wnd = GetDlgItem(hwndDlg, IDC_TREE1);
				TreeView_SelectItem(wnd, it);
			}
		}
		break;

	case WM_DRAWITEM:
		if (wParam == IDC_PREVIEW) {
			// TODO:Draw hPreviewBitmap here
			HBRUSH hbr = CreateSolidBrush(GetSysColor(COLOR_3DFACE));
			DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT*)lParam;
			int mWidth = dis->rcItem.right - dis->rcItem.left;
			int mHeight = dis->rcItem.bottom - dis->rcItem.top;
			HDC memDC = CreateCompatibleDC(dis->hDC);
			HBITMAP hbmp = ske_CreateDIB32(mWidth, mHeight);
			HBITMAP holdbmp = (HBITMAP)SelectObject(memDC, hbmp);
			RECT workRect = dis->rcItem;
			OffsetRect(&workRect, -workRect.left, -workRect.top);
			FillRect(memDC, &workRect, hbr);
			DeleteObject(hbr);
			if (hPreviewBitmap) {
				// variables
				BITMAP bmp = {};
				GetObject(hPreviewBitmap, sizeof(bmp), &bmp);

				// GetSize
				float xScale = 1, yScale = 1;
				int wWidth = workRect.right - workRect.left;
				int wHeight = workRect.bottom - workRect.top;
				if (wWidth < bmp.bmWidth)
					xScale = (float)wWidth / bmp.bmWidth;
				if (wHeight < bmp.bmHeight)
					yScale = (float)wHeight / bmp.bmHeight;
				xScale = min(xScale, yScale);
				yScale = xScale;
				int dWidth = (int)(xScale*bmp.bmWidth);
				int dHeight = (int)(yScale*bmp.bmHeight);
				
				// CalcPosition
				POINT imgPos = { 0 };
				imgPos.x = workRect.left + ((wWidth - dWidth) >> 1);
				imgPos.y = workRect.top + ((wHeight - dHeight) >> 1);
				
				// DrawImage
				DrawAvatarImageWithGDIp(memDC, imgPos.x, imgPos.y, dWidth, dHeight, hPreviewBitmap, 0, 0, bmp.bmWidth, bmp.bmHeight, 8, 255);
			}
			BitBlt(dis->hDC, dis->rcItem.left, dis->rcItem.top, mWidth, mHeight, memDC, 0, 0, SRCCOPY);
			SelectObject(memDC, holdbmp);
			DeleteObject(hbmp);
			DeleteDC(memDC);
		}
		break;

	case WM_NOTIFY:
		switch (((LPNMHDR)lParam)->idFrom) {
		case 0:
			if (((LPNMHDR)lParam)->code == PSN_APPLY) {
				Clist_Broadcast(INTM_RELOADOPTIONS, 0, 0);
				NotifyEventHooks(g_CluiData.hEventBkgrChanged, 0, 0);
				Clist_Broadcast(INTM_INVALIDATE, 0, 0);
				RedrawWindow(GetParent(g_clistApi.hwndContactTree), nullptr, nullptr, RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
			}
			break;

		case IDC_TREE1:
			NMTREEVIEW *nmtv = (NMTREEVIEW*)lParam;
			if (nmtv == nullptr)
				return 0;

			if (nmtv->hdr.code == TVN_SELCHANGED) {
				if (hPreviewBitmap) {
					ske_UnloadGlyphImage(hPreviewBitmap);
					hPreviewBitmap = nullptr;
				}

				if (nmtv->itemNew.lParam) {
					SkinListData *sd = (SkinListData*)nmtv->itemNew.lParam;

					wchar_t buf[MAX_PATH];
					PathToRelativeW(sd->File, buf);
					SetDlgItemText(hwndDlg, IDC_EDIT_SKIN_FILENAME, buf);

					wchar_t prfn[MAX_PATH] = { 0 }, imfn[MAX_PATH] = { 0 }, skinfolder[MAX_PATH] = { 0 };
					GetPrivateProfileString(L"Skin_Description_Section", L"Preview", L"", imfn, _countof(imfn), sd->File);
					IniParser::GetSkinFolder(sd->File, skinfolder);
					mir_snwprintf(prfn, L"%s\\%s", skinfolder, imfn);
					PathToAbsoluteW(prfn, imfn);
					hPreviewBitmap = ske_LoadGlyphImage(imfn);

					EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON_APPLY_SKIN), TRUE);
					EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON_INFO), TRUE);
					if (hPreviewBitmap)
						InvalidateRect(GetDlgItem(hwndDlg, IDC_PREVIEW), nullptr, TRUE);
					else { // prepare text
						HTREEITEM hti = TreeView_GetSelection(GetDlgItem(hwndDlg, IDC_TREE1));
						if (hti == nullptr)
							return 0;

						TVITEM tvi = { 0 };
						tvi.hItem = hti;
						tvi.mask = TVIF_HANDLE | TVIF_PARAM;
						TreeView_GetItem(GetDlgItem(hwndDlg, IDC_TREE1), &tvi);
						SkinListData *sd2 = (SkinListData*)(tvi.lParam);
						if (!sd2)
							return 0;

						wchar_t Author[255], URL[MAX_PATH], Contact[255], Description[400], text[2000];
						if (!wcschr(sd2->File, '%')) {
							GetPrivateProfileString(L"Skin_Description_Section", L"Author", TranslateT("( unknown )"), Author, _countof(Author), sd2->File);
							GetPrivateProfileString(L"Skin_Description_Section", L"URL", L"", URL, _countof(URL), sd2->File);
							GetPrivateProfileString(L"Skin_Description_Section", L"Contact", L"", Contact, _countof(Contact), sd2->File);
							GetPrivateProfileString(L"Skin_Description_Section", L"Description", L"", Description, _countof(Description), sd2->File);
							mir_snwprintf(text, TranslateT("Preview is not available\n\n%s\n----------------------\n\n%s\n\nAUTHOR(S):\n%s\n\nCONTACT:\n%s\n\nHOMEPAGE:\n%s"),
								sd2->Name, Description, Author, Contact, URL);
						}
						else {
							mir_snwprintf(text, TranslateT("%s\n\n%s\n\nAUTHORS:\n%s\n\nCONTACT:\n%s\n\nWEB:\n%s\n\n\n"),
								TranslateT("reVista for Modern v0.5"),
								TranslateT("This is second default Modern Contact list skin in Vista Aero style"),
								TranslateT("graphics by Angeli-Ka\ntemplate by FYR"),
								L"JID: [email protected]",
								L"fyr.mirandaim.ru");
						}
						ShowWindow(GetDlgItem(hwndDlg, IDC_PREVIEW), SW_HIDE);
						ShowWindow(GetDlgItem(hwndDlg, IDC_STATIC_INFO), SW_SHOW);
						SetDlgItemText(hwndDlg, IDC_STATIC_INFO, text);
					}
				}
				else {
					// no selected
					SetDlgItemText(hwndDlg, IDC_EDIT_SKIN_FILENAME, TranslateT("Select skin from list"));
					EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON_APPLY_SKIN), FALSE);
					EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON_INFO), FALSE);
					SetDlgItemText(hwndDlg, IDC_STATIC_INFO, TranslateT("Please select skin to apply"));
					ShowWindow(GetDlgItem(hwndDlg, IDC_PREVIEW), SW_HIDE);
				}
				ShowWindow(GetDlgItem(hwndDlg, IDC_PREVIEW), hPreviewBitmap ? SW_SHOW : SW_HIDE);
				return 0;
			}
			else if (nmtv->hdr.code == TVN_DELETEITEM) {
				mir_free_and_nil(nmtv->itemOld.lParam);
				return 0;
			}
			break;
		}
	}