From 8d284bebe3c2392680949c06bbd17253960ce0f8 Mon Sep 17 00:00:00 2001 From: Kirill Volinsky Date: Wed, 1 Aug 2012 05:54:33 +0000 Subject: git-svn-id: http://svn.miranda-ng.org/main/trunk@1295 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/Clist_nicer/src/cluiservices.cpp | 261 +++++++++++++++++++++++++++++++ 1 file changed, 261 insertions(+) create mode 100644 plugins/Clist_nicer/src/cluiservices.cpp (limited to 'plugins/Clist_nicer/src/cluiservices.cpp') diff --git a/plugins/Clist_nicer/src/cluiservices.cpp b/plugins/Clist_nicer/src/cluiservices.cpp new file mode 100644 index 0000000000..d446872f16 --- /dev/null +++ b/plugins/Clist_nicer/src/cluiservices.cpp @@ -0,0 +1,261 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2003 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +UNICODE done + +*/ +#include +#include "../cluiframes/cluiframes.h" +#include + +extern HIMAGELIST hCListImages, himlExtraImages;; +extern ButtonItem *g_ButtonItems; +extern PLUGININFOEX pluginInfo; + +static INT_PTR GetClistVersion(WPARAM wParam, LPARAM lParam) +{ + static char g_szVersionString[256]; + + mir_snprintf(g_szVersionString, 256, "%s, %d.%d.%d.%d", pluginInfo.shortName, HIBYTE(HIWORD(pluginInfo.version)), LOBYTE(HIWORD(pluginInfo.version)), HIBYTE(LOWORD(pluginInfo.version)), LOBYTE(LOBYTE(pluginInfo.version))); + if (!IsBadWritePtr((LPVOID)lParam, 4)) + *((DWORD *)lParam) = pluginInfo.version; + + return (INT_PTR)g_szVersionString; +} + + +void FreeProtocolData( void ) +{ + //free protocol data + int nPanel; + int nParts=SendMessage(pcli->hwndStatus,SB_GETPARTS,0,0); + for (nPanel=0;nPanelhwndStatus,SB_GETTEXT,(WPARAM)nPanel,(LPARAM)0); + if (PD!=NULL&&!IsBadCodePtr((FARPROC)PD)) + { + SendMessage(pcli->hwndStatus,SB_SETTEXT,(WPARAM)nPanel|SBT_OWNERDRAW,(LPARAM)0); + if (PD->RealName) mir_free(PD->RealName); + if (PD) mir_free(PD); +} } } + +int g_maxStatus = ID_STATUS_OFFLINE; +char g_maxProto[100] = ""; + +void CluiProtocolStatusChanged( int parStatus, const char* szProto ) +{ + int protoCount,i; + PROTOACCOUNT **accs; + int *partWidths,partCount; + int borders[3]; + int status; + int toshow; + TCHAR *szStatus = NULL; + char *szMaxProto = NULL; + int maxOnline = 0, onlineness = 0; + WORD maxStatus = ID_STATUS_OFFLINE, wStatus; + DBVARIANT dbv = {0}; + int iIcon = 0; + HICON hIcon = 0; + int rdelta = cfg::dat.bCLeft + cfg::dat.bCRight; + BYTE windowStyle; + + if (pcli->hwndStatus == 0 || cfg::shutDown) + return; + + ProtoEnumAccounts( &protoCount, &accs ); + if (protoCount == 0) + return; + + FreeProtocolData(); + g_maxStatus = ID_STATUS_OFFLINE; + g_maxProto[0] = 0; + + SendMessage(pcli->hwndStatus,SB_GETBORDERS,0,(LPARAM)&borders); + + partWidths=(int*)_alloca(( protoCount+1)*sizeof(int)); + + if (cfg::dat.bEqualSections) { + RECT rc; + int part; + //SendMessage(pcli->hwndStatus,WM_SIZE,0,0); // XXX fix (may break status bar geometry) + GetClientRect(pcli->hwndStatus,&rc); + rc.right-=borders[0]*2; + toshow=0; + for ( i=0; i < protoCount; i++ ) + if ( pcli->pfnGetProtocolVisibility( accs[i]->szModuleName )) + toshow++; + + if ( toshow > 0 ) { + for ( part=0, i=0; i < protoCount; i++ ) { + if ( !pcli->pfnGetProtocolVisibility( accs[i]->szModuleName )) + continue; + + partWidths[ part ] = ((rc.right-rc.left-rdelta)/toshow)*(part+1) + cfg::dat.bCLeft; + if ( part == toshow-1 ) + partWidths[ part ] += cfg::dat.bCRight; + part++; + } } + + partCount=toshow; + } + else { + HDC hdc; + SIZE textSize; + BYTE showOpts = cfg::getByte("CLUI","SBarShow",1); + int x; + HFONT hofont; + TCHAR szName[32]; + PROTOACCOUNT* pa; + + hdc=GetDC(NULL); + hofont = reinterpret_cast(SelectObject(hdc,(HFONT)SendMessage(pcli->hwndStatus,WM_GETFONT,0,0))); + + for ( partCount=0,i=0; i < protoCount; i++ ) { //count down since built in ones tend to go at the end + int idx = pcli->pfnGetAccountIndexByPos( i ); + if ( idx == -1 ) + continue; + + pa = accs[idx]; + if ( !pcli->pfnGetProtocolVisibility( pa->szModuleName )) + continue; + + x=2; + if (showOpts & 1) + x += 16; + if (showOpts & 2) { + lstrcpyn( szName, pa->tszAccountName, SIZEOF(szName)); + szName[ SIZEOF(szName)-1 ] = 0; + if (( showOpts & 4 ) && lstrlen(szName) < sizeof(szName)-1 ) + lstrcat( szName, _T(" ")); + GetTextExtentPoint32( hdc, szName, lstrlen(szName), &textSize ); + x += textSize.cx + GetSystemMetrics(SM_CXBORDER) * 4; // The SB panel doesnt allocate enough room + } + if (showOpts & 4) { + TCHAR* modeDescr = pcli->pfnGetStatusModeDescription( CallProtoService(accs[i]->szModuleName,PS_GETSTATUS,0,0 ), 0 ); + GetTextExtentPoint32(hdc, modeDescr, lstrlen(modeDescr), &textSize ); + x += textSize.cx + GetSystemMetrics(SM_CXBORDER) * 4; // The SB panel doesnt allocate enough room + } + partWidths[partCount]=(partCount?partWidths[partCount-1]:cfg::dat.bCLeft)+ x + 2; + partCount++; + } + SelectObject(hdc,hofont); + ReleaseDC(NULL,hdc); + } + if (partCount==0) { + SendMessage(pcli->hwndStatus,SB_SIMPLE,TRUE,0); + return; + } + SendMessage(pcli->hwndStatus,SB_SIMPLE,FALSE,0); + + partWidths[partCount-1]=-1; + windowStyle = cfg::getByte("CLUI", "WindowStyle", 0); + SendMessage(pcli->hwndStatus,SB_SETMINHEIGHT, 18 + cfg::dat.bClipBorder + ((windowStyle == SETTING_WINDOWSTYLE_THINBORDER || windowStyle == SETTING_WINDOWSTYLE_NOBORDER) ? 3 : 0), 0); + SendMessage(pcli->hwndStatus, SB_SETPARTS, partCount, (LPARAM)partWidths); + + for ( partCount=0, i=0; i < protoCount; i++ ) { //count down since built in ones tend to go at the end + ProtocolData *PD; + PROTOACCOUNT *pa; + int caps1, caps2; + + int idx = pcli->pfnGetAccountIndexByPos( i ); + if ( idx == -1 ) + continue; + + pa = accs[idx]; + if ( !pcli->pfnGetProtocolVisibility( pa->szModuleName )) + continue; + + status = CallProtoService( pa->szModuleName,PS_GETSTATUS,0,0); + PD = ( ProtocolData* )mir_alloc(sizeof(ProtocolData)); + PD->RealName = mir_strdup( pa->szModuleName ); + PD->statusbarpos = partCount; + { + int flags; + flags = SBT_OWNERDRAW; + if ( cfg::getByte("CLUI","SBarBevel", 1)==0 ) + flags |= SBT_NOBORDERS; + SendMessageA( pcli->hwndStatus, SB_SETTEXTA, partCount|flags,(LPARAM)PD ); + } + caps2 = CallProtoService(pa->szModuleName, PS_GETCAPS, PFLAGNUM_2, 0); + caps1 = CallProtoService(pa->szModuleName, PS_GETCAPS, PFLAGNUM_1, 0); + if ((caps1 & PF1_IM) && (caps2 & (PF2_LONGAWAY | PF2_SHORTAWAY))) { + onlineness = GetStatusOnlineness(status); + if(onlineness > maxOnline) { + maxStatus = status; + maxOnline = onlineness; + szMaxProto = pa->szModuleName; + } + } + partCount++; + } + // update the clui button + + if (!DBGetContactSetting(NULL, "CList", "PrimaryStatus", &dbv)) { + if (dbv.type == DBVT_ASCIIZ && lstrlenA(dbv.pszVal) > 1) { + wStatus = (WORD) CallProtoService(dbv.pszVal, PS_GETSTATUS, 0, 0); + iIcon = IconFromStatusMode(dbv.pszVal, (int) wStatus, 0, &hIcon); + } + mir_free(dbv.pszVal); + } else { + wStatus = maxStatus; + iIcon = IconFromStatusMode((wStatus >= ID_STATUS_CONNECTING && wStatus < ID_STATUS_OFFLINE) ? szMaxProto : NULL, (int) wStatus, 0, &hIcon); + g_maxStatus = (int)wStatus; + if(szMaxProto) { + lstrcpynA(g_maxProto, szMaxProto, 100); + g_maxProto[99] = 0; + } + } + /* + * this is used globally (actually, by the clist control only) to determine if + * any protocol is "in connection" state. If true, then the clist discards redraws + * and uses timer based sort and redraw handling. This can improve performance + * when connecting multiple protocols significantly. + */ + //g_isConnecting = (wStatus >= ID_STATUS_CONNECTING && wStatus < ID_STATUS_OFFLINE); + szStatus = (TCHAR *)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM) wStatus, GSMDF_TCHAR); + + /* + * set the global status icon and display the global (most online) status mode on the + * status mode button + */ + + if (szStatus) { + if(pcli->hwndContactList && IsWindow(GetDlgItem(pcli->hwndContactList, IDC_TBGLOBALSTATUS)) && IsWindow(GetDlgItem(pcli->hwndContactList, IDC_TBTOPSTATUS))) { + SendMessage(GetDlgItem(pcli->hwndContactList, IDC_TBGLOBALSTATUS), WM_SETTEXT, 0, (LPARAM) szStatus); + if (!hIcon) { + SendMessage(GetDlgItem(pcli->hwndContactList, IDC_TBGLOBALSTATUS), BUTTONSETIMLICON, (WPARAM) hCListImages, (LPARAM) iIcon); + if(g_ButtonItems == NULL) + SendMessage(GetDlgItem(pcli->hwndContactList, IDC_TBTOPSTATUS), BUTTONSETIMLICON, (WPARAM) hCListImages, (LPARAM) iIcon); + } + else { + SendMessage(GetDlgItem(pcli->hwndContactList, IDC_TBGLOBALSTATUS), BM_SETIMAGE, IMAGE_ICON, (LPARAM) hIcon); + if(g_ButtonItems == NULL) + SendMessage(GetDlgItem(pcli->hwndContactList, IDC_TBTOPSTATUS), BM_SETIMAGE, IMAGE_ICON, (LPARAM) hIcon); + } + InvalidateRect(GetDlgItem(pcli->hwndContactList, IDC_TBGLOBALSTATUS), NULL, TRUE); + InvalidateRect(GetDlgItem(pcli->hwndContactList, IDC_TBTOPSTATUS), NULL, TRUE); + SFL_Update(hIcon, iIcon, hCListImages, szStatus, TRUE); + } } + return; +} -- cgit v1.2.3