/* Miranda IM: the free IM client for Microsoft* Windows* Copyright 2000-2009 Miranda ICQ/IM project, all portions of this codebase are copyrighted to the people listed in contributors.txt. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "..\..\core\commonheaders.h" #include "clc.h" static INT_PTR GetHwnd(WPARAM, LPARAM) { return (INT_PTR)cli.hwndContactList; } static INT_PTR GetHwndTree(WPARAM, LPARAM) { return (INT_PTR)cli.hwndContactTree; } static INT_PTR CluiProtocolStatusChanged(WPARAM wParam, LPARAM lParam) { cli.pfnCluiProtocolStatusChanged( wParam, (const char*)lParam ); return 0; } INT_PTR SortList(WPARAM, LPARAM) { //unnecessary: CLC does this automatically return 0; } static INT_PTR GroupAdded(WPARAM wParam, LPARAM lParam) { //CLC does this automatically unless it's a new group if (lParam) { HANDLE hItem; TCHAR szFocusClass[64]; HWND hwndFocus = GetFocus(); GetClassName(hwndFocus, szFocusClass, SIZEOF(szFocusClass)); if (!lstrcmp(szFocusClass, CLISTCONTROL_CLASS)) { hItem = (HANDLE) SendMessage(hwndFocus, CLM_FINDGROUP, wParam, 0); if (hItem) SendMessage(hwndFocus, CLM_EDITLABEL, (WPARAM) hItem, 0); } } return 0; } static INT_PTR ContactSetIcon(WPARAM, LPARAM) { //unnecessary: CLC does this automatically return 0; } static INT_PTR ContactDeleted(WPARAM, LPARAM) { //unnecessary: CLC does this automatically return 0; } static INT_PTR ContactAdded(WPARAM, LPARAM) { //unnecessary: CLC does this automatically return 0; } static INT_PTR ListBeginRebuild(WPARAM, LPARAM) { //unnecessary: CLC does this automatically return 0; } static INT_PTR ListEndRebuild(WPARAM, LPARAM) { int rebuild = 0; //CLC does this automatically, but we need to force it if hideoffline or hideempty has changed if ((DBGetContactSettingByte(NULL, "CList", "HideOffline", SETTING_HIDEOFFLINE_DEFAULT) == 0) != ((GetWindowLongPtr(cli.hwndContactTree, GWL_STYLE) & CLS_HIDEOFFLINE) == 0)) { if (DBGetContactSettingByte(NULL, "CList", "HideOffline", SETTING_HIDEOFFLINE_DEFAULT)) SetWindowLongPtr(cli.hwndContactTree, GWL_STYLE, GetWindowLongPtr(cli.hwndContactTree, GWL_STYLE) | CLS_HIDEOFFLINE); else SetWindowLongPtr(cli.hwndContactTree, GWL_STYLE, GetWindowLongPtr(cli.hwndContactTree, GWL_STYLE) & ~CLS_HIDEOFFLINE); rebuild = 1; } if ((DBGetContactSettingByte(NULL, "CList", "HideEmptyGroups", SETTING_HIDEEMPTYGROUPS_DEFAULT) == 0) != ((GetWindowLongPtr(cli.hwndContactTree, GWL_STYLE) & CLS_HIDEEMPTYGROUPS) == 0)) { if (DBGetContactSettingByte(NULL, "CList", "HideEmptyGroups", SETTING_HIDEEMPTYGROUPS_DEFAULT)) SetWindowLongPtr(cli.hwndContactTree, GWL_STYLE, GetWindowLongPtr(cli.hwndContactTree, GWL_STYLE) | CLS_HIDEEMPTYGROUPS); else SetWindowLongPtr(cli.hwndContactTree, GWL_STYLE, GetWindowLongPtr(cli.hwndContactTree, GWL_STYLE) & ~CLS_HIDEEMPTYGROUPS); rebuild = 1; } if ((DBGetContactSettingByte(NULL, "CList", "UseGroups", SETTING_USEGROUPS_DEFAULT) == 0) != ((GetWindowLongPtr(cli.hwndContactTree, GWL_STYLE) & CLS_USEGROUPS) == 0)) { if (DBGetContactSettingByte(NULL, "CList", "UseGroups", SETTING_USEGROUPS_DEFAULT)) SetWindowLongPtr(cli.hwndContactTree, GWL_STYLE, GetWindowLongPtr(cli.hwndContactTree, GWL_STYLE) | CLS_USEGROUPS); else SetWindowLongPtr(cli.hwndContactTree, GWL_STYLE, GetWindowLongPtr(cli.hwndContactTree, GWL_STYLE) & ~CLS_USEGROUPS); rebuild = 1; } if (rebuild) SendMessage(cli.hwndContactTree, CLM_AUTOREBUILD, 0, 0); return 0; } static INT_PTR ContactRenamed(WPARAM, LPARAM) { //unnecessary: CLC does this automatically return 0; } static INT_PTR GetCaps(WPARAM wParam, LPARAM) { switch (wParam) { case CLUICAPS_FLAGS1: return CLUIF_HIDEEMPTYGROUPS | CLUIF_DISABLEGROUPS | CLUIF_HASONTOPOPTION | CLUIF_HASAUTOHIDEOPTION; } return 0; } void LoadCluiServices(void) { CreateServiceFunction(MS_CLUI_GETHWND, GetHwnd); CreateServiceFunction(MS_CLUI_GETHWNDTREE, GetHwndTree); CreateServiceFunction(MS_CLUI_PROTOCOLSTATUSCHANGED, CluiProtocolStatusChanged); CreateServiceFunction(MS_CLUI_GROUPADDED, GroupAdded); CreateServiceFunction(MS_CLUI_CONTACTSETICON, ContactSetIcon); CreateServiceFunction(MS_CLUI_CONTACTADDED, ContactAdded); CreateServiceFunction(MS_CLUI_CONTACTDELETED, ContactDeleted); CreateServiceFunction(MS_CLUI_CONTACTRENAMED, ContactRenamed); CreateServiceFunction(MS_CLUI_LISTBEGINREBUILD, ListBeginRebuild); CreateServiceFunction(MS_CLUI_LISTENDREBUILD, ListEndRebuild); CreateServiceFunction(MS_CLUI_SORTLIST, SortList); CreateServiceFunction(MS_CLUI_GETCAPS, GetCaps); } ///////////////////////////////////////////////////////////////////////////////////////// // default protocol status notification handler void fnCluiProtocolStatusChanged(int, const char* ) { int i, *partWidths; int borders[3]; int flags = 0; if ( cli.menuProtoCount == 0 ) { SendMessage(cli.hwndStatus, SB_SETPARTS, 0, 0); SendMessage( cli.hwndStatus, SB_SETTEXT, SBT_OWNERDRAW, 0 ); return; } SendMessage(cli.hwndStatus, SB_GETBORDERS, 0, ( LPARAM )&borders); partWidths = ( int* )alloca( cli.menuProtoCount * sizeof( int )); if ( DBGetContactSettingByte( NULL, "CLUI", "EqualSections", 0 )) { RECT rc; GetClientRect( cli.hwndStatus, &rc ); rc.right -= borders[0] * 2 + ( DBGetContactSettingByte( NULL, "CLUI", "ShowGrip", 1 ) ? GetSystemMetrics( SM_CXVSCROLL ) : 0 ); for ( i = 0; i < cli.menuProtoCount; i++ ) partWidths[ i ] = ( i+1 ) * rc.right / cli.menuProtoCount - (borders[2] >> 1); } else { HDC hdc; SIZE textSize; BYTE showOpts = DBGetContactSettingByte(NULL, "CLUI", "SBarShow", 1); hdc = GetDC(NULL); SelectObject(hdc, (HFONT) SendMessage(cli.hwndStatus, WM_GETFONT, 0, 0)); for ( i = 0; i < cli.menuProtoCount; i++ ) { //count down since built in ones tend to go at the end int x = 2; if ( showOpts & 1 ) x += g_IconWidth; if ( showOpts & 2 ) { TCHAR tszName[64]; PROTOACCOUNT* pa = Proto_GetAccount( cli.menuProtos[i].szProto ); if ( pa ) mir_sntprintf( tszName, SIZEOF(tszName), _T("%s "), pa->tszAccountName ); else tszName[0] = 0; if ( showOpts & 4 && lstrlen(tszName) < SIZEOF(tszName)-1 ) lstrcat( tszName, _T(" ")); GetTextExtentPoint32(hdc, tszName, lstrlen(tszName), &textSize); x += textSize.cx; x += GetSystemMetrics(SM_CXBORDER) * 4; // The SB panel doesnt allocate enough room } if ( showOpts & 4 ) { TCHAR* modeDescr = cli.pfnGetStatusModeDescription( CallProtoService( cli.menuProtos[i].szProto, PS_GETSTATUS, 0, 0), 0 ); GetTextExtentPoint32(hdc, modeDescr, lstrlen(modeDescr), &textSize); x += textSize.cx; x += GetSystemMetrics(SM_CXBORDER) * 4; // The SB panel doesnt allocate enough room } partWidths[ i ] = ( i ? partWidths[ i-1] : 0 ) + x + 2; } ReleaseDC(NULL, hdc); } partWidths[ cli.menuProtoCount-1 ] = -1; SendMessage(cli.hwndStatus, SB_SETMINHEIGHT, g_IconHeight, 0); SendMessage(cli.hwndStatus, SB_SETPARTS, cli.menuProtoCount, ( LPARAM )partWidths); flags = SBT_OWNERDRAW; if ( DBGetContactSettingByte( NULL, "CLUI", "SBarBevel", 1 ) == 0 ) flags |= SBT_NOBORDERS; for ( i = 0; i < cli.menuProtoCount; i++ ) { SendMessage( cli.hwndStatus, SB_SETTEXT, i | flags, ( LPARAM )cli.menuProtos[i].szProto ); } }