From 48540940b6c28bb4378abfeb500ec45a625b37b6 Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Tue, 15 May 2012 10:38:20 +0000 Subject: initial commit git-svn-id: http://svn.miranda-ng.org/main/trunk@2 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/JabberG/jabber_privacy.cpp | 2332 ++++++++++++++++++++++++++++++++++ 1 file changed, 2332 insertions(+) create mode 100644 protocols/JabberG/jabber_privacy.cpp (limited to 'protocols/JabberG/jabber_privacy.cpp') diff --git a/protocols/JabberG/jabber_privacy.cpp b/protocols/JabberG/jabber_privacy.cpp new file mode 100644 index 0000000000..f6c1514c29 --- /dev/null +++ b/protocols/JabberG/jabber_privacy.cpp @@ -0,0 +1,2332 @@ +/* + +Jabber Protocol Plugin for Miranda IM +Copyright ( C ) 2002-04 Santithorn Bunchua +Copyright ( C ) 2005-11 George Hazan +Copyright ( C ) 2007-09 Maxim Mluhov +Copyright ( C ) 2007-09 Victor Pavlychko + +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. + +Revision : $Revision: 13869 $ +Last change on : $Date: 2011-09-16 01:42:09 +0300 (Пт, 16 сен 2011) $ +Last change by : $Author: george.hazan $ + +*/ + +#include "jabber.h" +#include "jabber_iq.h" +#include "jabber_privacy.h" + +#include +#include +#include + +#define JABBER_PL_BUSY_MSG "Sending request, please wait..." + +BOOL CJabberProto::OnIqRequestPrivacyLists( HXML, CJabberIqInfo* pInfo ) +{ + if ( pInfo->GetIqType() == JABBER_IQ_TYPE_SET ) { + if ( !m_pDlgPrivacyLists ) + { + m_privacyListManager.RemoveAllLists(); + QueryPrivacyLists(); + } + else m_pDlgPrivacyLists->SetStatusText(TranslateT("Warning: privacy lists were changed on server.")); + + XmlNodeIq iq( _T("result"), pInfo ); + m_ThreadInfo->send( iq ); + } + return TRUE; +} + +void CJabberProto::OnIqResultPrivacyListModify( HXML, CJabberIqInfo* pInfo ) +{ + if ( !pInfo->m_pUserData ) + return; + + CPrivacyListModifyUserParam *pParam = ( CPrivacyListModifyUserParam * )pInfo->m_pUserData; + + if ( pInfo->m_nIqType != JABBER_IQ_TYPE_RESULT ) + pParam->m_bAllOk = FALSE; + + InterlockedDecrement( &pParam->m_dwCount ); + if ( !pParam->m_dwCount ) { + TCHAR szText[ 512 ]; + if ( !pParam->m_bAllOk ) + mir_sntprintf( szText, SIZEOF( szText ), TranslateT("Error occurred while applying changes")); + else + mir_sntprintf( szText, SIZEOF( szText ), TranslateT("Privacy lists successfully saved")); + if (m_pDlgPrivacyLists) + m_pDlgPrivacyLists->SetStatusText( szText ); + // FIXME: enable apply button + delete pParam; + } +} + +void CJabberProto::OnIqResultPrivacyList( HXML iqNode ) +{ + if ( !iqNode ) + return; + + const TCHAR *type = xmlGetAttrValue( iqNode, _T("type")); + if ( !type ) + return; + + if ( !_tcscmp( type, _T("result"))) { + HXML query = xmlGetChild( iqNode , "query" ); + if ( !query ) + return; + HXML list = xmlGetChild( query , "list" ); + if ( !list ) + return; + TCHAR *szListName = ( TCHAR* )xmlGetAttrValue( list, _T("name")); + if ( !szListName ) + return; + m_privacyListManager.Lock(); + CPrivacyList* pList = m_privacyListManager.FindList( szListName ); + if ( !pList ) { + m_privacyListManager.AddList( szListName ); + pList = m_privacyListManager.FindList( szListName ); + if ( !pList ) { + m_privacyListManager.Unlock(); + return; + } } + + HXML item; + for ( int i = 1; ( item = xmlGetNthChild( list, _T("item"), i )) != NULL; i++ ) { + const TCHAR *itemType = xmlGetAttrValue( item, _T("type")); + PrivacyListRuleType nItemType = Else; + if ( itemType ) { + if ( !_tcsicmp( itemType, _T( "jid" ))) + nItemType = Jid; + else if ( !_tcsicmp( itemType, _T( "group" ))) + nItemType = Group; + else if ( !_tcsicmp( itemType, _T( "subscription" ))) + nItemType = Subscription; + } + + const TCHAR *itemValue = xmlGetAttrValue( item, _T("value")); + + const TCHAR *itemAction = xmlGetAttrValue( item, _T("action")); + BOOL bAllow = TRUE; + if ( itemAction && !_tcsicmp( itemAction, _T( "deny" ))) + bAllow = FALSE; + + const TCHAR *itemOrder = xmlGetAttrValue( item, _T("order")); + DWORD dwOrder = 0; + if ( itemOrder ) + dwOrder = _ttoi( itemOrder ); + + DWORD dwPackets = 0; + if ( xmlGetChild( item , "message" )) + dwPackets |= JABBER_PL_RULE_TYPE_MESSAGE; + if ( xmlGetChild( item , "presence-in" )) + dwPackets |= JABBER_PL_RULE_TYPE_PRESENCE_IN; + if ( xmlGetChild( item , "presence-out" )) + dwPackets |= JABBER_PL_RULE_TYPE_PRESENCE_OUT; + if ( xmlGetChild( item , "iq" )) + dwPackets |= JABBER_PL_RULE_TYPE_IQ; + + pList->AddRule( nItemType, itemValue, bAllow, dwOrder, dwPackets ); + } + pList->Reorder(); + pList->SetLoaded(); + pList->SetModified(FALSE); + m_privacyListManager.Unlock(); + + UI_SAFE_NOTIFY(m_pDlgPrivacyLists, WM_JABBER_REFRESH); +} } + +CPrivacyList* GetSelectedList(HWND hDlg) +{ + LRESULT nCurSel = SendDlgItemMessage( hDlg, IDC_LB_LISTS, LB_GETCURSEL, 0, 0 ); + if ( nCurSel == LB_ERR ) + return NULL; + + LRESULT nItemData = SendDlgItemMessage( hDlg, IDC_LB_LISTS, LB_GETITEMDATA, nCurSel, 0 ); + if ( nItemData == LB_ERR || nItemData == 0 ) + return NULL; + + return ( CPrivacyList* )nItemData; +} + +CPrivacyListRule* GetSelectedRule(HWND hDlg) +{ + LRESULT nCurSel = SendDlgItemMessage( hDlg, IDC_PL_RULES_LIST, LB_GETCURSEL, 0, 0 ); + if ( nCurSel == LB_ERR) + return NULL; + + LRESULT nItemData = SendDlgItemMessage( hDlg, IDC_PL_RULES_LIST, LB_GETITEMDATA, nCurSel, 0 ); + if ( nItemData == LB_ERR || nItemData == 0 ) + return NULL; + + return (CPrivacyListRule* )nItemData; +} + +void CJabberProto::OnIqResultPrivacyListActive( HXML iqNode, CJabberIqInfo* pInfo ) +{ + CPrivacyList *pList = (CPrivacyList *)pInfo->GetUserData(); + + if ( m_pDlgPrivacyLists ) + EnableWindow( GetDlgItem( m_pDlgPrivacyLists->GetHwnd(), IDC_ACTIVATE ), TRUE ); + + if ( !iqNode ) + return; + + const TCHAR *type = xmlGetAttrValue( iqNode, _T("type")); + if ( !type ) + return; + + TCHAR szText[ 512 ]; + szText[0] = _T('\0'); + m_privacyListManager.Lock(); + if ( !_tcscmp( type, _T("result"))) { + if ( pList ) { + m_privacyListManager.SetActiveListName( pList->GetListName() ); + mir_sntprintf( szText, SIZEOF( szText ), TranslateT("Privacy list %s set as active"), pList->GetListName() ); + } + else { + m_privacyListManager.SetActiveListName( NULL ); + mir_sntprintf( szText, SIZEOF( szText ), TranslateT("Active privacy list successfully declined")); + } + } + else mir_sntprintf( szText, SIZEOF( szText ), TranslateT("Error occurred while setting active list") ); + + m_privacyListManager.Unlock(); + + if ( m_pDlgPrivacyLists ) + { + m_pDlgPrivacyLists->SetStatusText( szText ); + RedrawWindow(GetDlgItem(m_pDlgPrivacyLists->GetHwnd(), IDC_LB_LISTS), NULL, NULL, RDW_INVALIDATE); + } + + BuildPrivacyListsMenu( true ); +} + +void CJabberProto::OnIqResultPrivacyListDefault( HXML iqNode, CJabberIqInfo* pInfo ) +{ + CPrivacyList *pList = (CPrivacyList *)pInfo->GetUserData(); + + if ( m_pDlgPrivacyLists ) + EnableWindow( GetDlgItem( m_pDlgPrivacyLists->GetHwnd(), IDC_SET_DEFAULT ), TRUE ); + + if ( !iqNode ) + return; + + const TCHAR *type = xmlGetAttrValue( iqNode, _T("type")); + if ( !type ) + return; + + TCHAR szText[ 512 ]; + szText[0] = _T('\0'); + m_privacyListManager.Lock(); + if ( !_tcscmp( type, _T("result"))) { + if ( pList ) { + m_privacyListManager.SetDefaultListName( pList->GetListName() ); + mir_sntprintf( szText, SIZEOF( szText ), TranslateT("Privacy list %s set as default"), pList->GetListName() ); + } + else { + m_privacyListManager.SetDefaultListName( NULL ); + mir_sntprintf( szText, SIZEOF( szText ), TranslateT("Default privacy list successfully declined")); + } + } + else { + mir_sntprintf( szText, SIZEOF( szText ), TranslateT("Error occurred while setting default list") ); + } + m_privacyListManager.Unlock(); + + if ( m_pDlgPrivacyLists ) + { + m_pDlgPrivacyLists->SetStatusText( szText ); + RedrawWindow(GetDlgItem(m_pDlgPrivacyLists->GetHwnd(), IDC_LB_LISTS), NULL, NULL, RDW_INVALIDATE); + } +} + +void CJabberProto::OnIqResultPrivacyLists( HXML iqNode, CJabberIqInfo* pInfo ) +{ + if ( pInfo->m_nIqType != JABBER_IQ_TYPE_RESULT ) + return; + + HXML query = xmlGetChild( iqNode, "query" ); + if ( !query ) + return; + + if ( m_ThreadInfo ) + m_ThreadInfo->jabberServerCaps |= JABBER_CAPS_PRIVACY_LISTS; + + m_privacyListManager.Lock(); + m_privacyListManager.RemoveAllLists(); + + for ( int i = 1; ; i++ ) { + HXML list = xmlGetNthChild( query, _T("list"), i ); + if ( !list ) + break; + + const TCHAR *listName = xmlGetAttrValue( list, _T("name")); + if ( listName ) { + m_privacyListManager.AddList(( TCHAR* )listName); + + // Query contents only if list editior is visible! + if ( m_pDlgPrivacyLists ) { + int iqId = SerialNext(); + IqAdd( iqId, IQ_PROC_NONE, &CJabberProto::OnIqResultPrivacyList); + m_ThreadInfo->send( XmlNodeIq( _T("get"), iqId ) << XQUERY( _T(JABBER_FEAT_PRIVACY_LISTS)) << XCHILD( _T("list")) << XATTR( _T("name"), listName )); + } } } + + const TCHAR *szName = NULL; + HXML node = xmlGetChild( query , "active" ); + if ( node ) + szName = xmlGetAttrValue( node, _T("name")); + m_privacyListManager.SetActiveListName( szName ); + + szName = NULL; + node = xmlGetChild( query , "default" ); + if ( node ) + szName = xmlGetAttrValue( node, _T("name")); + m_privacyListManager.SetDefaultListName( szName ); + + m_privacyListManager.Unlock(); + + UI_SAFE_NOTIFY(m_pDlgPrivacyLists, WM_JABBER_REFRESH); + + BuildPrivacyListsMenu( true ); +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Add privacy list box +class CJabberDlgPrivacyAddList: public CJabberDlgBase +{ + typedef CJabberDlgBase CSuper; + +public: + TCHAR szLine[512]; + + CJabberDlgPrivacyAddList(CJabberProto *proto, HWND hwndParent): + CJabberDlgBase(proto, IDD_PRIVACY_ADD_LIST, hwndParent, false), + m_txtName(this, IDC_EDIT_NAME), + m_btnOk(this, IDOK), + m_btnCancel(this, IDCANCEL) + { + m_btnOk.OnClick = Callback( this, &CJabberDlgPrivacyAddList::btnOk_OnClick ); + m_btnCancel.OnClick = Callback( this, &CJabberDlgPrivacyAddList::btnCancel_OnClick); + } + + void btnOk_OnClick(CCtrlButton*) + { + GetDlgItemText(m_hwnd, IDC_EDIT_NAME, szLine, SIZEOF(szLine)); + EndDialog(m_hwnd, 1); + } + void btnCancel_OnClick(CCtrlButton*) + { + *szLine = 0; + EndDialog(m_hwnd, 0); + } + +private: + CCtrlEdit m_txtName; + CCtrlButton m_btnOk; + CCtrlButton m_btnCancel; +}; + +///////////////////////////////////////////////////////////////////////////////////////// +// Privacy rule editor +class CJabberDlgPrivacyRule: public CJabberDlgBase +{ + typedef CJabberDlgBase CSuper; + + CCtrlButton m_btnOk; + CCtrlButton m_btnCancel; + CCtrlCombo m_cbType; + +public: + CPrivacyListRule *m_pRule; + + CJabberDlgPrivacyRule(CJabberProto *proto, HWND hwndParent, CPrivacyListRule *pRule): + CJabberDlgBase(proto, IDD_PRIVACY_RULE, hwndParent, false), + m_btnOk(this, IDOK), + m_btnCancel(this, IDCANCEL), + m_cbType(this, IDC_COMBO_TYPE) + { + m_pRule = pRule; + m_cbType.OnChange = Callback(this, &CJabberDlgPrivacyRule::cbType_OnChange); + m_btnOk.OnClick = Callback(this, &CJabberDlgPrivacyRule::btnOk_OnClick); + m_btnCancel.OnClick = Callback(this, &CJabberDlgPrivacyRule::btnCancel_OnClick); + } + + virtual void OnInitDialog() + { + CSuper::OnInitDialog(); + + m_proto->m_hwndPrivacyRule = m_hwnd; + + SendDlgItemMessage(m_hwnd, IDC_ICO_MESSAGE, STM_SETICON, (WPARAM)m_proto->LoadIconEx("pl_msg_allow"), 0); + SendDlgItemMessage(m_hwnd, IDC_ICO_QUERY, STM_SETICON, (WPARAM)m_proto->LoadIconEx("pl_iq_allow"), 0); + SendDlgItemMessage(m_hwnd, IDC_ICO_PRESENCEIN, STM_SETICON, (WPARAM)m_proto->LoadIconEx("pl_prin_allow"), 0); + SendDlgItemMessage(m_hwnd, IDC_ICO_PRESENCEOUT, STM_SETICON, (WPARAM)m_proto->LoadIconEx("pl_prout_allow"), 0); + + TCHAR* szTypes[] = { _T("JID"), _T("Group"), _T("Subscription"), _T("Any") }; + int i, nTypes[] = { Jid, Group, Subscription, Else }; + for ( i = 0; i < SIZEOF(szTypes); i++ ) + { + LRESULT nItem = SendDlgItemMessage( m_hwnd, IDC_COMBO_TYPE, CB_ADDSTRING, 0, (LPARAM)TranslateTS( szTypes[i] )); + SendDlgItemMessage( m_hwnd, IDC_COMBO_TYPE, CB_SETITEMDATA, nItem, nTypes[i] ); + if ( m_pRule->GetType() == nTypes[i] ) + SendDlgItemMessage( m_hwnd, IDC_COMBO_TYPE, CB_SETCURSEL, nItem, 0 ); + } + + SendDlgItemMessage( m_hwnd, IDC_COMBO_VALUE, CB_RESETCONTENT, 0, 0 ); + TCHAR* szSubscriptions[] = { _T("none"), _T("from"), _T("to"), _T("both") }; + for ( i = 0; i < SIZEOF(szSubscriptions); i++ ) + { + LRESULT nItem = SendDlgItemMessage( m_hwnd, IDC_COMBO_VALUE, CB_ADDSTRING, 0, (LPARAM)TranslateTS( szSubscriptions[i] )); + SendDlgItemMessage( m_hwnd, IDC_COMBO_VALUE, CB_SETITEMDATA, nItem, (LPARAM)szSubscriptions[i] ); + } + + PostMessage( m_hwnd, WM_COMMAND, MAKEWPARAM( IDC_COMBO_TYPE, CBN_SELCHANGE ), 0 ); + + SendDlgItemMessage( m_hwnd, IDC_COMBO_ACTION, CB_ADDSTRING, 0, (LPARAM)TranslateTS( _T("Deny" ))); + SendDlgItemMessage( m_hwnd, IDC_COMBO_ACTION, CB_ADDSTRING, 0, (LPARAM)TranslateTS( _T("Allow" ))); + + SendDlgItemMessage( m_hwnd, IDC_COMBO_ACTION, CB_SETCURSEL, m_pRule->GetAction() ? 1 : 0, 0 ); + + DWORD dwPackets = m_pRule->GetPackets(); + if ( !dwPackets ) + dwPackets = JABBER_PL_RULE_TYPE_ALL; + if ( dwPackets & JABBER_PL_RULE_TYPE_IQ ) + SendDlgItemMessage( m_hwnd, IDC_CHECK_QUERIES, BM_SETCHECK, BST_CHECKED, 0 ); + if ( dwPackets & JABBER_PL_RULE_TYPE_MESSAGE ) + SendDlgItemMessage( m_hwnd, IDC_CHECK_MESSAGES, BM_SETCHECK, BST_CHECKED, 0 ); + if ( dwPackets & JABBER_PL_RULE_TYPE_PRESENCE_IN ) + SendDlgItemMessage( m_hwnd, IDC_CHECK_PRESENCE_IN, BM_SETCHECK, BST_CHECKED, 0 ); + if ( dwPackets & JABBER_PL_RULE_TYPE_PRESENCE_OUT ) + SendDlgItemMessage( m_hwnd, IDC_CHECK_PRESENCE_OUT, BM_SETCHECK, BST_CHECKED, 0 ); + + if ( m_pRule->GetValue() && ( m_pRule->GetType() == Jid || m_pRule->GetType() == Group )) + SetDlgItemText( m_hwnd, IDC_EDIT_VALUE, m_pRule->GetValue() ); + } + + void cbType_OnChange(CCtrlData*) + { + if ( !m_pRule ) return; + + LRESULT nCurSel = SendDlgItemMessage( m_hwnd, IDC_COMBO_TYPE, CB_GETCURSEL, 0, 0 ); + if ( nCurSel == CB_ERR ) + return; + + LRESULT nItemData = SendDlgItemMessage( m_hwnd, IDC_COMBO_TYPE, CB_GETITEMDATA, nCurSel, 0 ); + switch (nItemData) + { + case Jid: + { + ShowWindow( GetDlgItem( m_hwnd, IDC_COMBO_VALUES ), SW_SHOW ); + ShowWindow( GetDlgItem( m_hwnd, IDC_COMBO_VALUE ), SW_HIDE ); + + SendDlgItemMessage( m_hwnd, IDC_COMBO_VALUES, CB_RESETCONTENT, 0, 0 ); + + HANDLE hContact = ( HANDLE ) JCallService( MS_DB_CONTACT_FINDFIRST, 0, 0 ); + while ( hContact != NULL ) + { + char* szProto = ( char* )JCallService( MS_PROTO_GETCONTACTBASEPROTO, ( WPARAM ) hContact, 0 ); + if ( szProto != NULL && !strcmp( szProto, m_proto->m_szModuleName )) + { + DBVARIANT dbv; + if ( !m_proto->JGetStringT( hContact, "jid", &dbv )) + { + SendDlgItemMessage( m_hwnd, IDC_COMBO_VALUES, CB_ADDSTRING, 0, (LPARAM)dbv.ptszVal ); + JFreeVariant( &dbv ); + } + } + hContact = ( HANDLE ) JCallService( MS_DB_CONTACT_FINDNEXT, ( WPARAM ) hContact, 0 ); + } + + // append known chatroom jids from bookmarks + LISTFOREACH(i, m_proto, LIST_BOOKMARK) + { + JABBER_LIST_ITEM *item = 0; + if ( item = m_proto->ListGetItemPtrFromIndex( i )) + SendDlgItemMessage( m_hwnd, IDC_COMBO_VALUES, CB_ADDSTRING, 0, (LPARAM)item->jid ); + } + + // FIXME: ugly code :) + if ( m_pRule->GetValue() ) + { + SetDlgItemText( m_hwnd, IDC_COMBO_VALUES, m_pRule->GetValue() ); + LRESULT nSelPos = SendDlgItemMessage( m_hwnd, IDC_COMBO_VALUES, CB_FINDSTRINGEXACT , -1, (LPARAM)m_pRule->GetValue() ); + if ( nSelPos != CB_ERR ) + SendDlgItemMessage( m_hwnd, IDC_COMBO_VALUES, CB_SETCURSEL, nSelPos, 0 ); + } + break; + } + + case Group: + { + ShowWindow( GetDlgItem( m_hwnd, IDC_COMBO_VALUES ), SW_SHOW ); + ShowWindow( GetDlgItem( m_hwnd, IDC_COMBO_VALUE ), SW_HIDE ); + + SendDlgItemMessage( m_hwnd, IDC_COMBO_VALUES, CB_RESETCONTENT, 0, 0 ); + + char buf[ 20 ]; + DBVARIANT dbv; + for ( int i = 0; ; i++ ) + { + mir_snprintf(buf, 20, "%d", i); + if ( DBGetContactSettingTString(NULL, "CListGroups", buf, &dbv) ) + break; + + SendDlgItemMessage( m_hwnd, IDC_COMBO_VALUES, CB_ADDSTRING, 0, (LPARAM)&dbv.ptszVal[1] ); + DBFreeVariant(&dbv); + } + + // FIXME: ugly code :) + if ( m_pRule->GetValue() ) + { + SetDlgItemText( m_hwnd, IDC_COMBO_VALUES, m_pRule->GetValue() ); + LRESULT nSelPos = SendDlgItemMessage( m_hwnd, IDC_COMBO_VALUES, CB_FINDSTRINGEXACT , -1, (LPARAM)m_pRule->GetValue() ); + if ( nSelPos != CB_ERR ) + SendDlgItemMessage( m_hwnd, IDC_COMBO_VALUES, CB_SETCURSEL, nSelPos, 0 ); + } + break; + } + + case Subscription: + { + ShowWindow( GetDlgItem( m_hwnd, IDC_COMBO_VALUES ), SW_HIDE ); + ShowWindow( GetDlgItem( m_hwnd, IDC_COMBO_VALUE ), SW_SHOW ); + + if ( m_pRule->GetValue() ) + { + LRESULT nSelected = SendDlgItemMessage( m_hwnd, IDC_COMBO_VALUE, CB_SELECTSTRING, -1, (LPARAM)TranslateTS(m_pRule->GetValue()) ); + if ( nSelected == CB_ERR ) + SendDlgItemMessage( m_hwnd, IDC_COMBO_VALUE, CB_SETCURSEL, 0, 0 ); + } + else SendDlgItemMessage( m_hwnd, IDC_COMBO_VALUE, CB_SETCURSEL, 0, 0 ); + break; + } + + case Else: + { + ShowWindow( GetDlgItem( m_hwnd, IDC_COMBO_VALUES ), SW_HIDE ); + ShowWindow( GetDlgItem( m_hwnd, IDC_COMBO_VALUE ), SW_HIDE ); + break; + } + } + + return; + } + + void btnOk_OnClick(CCtrlButton *) + { + LRESULT nItemData = -1; + LRESULT nCurSel = SendDlgItemMessage( m_hwnd, IDC_COMBO_TYPE, CB_GETCURSEL, 0, 0 ); + if ( nCurSel != CB_ERR ) + nItemData = SendDlgItemMessage( m_hwnd, IDC_COMBO_TYPE, CB_GETITEMDATA, nCurSel, 0 ); + + switch ( nItemData ) + { + case Jid: + case Group: + { + TCHAR szText[ 512 ]; + GetDlgItemText( m_hwnd, IDC_COMBO_VALUES, szText, SIZEOF(szText) ); + m_pRule->SetValue( szText ); + break; + } + case Subscription: + { + nCurSel = SendDlgItemMessage( m_hwnd, IDC_COMBO_VALUE, CB_GETCURSEL, 0, 0 ); + if ( nCurSel != CB_ERR ) + m_pRule->SetValue(( TCHAR* )SendDlgItemMessage( m_hwnd, IDC_COMBO_VALUE, CB_GETITEMDATA, nCurSel, 0 )); + else + m_pRule->SetValue( _T( "none" )); + break; + } + + default: + m_pRule->SetValue( NULL ); + break; + } + + m_pRule->SetType( ( PrivacyListRuleType )nItemData ); + nCurSel = SendDlgItemMessage( m_hwnd, IDC_COMBO_ACTION, CB_GETCURSEL, 0, 0 ); + if ( nCurSel == CB_ERR ) + nCurSel = 1; + m_pRule->SetAction( nCurSel ? TRUE : FALSE ); + + DWORD dwPackets = 0; + if ( BST_CHECKED == SendDlgItemMessage( m_hwnd, IDC_CHECK_MESSAGES, BM_GETCHECK, 0, 0 )) + dwPackets |= JABBER_PL_RULE_TYPE_MESSAGE; + if ( BST_CHECKED == SendDlgItemMessage( m_hwnd, IDC_CHECK_PRESENCE_IN, BM_GETCHECK, 0, 0 )) + dwPackets |= JABBER_PL_RULE_TYPE_PRESENCE_IN; + if ( BST_CHECKED == SendDlgItemMessage( m_hwnd, IDC_CHECK_PRESENCE_OUT, BM_GETCHECK, 0, 0 )) + dwPackets |= JABBER_PL_RULE_TYPE_PRESENCE_OUT; + if ( BST_CHECKED == SendDlgItemMessage( m_hwnd, IDC_CHECK_QUERIES, BM_GETCHECK, 0, 0 )) + dwPackets |= JABBER_PL_RULE_TYPE_IQ; + if ( !dwPackets ) + dwPackets = JABBER_PL_RULE_TYPE_ALL; + + m_pRule->SetPackets( dwPackets ); + + EndDialog( m_hwnd, 1 ); + } + + void btnCancel_OnClick(CCtrlButton *) + { + EndDialog(m_hwnd, 0); + } + + void OnDestroy() + { + g_ReleaseIcon(( HICON )SendDlgItemMessage(m_hwnd, IDC_ICO_MESSAGE, STM_SETICON, 0, 0)); + g_ReleaseIcon(( HICON )SendDlgItemMessage(m_hwnd, IDC_ICO_QUERY, STM_SETICON, 0, 0)); + g_ReleaseIcon(( HICON )SendDlgItemMessage(m_hwnd, IDC_ICO_PRESENCEIN, STM_SETICON, 0, 0)); + g_ReleaseIcon(( HICON )SendDlgItemMessage(m_hwnd, IDC_ICO_PRESENCEOUT, STM_SETICON, 0, 0)); + m_proto->m_hwndPrivacyRule = NULL; + } +}; + +///////////////////////////////////////////////////////////////////////////////////////// +// Main privacy list dialog +class CJabberDlgPrivacyLists: public CJabberDlgBase +{ + typedef CJabberDlgBase CSuper; + +public: + CJabberDlgPrivacyLists(CJabberProto *proto); + +protected: + static int idSimpleControls[]; + static int idAdvancedControls[]; + + void OnInitDialog(); + void OnClose(); + void OnDestroy(); + void OnProtoRefresh(WPARAM, LPARAM); + int Resizer(UTILRESIZECONTROL *urc); + + UI_MESSAGE_MAP(CJabberDlgPrivacyLists, CSuper); + UI_MESSAGE(WM_MEASUREITEM, OnWmMeasureItem); + UI_MESSAGE(WM_DRAWITEM, OnWmDrawItem); + UI_MESSAGE(WM_GETMINMAXINFO, OnWmGetMinMaxInfo); + UI_MESSAGE_MAP_END(); + + BOOL OnWmMeasureItem(UINT msg, WPARAM wParam, LPARAM lParam); + BOOL OnWmDrawItem(UINT msg, WPARAM wParam, LPARAM lParam); + BOOL OnWmGetMinMaxInfo(UINT msg, WPARAM wParam, LPARAM lParam); + + void btnSimple_OnClick(CCtrlButton *); + void btnAdvanced_OnClick(CCtrlButton *); + void btnAddJid_OnClick(CCtrlButton *); + void btnActivate_OnClick(CCtrlButton *); + void btnSetDefault_OnClick(CCtrlButton *); + void lbLists_OnSelChange(CCtrlListBox *); + void lbLists_OnDblClick(CCtrlListBox *); + void lbRules_OnSelChange(CCtrlListBox *); + void lbRules_OnDblClick(CCtrlListBox *); + void btnEditRule_OnClick(CCtrlButton *); + void btnAddRule_OnClick(CCtrlButton *); + void btnRemoveRule_OnClick(CCtrlButton *); + void btnUpRule_OnClick(CCtrlButton *); + void btnDownRule_OnClick(CCtrlButton *); + void btnAddList_OnClick(CCtrlButton *); + void btnRemoveList_OnClick(CCtrlButton *); + void btnApply_OnClick(CCtrlButton *); + void clcClist_OnUpdate(CCtrlClc::TEventInfo *evt); + void clcClist_OnOptionsChanged(CCtrlClc::TEventInfo *evt); + void clcClist_OnClick(CCtrlClc::TEventInfo *evt); + + void OnCommand_Close(HWND hwndCtrl, WORD idCtrl, WORD idCode); + + void ShowAdvancedList(CPrivacyList *pList); + void DrawNextRulePart(HDC hdc, COLORREF color, const TCHAR *text, RECT *rc); + void DrawRuleAction(HDC hdc, COLORREF clLine1, COLORREF clLine2, CPrivacyListRule *pRule, RECT *rc); + void DrawRulesList(LPDRAWITEMSTRUCT lpdis); + void DrawLists(LPDRAWITEMSTRUCT lpdis); + + void CListResetOptions(HWND hwndList); + void CListFilter(HWND hwndList); + bool CListIsGroup(HANDLE hGroup); + HANDLE CListFindGroupByName(TCHAR *name); + void CListResetIcons(HWND hwndList, HANDLE hItem, bool hide=false); + void CListSetupIcons(HWND hwndList, HANDLE hItem, int iSlot, DWORD dwProcess, BOOL bAction); + HANDLE CListAddContact(HWND hwndList, TCHAR *jid); + void CListApplyList(HWND hwndList, CPrivacyList *pList = NULL); + DWORD CListGetPackets(HWND hwndList, HANDLE hItem, bool bAction); + void CListBuildList(HWND hwndList, CPrivacyList *pList); + + void EnableEditorControls(); + BOOL CanExit(); + + static LRESULT CALLBACK LstListsSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); + static LRESULT CALLBACK LstRulesSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); + + struct TCLCInfo + { + struct TJidData + { + HANDLE hItem; + TCHAR *jid; + + static int cmp(const TJidData *p1, const TJidData *p2) { return lstrcmp(p1->jid, p2->jid); } + }; + + HANDLE hItemDefault; + HANDLE hItemSubNone; + HANDLE hItemSubTo; + HANDLE hItemSubFrom; + HANDLE hItemSubBoth; + + LIST newJids; + + bool bChanged; + + CPrivacyList *pList; + + TCLCInfo(): newJids(1, TJidData::cmp), bChanged(false), pList(0) {} + ~TCLCInfo() + { + for (int i = 0; i < newJids.getCount(); ++i) + { + mir_free(newJids[i]->jid); + mir_free(newJids[i]); + } + newJids.destroy(); + } + + void addJid(HANDLE hItem, TCHAR *jid) + { + TJidData *data = (TJidData *)mir_alloc(sizeof(TJidData)); + data->hItem = hItem; + data->jid = mir_tstrdup(jid); + newJids.insert(data); + } + + HANDLE findJid(TCHAR *jid) + { + TJidData data = {0}; + data.jid = jid; + TJidData *found = newJids.find(&data); + return found ? found->hItem : 0; + } + }; + + TCLCInfo clc_info; + +private: + CCtrlMButton m_btnSimple; + CCtrlMButton m_btnAdvanced; + CCtrlMButton m_btnAddJid; + CCtrlMButton m_btnActivate; + CCtrlMButton m_btnSetDefault; + CCtrlMButton m_btnEditRule; + CCtrlMButton m_btnAddRule; + CCtrlMButton m_btnRemoveRule; + CCtrlMButton m_btnUpRule; + CCtrlMButton m_btnDownRule; + CCtrlMButton m_btnAddList; + CCtrlMButton m_btnRemoveList; + CCtrlButton m_btnApply; + CCtrlListBox m_lbLists; + CCtrlListBox m_lbRules; + CCtrlClc m_clcClist; +}; + +int CJabberDlgPrivacyLists::idSimpleControls[] = +{ + IDC_CLIST, IDC_CANVAS, + IDC_TXT_OTHERJID, IDC_NEWJID, IDC_ADDJID, + IDC_ICO_MESSAGE, IDC_ICO_QUERY, IDC_ICO_INPRESENCE, IDC_ICO_OUTPRESENCE, + IDC_TXT_MESSAGE, IDC_TXT_QUERY, IDC_TXT_INPRESENCE, IDC_TXT_OUTPRESENCE, + 0 +}; + +int CJabberDlgPrivacyLists::idAdvancedControls[] = +{ + IDC_PL_RULES_LIST, + IDC_ADD_RULE, IDC_EDIT_RULE, IDC_REMOVE_RULE, + IDC_UP_RULE, IDC_DOWN_RULE, + 0 +}; + +CJabberDlgPrivacyLists::CJabberDlgPrivacyLists(CJabberProto *proto): + CSuper(proto, IDD_PRIVACY_LISTS, NULL), + m_btnSimple(this, IDC_BTN_SIMPLE, proto->LoadIconEx("group"), LPGEN("Simple mode")), + m_btnAdvanced(this, IDC_BTN_ADVANCED, proto->LoadIconEx("sd_view_list"), LPGEN("Advanced mode")), + m_btnAddJid(this, IDC_ADDJID, proto->LoadIconEx("addroster"), LPGEN("Add JID")), + m_btnActivate(this, IDC_ACTIVATE, proto->LoadIconEx("pl_list_active"), LPGEN("Activate")), + m_btnSetDefault(this, IDC_SET_DEFAULT, proto->LoadIconEx("pl_list_default"), LPGEN("Set default")), + m_btnEditRule(this, IDC_EDIT_RULE, SKINICON_OTHER_RENAME, LPGEN("Edit rule")), + m_btnAddRule(this, IDC_ADD_RULE, SKINICON_OTHER_ADDCONTACT, LPGEN("Add rule")), + m_btnRemoveRule(this, IDC_REMOVE_RULE, SKINICON_OTHER_DELETE, LPGEN("Delete rule")), + m_btnUpRule(this, IDC_UP_RULE, proto->LoadIconEx("arrow_up"), LPGEN("Move rule up")), + m_btnDownRule(this, IDC_DOWN_RULE, proto->LoadIconEx("arrow_down"), LPGEN("Move rule down")), + m_btnAddList(this, IDC_ADD_LIST, SKINICON_OTHER_ADDCONTACT, LPGEN("Add list...")), + m_btnRemoveList(this, IDC_REMOVE_LIST, SKINICON_OTHER_DELETE, LPGEN("Remove list")), + m_btnApply(this, IDC_APPLY), + m_lbLists(this, IDC_LB_LISTS), + m_lbRules(this, IDC_PL_RULES_LIST), + m_clcClist(this, IDC_CLIST) +{ + m_btnSimple.OnClick = Callback( this, &CJabberDlgPrivacyLists::btnSimple_OnClick); + m_btnAdvanced.OnClick = Callback( this, &CJabberDlgPrivacyLists::btnAdvanced_OnClick); + m_btnAddJid.OnClick = Callback( this, &CJabberDlgPrivacyLists::btnAddJid_OnClick); + m_btnActivate.OnClick = Callback( this, &CJabberDlgPrivacyLists::btnActivate_OnClick); + m_btnSetDefault.OnClick = Callback( this, &CJabberDlgPrivacyLists::btnSetDefault_OnClick); + m_btnEditRule.OnClick = Callback( this, &CJabberDlgPrivacyLists::btnEditRule_OnClick); + m_btnAddRule.OnClick = Callback( this, &CJabberDlgPrivacyLists::btnAddRule_OnClick); + m_btnRemoveRule.OnClick = Callback( this, &CJabberDlgPrivacyLists::btnRemoveRule_OnClick); + m_btnUpRule.OnClick = Callback( this, &CJabberDlgPrivacyLists::btnUpRule_OnClick); + m_btnDownRule.OnClick = Callback( this, &CJabberDlgPrivacyLists::btnDownRule_OnClick); + m_btnAddList.OnClick = Callback( this, &CJabberDlgPrivacyLists::btnAddList_OnClick); + m_btnRemoveList.OnClick = Callback( this, &CJabberDlgPrivacyLists::btnRemoveList_OnClick); + m_btnApply.OnClick = Callback( this, &CJabberDlgPrivacyLists::btnApply_OnClick); + + m_lbLists.OnSelChange = Callback(this, &CJabberDlgPrivacyLists::lbLists_OnSelChange); + m_lbLists.OnDblClick = Callback(this, &CJabberDlgPrivacyLists::lbLists_OnDblClick); + m_lbRules.OnSelChange = Callback(this, &CJabberDlgPrivacyLists::lbRules_OnSelChange); + m_lbRules.OnDblClick = Callback(this, &CJabberDlgPrivacyLists::lbRules_OnDblClick); + + m_clcClist.OnNewContact = + m_clcClist.OnListRebuilt = Callback(this, &CJabberDlgPrivacyLists::clcClist_OnUpdate); + m_clcClist.OnOptionsChanged = Callback(this, &CJabberDlgPrivacyLists::clcClist_OnOptionsChanged); + m_clcClist.OnClick = Callback(this, &CJabberDlgPrivacyLists::clcClist_OnClick); +} + +void CJabberDlgPrivacyLists::OnInitDialog() +{ + CSuper::OnInitDialog(); + + WindowSetIcon( m_hwnd, m_proto, "privacylists" ); + + EnableWindow( GetDlgItem( m_hwnd, IDC_ADD_RULE ), FALSE ); + EnableWindow( GetDlgItem( m_hwnd, IDC_EDIT_RULE ), FALSE ); + EnableWindow( GetDlgItem( m_hwnd, IDC_REMOVE_RULE ), FALSE ); + EnableWindow( GetDlgItem( m_hwnd, IDC_UP_RULE ), FALSE ); + EnableWindow( GetDlgItem( m_hwnd, IDC_DOWN_RULE ), FALSE ); + + m_proto->QueryPrivacyLists(); + + LOGFONT lf; + GetObject((HFONT)SendDlgItemMessage(m_hwnd, IDC_TXT_LISTS, WM_GETFONT, 0, 0), sizeof(lf), &lf); + lf.lfWeight = FW_BOLD; + HFONT hfnt = CreateFontIndirect(&lf); + SendDlgItemMessage(m_hwnd, IDC_TXT_LISTS, WM_SETFONT, (WPARAM)hfnt, TRUE); + SendDlgItemMessage(m_hwnd, IDC_TXT_RULES, WM_SETFONT, (WPARAM)hfnt, TRUE); + + SetWindowLong(GetDlgItem(m_hwnd, IDC_CLIST), GWL_STYLE, + GetWindowLong(GetDlgItem(m_hwnd, IDC_CLIST), GWL_STYLE)|CLS_HIDEEMPTYGROUPS|CLS_USEGROUPS|CLS_GREYALTERNATE); + m_clcClist.SetExStyle(CLS_EX_DISABLEDRAGDROP|CLS_EX_TRACKSELECT); + + HIMAGELIST hIml = ImageList_Create(GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),(IsWinVerXPPlus()?ILC_COLOR32:ILC_COLOR16)|ILC_MASK,9,9); + ImageList_AddIcon_Icolib(hIml, LoadSkinnedIcon(SKINICON_OTHER_SMALLDOT)); + ImageList_AddIcon_Icolib(hIml, m_proto->LoadIconEx("pl_msg_allow")); + ImageList_AddIcon_Icolib(hIml, m_proto->LoadIconEx("pl_msg_deny")); + ImageList_AddIcon_Icolib(hIml, m_proto->LoadIconEx("pl_prin_allow")); + ImageList_AddIcon_Icolib(hIml, m_proto->LoadIconEx("pl_prin_deny")); + ImageList_AddIcon_Icolib(hIml, m_proto->LoadIconEx("pl_prout_allow")); + ImageList_AddIcon_Icolib(hIml, m_proto->LoadIconEx("pl_prout_deny")); + ImageList_AddIcon_Icolib(hIml, m_proto->LoadIconEx("pl_iq_allow")); + ImageList_AddIcon_Icolib(hIml, m_proto->LoadIconEx("pl_iq_deny")); + m_clcClist.SetExtraImageList(hIml); + m_clcClist.SetExtraColumns(4); + + m_btnSimple.MakePush(); + m_btnAdvanced.MakePush(); + + CLCINFOITEM cii = {0}; + cii.cbSize = sizeof(cii); + + cii.flags = CLCIIF_GROUPFONT; + cii.pszText = TranslateT("** Default **"); + clc_info.hItemDefault = m_clcClist.AddInfoItem(&cii); + cii.pszText = TranslateT("** Subsription: both **"); + clc_info.hItemSubBoth = m_clcClist.AddInfoItem(&cii); + cii.pszText = TranslateT("** Subsription: to **"); + clc_info.hItemSubTo = m_clcClist.AddInfoItem(&cii); + cii.pszText = TranslateT("** Subsription: from **"); + clc_info.hItemSubFrom = m_clcClist.AddInfoItem(&cii); + cii.pszText = TranslateT("** Subsription: none **"); + clc_info.hItemSubNone = m_clcClist.AddInfoItem(&cii); + + CListResetOptions(GetDlgItem(m_hwnd, IDC_CLIST)); + CListFilter(GetDlgItem(m_hwnd, IDC_CLIST)); + CListApplyList(GetDlgItem(m_hwnd, IDC_CLIST)); + + if ( DBGetContactSettingByte(NULL, m_proto->m_szModuleName, "plistsWnd_simpleMode", 1)) + { + UIShowControls(m_hwnd, idSimpleControls, SW_SHOW); + UIShowControls(m_hwnd, idAdvancedControls, SW_HIDE); + CheckDlgButton(m_hwnd, IDC_BTN_SIMPLE, TRUE); + } else + { + UIShowControls(m_hwnd, idSimpleControls, SW_HIDE); + UIShowControls(m_hwnd, idAdvancedControls, SW_SHOW); + CheckDlgButton(m_hwnd, IDC_BTN_ADVANCED, TRUE); + } + + SetWindowLongPtr(GetDlgItem(m_hwnd, IDC_LB_LISTS), GWLP_USERDATA, + SetWindowLongPtr(GetDlgItem(m_hwnd, IDC_LB_LISTS), GWLP_WNDPROC, (LONG_PTR)LstListsSubclassProc)); + SetWindowLongPtr(GetDlgItem(m_hwnd, IDC_PL_RULES_LIST), GWLP_USERDATA, + SetWindowLongPtr(GetDlgItem(m_hwnd, IDC_PL_RULES_LIST), GWLP_WNDPROC, (LONG_PTR)LstRulesSubclassProc)); + + SetStatusText(TranslateT("Loading...")); + + Utils_RestoreWindowPosition(m_hwnd, NULL, m_proto->m_szModuleName, "plistsWnd_sz"); +} + +void CJabberDlgPrivacyLists::OnClose() +{ + if (CanExit()) { + DestroyWindow(m_hwnd); + CSuper::OnClose(); + } + else + m_lresult = TRUE; +} + +void CJabberDlgPrivacyLists::OnDestroy() +{ + m_proto->m_pDlgPrivacyLists = NULL; + + // Wipe all data and query lists without contents + m_proto->m_privacyListManager.RemoveAllLists(); + m_proto->QueryPrivacyLists(); + m_proto->m_privacyListManager.SetModified( FALSE ); + + // Delete custom bold font + DeleteObject((HFONT)SendDlgItemMessage(m_hwnd, IDC_TXT_LISTS, WM_GETFONT, 0, 0)); + + DBWriteContactSettingByte(NULL, m_proto->m_szModuleName, "plistsWnd_simpleMode", IsDlgButtonChecked(m_hwnd, IDC_BTN_SIMPLE)); + + Utils_SaveWindowPosition(m_hwnd, NULL, m_proto->m_szModuleName, "plistsWnd_sz"); + + CSuper::OnDestroy(); +} + +void CJabberDlgPrivacyLists::OnProtoRefresh(WPARAM, LPARAM) +{ + LRESULT sel = SendDlgItemMessage(m_hwnd, IDC_LB_LISTS, LB_GETCURSEL, 0, 0); + TCHAR *szCurrentSelectedList = NULL; + if ( sel != LB_ERR ) { + LRESULT len = SendDlgItemMessage(m_hwnd, IDC_LB_LISTS, LB_GETTEXTLEN, sel, 0) + 1; + szCurrentSelectedList = (TCHAR *)mir_alloc(len * sizeof(TCHAR)); + SendDlgItemMessage(m_hwnd, IDC_LB_LISTS, LB_GETTEXT, sel, (LPARAM)szCurrentSelectedList); + } + + SendDlgItemMessage( m_hwnd, IDC_LB_LISTS, LB_RESETCONTENT, 0, 0 ); + + LRESULT nItemId = SendDlgItemMessage( m_hwnd, IDC_LB_LISTS, LB_ADDSTRING, 0, (LPARAM)TranslateT( "" )); + SendDlgItemMessage( m_hwnd, IDC_LB_LISTS, LB_SETITEMDATA, nItemId, (LPARAM)NULL ); + + m_proto->m_privacyListManager.Lock(); + CPrivacyList* pList = m_proto->m_privacyListManager.GetFirstList(); + while ( pList ) { + if ( !pList->IsDeleted() ) { + nItemId = SendDlgItemMessage( m_hwnd, IDC_LB_LISTS, LB_ADDSTRING, 0, (LPARAM)pList->GetListName() ); + SendDlgItemMessage( m_hwnd, IDC_LB_LISTS, LB_SETITEMDATA, nItemId, (LPARAM)pList ); + } + pList = pList->GetNext(); + } + + if ( !szCurrentSelectedList || ( SendDlgItemMessage( m_hwnd, IDC_LB_LISTS, LB_SELECTSTRING, -1, (LPARAM)szCurrentSelectedList ) == LB_ERR )) + SendDlgItemMessage( m_hwnd, IDC_LB_LISTS, LB_SETCURSEL, 0, 0 ); + if ( szCurrentSelectedList ) + mir_free( szCurrentSelectedList ); + + m_proto->m_privacyListManager.Unlock(); + + PostMessage( m_hwnd, WM_COMMAND, MAKEWPARAM( IDC_LB_LISTS, LBN_SELCHANGE ), 0 ); + EnableEditorControls(); +} + +BOOL CJabberDlgPrivacyLists::OnWmMeasureItem(UINT, WPARAM, LPARAM lParam) +{ + LPMEASUREITEMSTRUCT lpmis = (LPMEASUREITEMSTRUCT)lParam; + if ((lpmis->CtlID != IDC_PL_RULES_LIST) && (lpmis->CtlID != IDC_LB_LISTS)) + return FALSE; + + TEXTMETRIC tm = {0}; + HDC hdc = GetDC(GetDlgItem(m_hwnd, lpmis->CtlID)); + GetTextMetrics(hdc, &tm); + ReleaseDC(GetDlgItem(m_hwnd, lpmis->CtlID), hdc); + + if (lpmis->CtlID == IDC_PL_RULES_LIST) + lpmis->itemHeight = tm.tmHeight * 2; + else if (lpmis->CtlID == IDC_LB_LISTS) + lpmis->itemHeight = tm.tmHeight; + + if (lpmis->itemHeight < 18) lpmis->itemHeight = 18; + + return TRUE; +} + +BOOL CJabberDlgPrivacyLists::OnWmDrawItem(UINT, WPARAM, LPARAM lParam) +{ + LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)lParam; + + if (lpdis->CtlID == IDC_PL_RULES_LIST) + DrawRulesList(lpdis); + else if (lpdis->CtlID == IDC_LB_LISTS) + DrawLists(lpdis); + else if (lpdis->CtlID == IDC_CANVAS) + { + static struct + { + TCHAR *textEng; + char *icon; + TCHAR *text; + } items[] = + { + { _T("Message"), "pl_msg_allow" }, + { _T("Presence (in)"), "pl_prin_allow" }, + { _T("Presence (out)"), "pl_prout_allow" }, + { _T("Query"), "pl_iq_allow" }, + }; + + int i, totalWidth = -5; // spacing for last item + for (i = 0; i < SIZEOF(items); ++i) + { + SIZE sz = {0}; + if (!items[i].text) items[i].text = TranslateTS(items[i].textEng); + GetTextExtentPoint32(lpdis->hDC, items[i].text, lstrlen(items[i].text), &sz); + totalWidth += sz.cx + 18 + 5; // 18 pixels for icon, 5 pixel spacing + } + + COLORREF clText = GetSysColor(COLOR_BTNTEXT); + RECT rc = lpdis->rcItem; + rc.left = (rc.left + rc.right - totalWidth)/2; + + for (i = 0; i < SIZEOF(items); ++i) + { + DrawIconEx(lpdis->hDC, rc.left, (rc.top+rc.bottom-16)/2, m_proto->LoadIconEx(items[i].icon), + 16, 16, 0, NULL, DI_NORMAL); + rc.left += 18; + DrawNextRulePart(lpdis->hDC, clText, items[i].text, &rc); + rc.left += 5; + } + } + else return FALSE; + + return TRUE; +} + +BOOL CJabberDlgPrivacyLists::OnWmGetMinMaxInfo(UINT, WPARAM, LPARAM lParam) +{ + LPMINMAXINFO lpmmi = (LPMINMAXINFO)lParam; + lpmmi->ptMinTrackSize.x = 550; + lpmmi->ptMinTrackSize.y = 390; + return 0; +} + +void CJabberDlgPrivacyLists::ShowAdvancedList(CPrivacyList *pList) +{ + int nLbSel = SendDlgItemMessage(m_hwnd, IDC_PL_RULES_LIST, LB_GETCURSEL, 0, 0); + SendDlgItemMessage( m_hwnd, IDC_PL_RULES_LIST, LB_RESETCONTENT, 0, 0 ); + + BOOL bListEmpty = TRUE; + + CPrivacyListRule* pRule = pList->GetFirstRule(); + + while ( pRule ) { + bListEmpty = FALSE; + TCHAR szTypeValue[ 512 ]; + switch ( pRule->GetType() ) { + case Jid: + mir_sntprintf( szTypeValue, SIZEOF( szTypeValue ), _T( "If jabber id is '%s' then" ), pRule->GetValue() ); + break; + case Group: + mir_sntprintf( szTypeValue, SIZEOF( szTypeValue ), _T( "If group is '%s' then" ), pRule->GetValue() ); + break; + case Subscription: + mir_sntprintf( szTypeValue, SIZEOF( szTypeValue ), _T( "If subscription is '%s' then" ), pRule->GetValue() ); + break; + case Else: + mir_sntprintf( szTypeValue, SIZEOF( szTypeValue ), _T( "Else")); + break; + } + + TCHAR szPackets[ 512 ]; + szPackets[ 0 ] = '\0'; + + DWORD dwPackets = pRule->GetPackets(); + if ( !dwPackets ) + dwPackets = JABBER_PL_RULE_TYPE_ALL; + if ( dwPackets == JABBER_PL_RULE_TYPE_ALL ) + _tcscpy( szPackets, _T("all") ); + else { + if ( dwPackets & JABBER_PL_RULE_TYPE_MESSAGE ) + _tcscat( szPackets, _T("messages") ); + if ( dwPackets & JABBER_PL_RULE_TYPE_PRESENCE_IN ) { + if ( _tcslen( szPackets )) + _tcscat( szPackets, _T(", ")); + _tcscat( szPackets, _T("presence-in") ); + } + if ( dwPackets & JABBER_PL_RULE_TYPE_PRESENCE_OUT ) { + if ( _tcslen( szPackets )) + _tcscat( szPackets, _T(", ")); + _tcscat( szPackets, _T("presence-out") ); + } + if ( dwPackets & JABBER_PL_RULE_TYPE_IQ ) { + if ( _tcslen( szPackets )) + _tcscat( szPackets, _T(", ")); + _tcscat( szPackets, _T("queries") ); + } } + + TCHAR szListItem[ 512 ]; + mir_sntprintf( szListItem, SIZEOF( szListItem ), _T("%s %s %s"), szTypeValue, pRule->GetAction() ? _T("allow") : _T("deny"), szPackets ); + + LRESULT nItemId = SendDlgItemMessage( m_hwnd, IDC_PL_RULES_LIST, LB_ADDSTRING, 0, (LPARAM)szListItem ); + SendDlgItemMessage( m_hwnd, IDC_PL_RULES_LIST, LB_SETITEMDATA, nItemId, (LPARAM)pRule ); + + pRule = pRule->GetNext(); + } + + EnableWindow( GetDlgItem( m_hwnd, IDC_PL_RULES_LIST ), !bListEmpty ); + if ( bListEmpty ) + SendDlgItemMessage( m_hwnd, IDC_PL_RULES_LIST, LB_ADDSTRING, 0, (LPARAM)TranslateTS(_T("List has no rules, empty lists will be deleted then changes applied"))); + else + SendDlgItemMessage( m_hwnd, IDC_PL_RULES_LIST, LB_SETCURSEL, nLbSel, 0 ); + + PostMessage( m_hwnd, WM_COMMAND, MAKEWPARAM( IDC_PL_RULES_LIST, LBN_SELCHANGE ), 0 ); +} + +void CJabberDlgPrivacyLists::DrawNextRulePart(HDC hdc, COLORREF color, const TCHAR *text, RECT *rc) +{ + SetTextColor(hdc, color); + DrawText(hdc, text, lstrlen(text), rc, DT_LEFT|DT_NOPREFIX|DT_SINGLELINE|DT_VCENTER|DT_WORD_ELLIPSIS); + + SIZE sz; + GetTextExtentPoint32(hdc, text, lstrlen(text), &sz); + rc->left += sz.cx; +} + +void CJabberDlgPrivacyLists::DrawRuleAction(HDC hdc, COLORREF clLine1, COLORREF, CPrivacyListRule *pRule, RECT *rc) +{ + DrawNextRulePart(hdc, clLine1, pRule->GetAction() ? TranslateT("allow ") : TranslateT("deny "), rc); + if (!pRule->GetPackets() || (pRule->GetPackets() == JABBER_PL_RULE_TYPE_ALL)) + { + DrawNextRulePart(hdc, clLine1, TranslateT("all."), rc); + } else + { + bool needComma = false; + int itemCount = + ((pRule->GetPackets() & JABBER_PL_RULE_TYPE_MESSAGE) ? 1 : 0) + + ((pRule->GetPackets() & JABBER_PL_RULE_TYPE_PRESENCE_IN) ? 1 : 0) + + ((pRule->GetPackets() & JABBER_PL_RULE_TYPE_PRESENCE_OUT) ? 1 : 0) + + ((pRule->GetPackets() & JABBER_PL_RULE_TYPE_IQ) ? 1 : 0); + + if (pRule->GetPackets() & JABBER_PL_RULE_TYPE_MESSAGE) + { + --itemCount; + needComma = true; + DrawNextRulePart(hdc, clLine1, TranslateT("messages"), rc); + } + if (pRule->GetPackets() & JABBER_PL_RULE_TYPE_PRESENCE_IN) + { + --itemCount; + if (needComma) + DrawNextRulePart(hdc, clLine1, itemCount ? _T(", ") : TranslateT(" and "), rc); + needComma = true; + DrawNextRulePart(hdc, clLine1, TranslateT("incoming presences"), rc); + } + if (pRule->GetPackets() & JABBER_PL_RULE_TYPE_PRESENCE_OUT) + { + --itemCount; + if (needComma) + DrawNextRulePart(hdc, clLine1, itemCount ? _T(", ") : TranslateT(" and "), rc); + needComma = true; + DrawNextRulePart(hdc, clLine1, TranslateT("outgoing presences"), rc); + } + if (pRule->GetPackets() & JABBER_PL_RULE_TYPE_IQ) + { + --itemCount; + if (needComma) + DrawNextRulePart(hdc, clLine1, itemCount ? _T(", ") : TranslateT(" and "), rc); + needComma = true; + DrawNextRulePart(hdc, clLine1, TranslateT("queries"), rc); + } + DrawNextRulePart(hdc, clLine1, _T("."), rc); + } +} + +void CJabberDlgPrivacyLists::DrawRulesList(LPDRAWITEMSTRUCT lpdis) +{ + if (lpdis->itemID == -1) + return; + + CPrivacyListRule *pRule = (CPrivacyListRule *)lpdis->itemData; + + COLORREF clLine1, clLine2, clBack; + if (lpdis->itemState & ODS_SELECTED) + { + FillRect(lpdis->hDC, &lpdis->rcItem, GetSysColorBrush(COLOR_HIGHLIGHT)); + clBack = GetSysColor(COLOR_HIGHLIGHT); + clLine1 = GetSysColor(COLOR_HIGHLIGHTTEXT); + } else + { + FillRect(lpdis->hDC, &lpdis->rcItem, GetSysColorBrush(COLOR_WINDOW)); + clBack = GetSysColor(COLOR_WINDOW); + clLine1 = GetSysColor(COLOR_WINDOWTEXT); + } + clLine2 = RGB( + GetRValue(clLine1) * 0.66 + GetRValue(clBack) * 0.34, + GetGValue(clLine1) * 0.66 + GetGValue(clBack) * 0.34, + GetBValue(clLine1) * 0.66 + GetBValue(clBack) * 0.34 + ); + + SetBkMode(lpdis->hDC, TRANSPARENT); + + RECT rc; + + if ( !pRule ) { + rc = lpdis->rcItem; + rc.left += 25; + + int len = SendDlgItemMessage(m_hwnd, lpdis->CtlID, LB_GETTEXTLEN, lpdis->itemID, 0) + 1; + TCHAR *str = (TCHAR *)_alloca(len * sizeof(TCHAR)); + SendDlgItemMessage(m_hwnd, lpdis->CtlID, LB_GETTEXT, lpdis->itemID, (LPARAM)str); + DrawNextRulePart(lpdis->hDC, clLine1, str, &rc); + } + else if (pRule->GetType() == Else) { + rc = lpdis->rcItem; + rc.left += 25; + + DrawNextRulePart(lpdis->hDC, clLine2, TranslateT("Else "), &rc); + DrawRuleAction(lpdis->hDC, clLine1, clLine2, pRule, &rc); + } + else { + rc = lpdis->rcItem; + rc.bottom -= (rc.bottom - rc.top) / 2; + rc.left += 25; + + switch ( pRule->GetType() ) + { + case Jid: + { + DrawNextRulePart(lpdis->hDC, clLine2, TranslateT("If jabber id is '"), &rc); + DrawNextRulePart(lpdis->hDC, clLine1, pRule->GetValue(), &rc); + DrawNextRulePart(lpdis->hDC, clLine2, TranslateT("'"), &rc); + + if (HANDLE hContact = m_proto->HContactFromJID(pRule->GetValue())) { + TCHAR *szName = (TCHAR *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_TCHAR); + if ( szName ) { + DrawNextRulePart(lpdis->hDC, clLine2, TranslateT(" (nickname: "), &rc); + DrawNextRulePart(lpdis->hDC, clLine1, szName, &rc); + DrawNextRulePart(lpdis->hDC, clLine2, TranslateT(")"), &rc); + } } + break; + } + + case Group: + DrawNextRulePart(lpdis->hDC, clLine2, TranslateT("If group is '"), &rc); + DrawNextRulePart(lpdis->hDC, clLine1, pRule->GetValue(), &rc); + DrawNextRulePart(lpdis->hDC, clLine2, TranslateT("'"), &rc); + break; + case Subscription: + DrawNextRulePart(lpdis->hDC, clLine2, TranslateT("If subscription is '"), &rc); + DrawNextRulePart(lpdis->hDC, clLine1, pRule->GetValue(), &rc); + DrawNextRulePart(lpdis->hDC, clLine2, TranslateT("'"), &rc); + break; + } + + rc = lpdis->rcItem; + rc.top += (rc.bottom - rc.top) / 2; + rc.left += 25; + + DrawNextRulePart(lpdis->hDC, clLine2, TranslateT("then "), &rc); + DrawRuleAction(lpdis->hDC, clLine1, clLine2, pRule, &rc); + } + + DrawIconEx(lpdis->hDC, lpdis->rcItem.left+4, (lpdis->rcItem.top+lpdis->rcItem.bottom-16)/2, + m_proto->LoadIconEx("main"), 16, 16, 0, NULL, DI_NORMAL); + + if (pRule) + { + DrawIconEx(lpdis->hDC, lpdis->rcItem.left+4, (lpdis->rcItem.top+lpdis->rcItem.bottom-16)/2, + m_proto->LoadIconEx(pRule->GetAction() ? "disco_ok" : "disco_fail"), + 16, 16, 0, NULL, DI_NORMAL); + } + + if (lpdis->itemState & ODS_FOCUS) + { + LRESULT sel = SendDlgItemMessage(m_hwnd, lpdis->CtlID, LB_GETCURSEL, 0, 0); + if ((sel == LB_ERR) || (sel == (LRESULT)lpdis->itemID)) + DrawFocusRect(lpdis->hDC, &lpdis->rcItem); + } +} + +void CJabberDlgPrivacyLists::DrawLists(LPDRAWITEMSTRUCT lpdis) +{ + if (lpdis->itemID == -1) + return; + + CPrivacyList *pList = (CPrivacyList *)lpdis->itemData; + + COLORREF clLine1, clLine2, clBack; + if (lpdis->itemState & ODS_SELECTED) + { + FillRect(lpdis->hDC, &lpdis->rcItem, GetSysColorBrush(COLOR_HIGHLIGHT)); + clBack = GetSysColor(COLOR_HIGHLIGHT); + clLine1 = GetSysColor(COLOR_HIGHLIGHTTEXT); + } else + { + FillRect(lpdis->hDC, &lpdis->rcItem, GetSysColorBrush(COLOR_WINDOW)); + clBack = GetSysColor(COLOR_WINDOW); + clLine1 = GetSysColor(COLOR_WINDOWTEXT); + } + clLine2 = RGB( + GetRValue(clLine1) * 0.66 + GetRValue(clBack) * 0.34, + GetGValue(clLine1) * 0.66 + GetGValue(clBack) * 0.34, + GetBValue(clLine1) * 0.66 + GetBValue(clBack) * 0.34 + ); + + SetBkMode(lpdis->hDC, TRANSPARENT); + + RECT rc; + m_proto->m_privacyListManager.Lock(); + TCHAR *szDefault = NEWTSTR_ALLOCA(m_proto->m_privacyListManager.GetDefaultListName()); + TCHAR *szActive = NEWTSTR_ALLOCA(m_proto->m_privacyListManager.GetActiveListName()); + m_proto->m_privacyListManager.Unlock(); + + rc = lpdis->rcItem; + rc.left +=3; + + bool bActive = false; + bool bDefault = false; + TCHAR *szName; + + if (!pList) + { + if (!szActive) bActive = true; + if (!szDefault) bDefault = true; + szName = TranslateT(""); + } else + { + if (!lstrcmp(pList->GetListName(), szActive)) bActive = true; + if (!lstrcmp(pList->GetListName(), szDefault)) bDefault = true; + szName = pList->GetListName(); + } + + HFONT hfnt = NULL; + if (bActive) + { + LOGFONT lf; + GetObject(GetCurrentObject(lpdis->hDC, OBJ_FONT), sizeof(lf), &lf); + lf.lfWeight = FW_BOLD; + hfnt = (HFONT)SelectObject(lpdis->hDC, CreateFontIndirect(&lf)); + } + + DrawNextRulePart(lpdis->hDC, clLine1, szName, &rc); + + if (bActive && bDefault) + DrawNextRulePart(lpdis->hDC, clLine2, TranslateT(" (act., def.)"), &rc); + else if (bActive) + DrawNextRulePart(lpdis->hDC, clLine2, TranslateT(" (active)"), &rc); + else if (bDefault) + DrawNextRulePart(lpdis->hDC, clLine2, TranslateT(" (default)"), &rc); + + DrawIconEx(lpdis->hDC, lpdis->rcItem.right-16-4, (lpdis->rcItem.top+lpdis->rcItem.bottom-16)/2, + m_proto->LoadIconEx(bActive ? "pl_list_active" : "pl_list_any"), + 16, 16, 0, NULL, DI_NORMAL); + + if (bDefault) + DrawIconEx(lpdis->hDC, lpdis->rcItem.right-16-4, (lpdis->rcItem.top+lpdis->rcItem.bottom-16)/2, + m_proto->LoadIconEx("disco_ok"), + 16, 16, 0, NULL, DI_NORMAL); + + if (hfnt) + DeleteObject(SelectObject(lpdis->hDC, hfnt)); + + if (lpdis->itemState & ODS_FOCUS) + { + int sel = SendDlgItemMessage(m_hwnd, lpdis->CtlID, LB_GETCURSEL, 0, 0); + if ((sel == LB_ERR) || (sel == (int)lpdis->itemID)) + DrawFocusRect(lpdis->hDC, &lpdis->rcItem); + } +} + +void CJabberDlgPrivacyLists::CListResetOptions(HWND) +{ + m_clcClist.SetBkBitmap(0, NULL); + m_clcClist.SetBkColor(GetSysColor(COLOR_WINDOW)); + m_clcClist.SetGreyoutFlags(0); + m_clcClist.SetLeftMargin(4); + m_clcClist.SetIndent(10); + m_clcClist.SetHideEmptyGroups(false); + m_clcClist.SetHideOfflineRoot(false); + for (int i = 0; i <= FONTID_MAX; i++) + m_clcClist.SetTextColor(i, GetSysColor(COLOR_WINDOWTEXT)); +} + +void CJabberDlgPrivacyLists::CListFilter(HWND) +{ + for (HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + hContact; + hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0)) + { + char *proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + if (!proto || lstrcmpA(proto, m_proto->m_szModuleName)) + if (HANDLE hItem = m_clcClist.FindContact(hContact)) + m_clcClist.DeleteItem(hItem); + } +} + +bool CJabberDlgPrivacyLists::CListIsGroup(HANDLE hGroup) +{ + char idstr[33]; + _i64toa((INT_PTR)hGroup-1, idstr, 10); + + DBVARIANT dbv; + bool result = DBGetContactSettingTString(NULL, "CListGroups", idstr, &dbv) == 0; + if ( result ) + DBFreeVariant(&dbv); + + return result; +} + +HANDLE CJabberDlgPrivacyLists::CListFindGroupByName(TCHAR *name) +{ + char idstr[33]; + DBVARIANT dbv; + + HANDLE hGroup = 0; + + for (int i= 0; !hGroup; ++i) + { + _itoa(i, idstr, 10); + + if (DBGetContactSettingTString(NULL, "CListGroups", idstr, &dbv)) + break; + + if (!_tcscmp(dbv.ptszVal + 1, name)) + hGroup = (HANDLE)(i+1); + + DBFreeVariant(&dbv); + } + + return hGroup; +} + +void CJabberDlgPrivacyLists::CListResetIcons(HWND, HANDLE hItem, bool hide) +{ + for (int i = 0; i < 4; ++i) + m_clcClist.SetExtraImage(hItem, i, hide ? 0xFF : 0); +} + +void CJabberDlgPrivacyLists::CListSetupIcons(HWND, HANDLE hItem, int iSlot, DWORD dwProcess, BOOL bAction) +{ + if (dwProcess && !m_clcClist.GetExtraImage(hItem, iSlot)) + m_clcClist.SetExtraImage(hItem, iSlot, iSlot*2 + (bAction?1:2)); +} + +HANDLE CJabberDlgPrivacyLists::CListAddContact(HWND hwndList, TCHAR *jid) +{ + HANDLE hItem = 0; + + HANDLE hContact = m_proto->HContactFromJID(jid); + if ( !hContact ) { + hItem = clc_info.findJid(jid); + if (!hItem) + { + CLCINFOITEM cii = {0}; + cii.cbSize = sizeof(cii); + cii.pszText = jid; + hItem = m_clcClist.AddInfoItem(&cii); + CListResetIcons(hwndList, hItem); + clc_info.addJid(hItem, jid); + } + } else + { + hItem = m_clcClist.FindContact(hContact); + } + + return hItem; +} + +void CJabberDlgPrivacyLists::CListApplyList(HWND hwndList, CPrivacyList *pList) +{ + clc_info.pList = pList; + + bool bHideIcons = pList ? false : true; + + CListResetIcons(hwndList, clc_info.hItemDefault, bHideIcons); + CListResetIcons(hwndList, clc_info.hItemSubBoth, bHideIcons); + CListResetIcons(hwndList, clc_info.hItemSubFrom, bHideIcons); + CListResetIcons(hwndList, clc_info.hItemSubNone, bHideIcons); + CListResetIcons(hwndList, clc_info.hItemSubTo, bHideIcons); + + // group handles start with 1 (0 is "root") + for (int iGroup = 1; CListIsGroup((HANDLE)iGroup); ++iGroup) + { + HANDLE hItem = m_clcClist.FindGroup((HANDLE)iGroup); + if (!hItem) continue; + CListResetIcons(hwndList, hItem, bHideIcons); + } + + for (HANDLE hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0); hContact; + hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact,0)) + { + HANDLE hItem = m_clcClist.FindContact(hContact); + if (!hItem) continue; + CListResetIcons(hwndList, hItem, bHideIcons); + } + + for (int iJid = 0; iJid < clc_info.newJids.getCount(); ++iJid) + CListResetIcons(hwndList, clc_info.newJids[iJid]->hItem, bHideIcons); + + if (!pList) + goto lbl_return; + + CPrivacyListRule *pRule; + for (pRule = pList->GetFirstRule(); pRule; pRule = pRule->GetNext()) + { + HANDLE hItem = 0; + switch (pRule->GetType()) + { + case Jid: + { + hItem = CListAddContact(hwndList, pRule->GetValue()); + break; + } + case Group: + { + HANDLE hGroup = CListFindGroupByName(pRule->GetValue()); + hItem = m_clcClist.FindGroup(hGroup); + break; + } + case Subscription: + { + if (!lstrcmp(pRule->GetValue(), _T("none"))) hItem = clc_info.hItemSubNone; + else if (!lstrcmp(pRule->GetValue(), _T("from"))) hItem = clc_info.hItemSubFrom; + else if (!lstrcmp(pRule->GetValue(), _T("to"))) hItem = clc_info.hItemSubTo; + else if (!lstrcmp(pRule->GetValue(), _T("both"))) hItem = clc_info.hItemSubBoth; + break; + } + case Else: + { + hItem = clc_info.hItemDefault; + break; + } + } + + if (!hItem) continue; + + DWORD dwPackets = pRule->GetPackets(); + if (!dwPackets) dwPackets = JABBER_PL_RULE_TYPE_ALL; + CListSetupIcons(hwndList, hItem, 0, dwPackets & JABBER_PL_RULE_TYPE_MESSAGE, pRule->GetAction()); + CListSetupIcons(hwndList, hItem, 1, dwPackets & JABBER_PL_RULE_TYPE_PRESENCE_IN, pRule->GetAction()); + CListSetupIcons(hwndList, hItem, 2, dwPackets & JABBER_PL_RULE_TYPE_PRESENCE_OUT, pRule->GetAction()); + CListSetupIcons(hwndList, hItem, 3, dwPackets & JABBER_PL_RULE_TYPE_IQ, pRule->GetAction()); + } + +lbl_return: + clc_info.bChanged = false; +} + +DWORD CJabberDlgPrivacyLists::CListGetPackets(HWND, HANDLE hItem, bool bAction) +{ + DWORD result = 0; + + int iIcon = 0; + + iIcon = m_clcClist.GetExtraImage(hItem, 0); + if ( bAction && (iIcon == 1)) result |= JABBER_PL_RULE_TYPE_MESSAGE; + else if (!bAction && (iIcon == 2)) result |= JABBER_PL_RULE_TYPE_MESSAGE; + + iIcon = m_clcClist.GetExtraImage(hItem, 1); + if ( bAction && (iIcon == 3)) result |= JABBER_PL_RULE_TYPE_PRESENCE_IN; + else if (!bAction && (iIcon == 4)) result |= JABBER_PL_RULE_TYPE_PRESENCE_IN; + + iIcon = m_clcClist.GetExtraImage(hItem, 2); + if ( bAction && (iIcon == 5)) result |= JABBER_PL_RULE_TYPE_PRESENCE_OUT; + else if (!bAction && (iIcon == 6)) result |= JABBER_PL_RULE_TYPE_PRESENCE_OUT; + + iIcon = m_clcClist.GetExtraImage(hItem, 3); + if ( bAction && (iIcon == 7)) result |= JABBER_PL_RULE_TYPE_IQ; + else if (!bAction && (iIcon == 8)) result |= JABBER_PL_RULE_TYPE_IQ; + + return result; +} + +void CJabberDlgPrivacyLists::CListBuildList(HWND hwndList, CPrivacyList *pList) +{ + if (!pList) return; + + if (!clc_info.bChanged) return; + + clc_info.bChanged = false; + + DWORD dwOrder = 0; + DWORD dwPackets = 0; + + HANDLE hItem; + TCHAR *szJid; + + pList->RemoveAllRules(); + + for (int iJid = 0; iJid < clc_info.newJids.getCount(); ++iJid) + { + hItem = clc_info.newJids[iJid]->hItem; + szJid = clc_info.newJids[iJid]->jid; + + if (dwPackets = CListGetPackets(hwndList, hItem, true)) + pList->AddRule(Jid, szJid, TRUE, dwOrder++, dwPackets); + if (dwPackets = CListGetPackets(hwndList, hItem, false)) + pList->AddRule(Jid, szJid, FALSE, dwOrder++, dwPackets); + } + + for (HANDLE hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0); hContact; + hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact,0)) + { + hItem = m_clcClist.FindContact(hContact); + + DBVARIANT dbv = {0}; + if ( m_proto->JGetStringT(hContact, "jid", &dbv)) { + if ( m_proto->JGetStringT(hContact, "ChatRoomID", &dbv)) + continue; + } + + szJid = dbv.ptszVal; + + if (dwPackets = CListGetPackets(hwndList, hItem, true)) + pList->AddRule(Jid, szJid, TRUE, dwOrder++, dwPackets); + if (dwPackets = CListGetPackets(hwndList, hItem, false)) + pList->AddRule(Jid, szJid, FALSE, dwOrder++, dwPackets); + + JFreeVariant(&dbv); + } + + // group handles start with 1 (0 is "root") + for (int iGroup = 1; ; ++iGroup) + { + char idstr[33]; + _itoa(iGroup-1, idstr, 10); + DBVARIANT dbv = {0}; + if (DBGetContactSettingTString(NULL, "CListGroups", idstr, &dbv)) + break; + + hItem = m_clcClist.FindGroup((HANDLE)iGroup); + szJid = dbv.ptszVal+1; + + if (dwPackets = CListGetPackets(hwndList, hItem, true)) + pList->AddRule(Group, szJid, TRUE, dwOrder++, dwPackets); + if (dwPackets = CListGetPackets(hwndList, hItem, false)) + pList->AddRule(Group, szJid, FALSE, dwOrder++, dwPackets); + + DBFreeVariant(&dbv); + } + + hItem = clc_info.hItemSubBoth; + szJid = _T("both"); + if (dwPackets = CListGetPackets(hwndList, hItem, true)) + pList->AddRule(Subscription, szJid, TRUE, dwOrder++, dwPackets); + if (dwPackets = CListGetPackets(hwndList, hItem, false)) + pList->AddRule(Subscription, szJid, FALSE, dwOrder++, dwPackets); + + hItem = clc_info.hItemSubFrom; + szJid = _T("from"); + if (dwPackets = CListGetPackets(hwndList, hItem, true)) + pList->AddRule(Subscription, szJid, TRUE, dwOrder++, dwPackets); + if (dwPackets = CListGetPackets(hwndList, hItem, false)) + pList->AddRule(Subscription, szJid, FALSE, dwOrder++, dwPackets); + + hItem = clc_info.hItemSubNone; + szJid = _T("none"); + if (dwPackets = CListGetPackets(hwndList, hItem, true)) + pList->AddRule(Subscription, szJid, TRUE, dwOrder++, dwPackets); + if (dwPackets = CListGetPackets(hwndList, hItem, false)) + pList->AddRule(Subscription, szJid, FALSE, dwOrder++, dwPackets); + + hItem = clc_info.hItemSubTo; + szJid = _T("to"); + if (dwPackets = CListGetPackets(hwndList, hItem, true)) + pList->AddRule(Subscription, szJid, TRUE, dwOrder++, dwPackets); + if (dwPackets = CListGetPackets(hwndList, hItem, false)) + pList->AddRule(Subscription, szJid, FALSE, dwOrder++, dwPackets); + + hItem = clc_info.hItemDefault; + szJid = NULL; + if (dwPackets = CListGetPackets(hwndList, hItem, true)) + pList->AddRule(Else, szJid, TRUE, dwOrder++, dwPackets); + if (dwPackets = CListGetPackets(hwndList, hItem, false)) + pList->AddRule(Else, szJid, FALSE, dwOrder++, dwPackets); + + pList->Reorder(); + pList->SetModified(); +} + +void CJabberDlgPrivacyLists::EnableEditorControls() +{ + m_proto->m_privacyListManager.Lock(); + BOOL bListsLoaded = m_proto->m_privacyListManager.IsAllListsLoaded(); + BOOL bListsModified = m_proto->m_privacyListManager.IsModified() || clc_info.bChanged; + m_proto->m_privacyListManager.Unlock(); + + int nCurSel = SendDlgItemMessage( m_hwnd, IDC_PL_RULES_LIST, LB_GETCURSEL, 0, 0 ); + int nItemCount = SendDlgItemMessage( m_hwnd, IDC_PL_RULES_LIST, LB_GETCOUNT, 0, 0 ); + BOOL bSelected = nCurSel != CB_ERR; + BOOL bListSelected = SendDlgItemMessage( m_hwnd, IDC_LB_LISTS, LB_GETCOUNT, 0, 0); + bListSelected = bListSelected && (SendDlgItemMessage( m_hwnd, IDC_LB_LISTS, LB_GETCURSEL, 0, 0) != LB_ERR); + bListSelected = bListSelected && SendDlgItemMessage( m_hwnd, IDC_LB_LISTS, LB_GETITEMDATA, SendDlgItemMessage( m_hwnd, IDC_LB_LISTS, LB_GETCURSEL, 0, 0), 0); + + EnableWindow( GetDlgItem( m_hwnd, IDC_TXT_OTHERJID ), bListsLoaded && bListSelected ); + EnableWindow( GetDlgItem( m_hwnd, IDC_NEWJID ), bListsLoaded && bListSelected ); + EnableWindow( GetDlgItem( m_hwnd, IDC_ADDJID ), bListsLoaded && bListSelected ); + + EnableWindow( GetDlgItem( m_hwnd, IDC_ADD_RULE ), bListsLoaded && bListSelected ); + EnableWindow( GetDlgItem( m_hwnd, IDC_EDIT_RULE ), bListsLoaded && bSelected ); + EnableWindow( GetDlgItem( m_hwnd, IDC_REMOVE_RULE ), bListsLoaded && bSelected ); + EnableWindow( GetDlgItem( m_hwnd, IDC_UP_RULE ), bListsLoaded && bSelected && nCurSel != 0 ); + EnableWindow( GetDlgItem( m_hwnd, IDC_DOWN_RULE ), bListsLoaded && bSelected && nCurSel != ( nItemCount - 1 )); + EnableWindow( GetDlgItem( m_hwnd, IDC_REMOVE_LIST ), bListsLoaded && bListSelected ); + EnableWindow( GetDlgItem( m_hwnd, IDC_APPLY ), bListsLoaded && bListsModified ); + + if (bListsLoaded) + SetStatusText( TranslateT("Ready.") ); +} + +LRESULT CALLBACK CJabberDlgPrivacyLists::LstListsSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + WNDPROC sttOldWndProc = (WNDPROC)GetWindowLongPtr(hwnd, GWLP_USERDATA); + switch (msg) + { + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + { + if (wParam == VK_INSERT) + return UIEmulateBtnClick(GetParent(hwnd), IDC_ADD_LIST); + if (wParam == VK_DELETE) + return UIEmulateBtnClick(GetParent(hwnd), IDC_REMOVE_LIST); + if (wParam == VK_SPACE) + { + if (GetAsyncKeyState(VK_CONTROL)) + return UIEmulateBtnClick(GetParent(hwnd), IDC_SET_DEFAULT); + return UIEmulateBtnClick(GetParent(hwnd), IDC_ACTIVATE); + } + + break; + } + } + return CallWindowProc(sttOldWndProc, hwnd, msg, wParam, lParam); +} + +LRESULT CALLBACK CJabberDlgPrivacyLists::LstRulesSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + WNDPROC sttOldWndProc = (WNDPROC)GetWindowLongPtr(hwnd, GWLP_USERDATA); + switch (msg) + { + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + { + if (wParam == VK_INSERT) + return UIEmulateBtnClick(GetParent(hwnd), IDC_ADD_RULE); + if (wParam == VK_DELETE) + return UIEmulateBtnClick(GetParent(hwnd), IDC_REMOVE_RULE); + if ((wParam == VK_UP) && (lParam & (1UL << 29))) + return UIEmulateBtnClick(GetParent(hwnd), IDC_UP_RULE); + if ((wParam == VK_DOWN) && (lParam & (1UL << 29))) + return UIEmulateBtnClick(GetParent(hwnd), IDC_DOWN_RULE); + if (wParam == VK_F2) + return UIEmulateBtnClick(GetParent(hwnd), IDC_EDIT_RULE); + + break; + } + } + return CallWindowProc(sttOldWndProc, hwnd, msg, wParam, lParam); +} + +BOOL CJabberDlgPrivacyLists::CanExit() +{ + m_proto->m_privacyListManager.Lock(); + BOOL bModified = m_proto->m_privacyListManager.IsModified(); + m_proto->m_privacyListManager.Unlock(); + + if (clc_info.bChanged) + bModified = TRUE; + + if ( !bModified ) + return TRUE; + + if ( IDYES == MessageBox( m_hwnd, TranslateT("Privacy lists are not saved, discard any changes and exit?"), TranslateT("Are you sure?"), MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON2 )) + return TRUE; + + return FALSE; +} + +void CJabberDlgPrivacyLists::btnSimple_OnClick(CCtrlButton *) +{ + CheckDlgButton(m_hwnd, IDC_BTN_SIMPLE, TRUE); + CheckDlgButton(m_hwnd, IDC_BTN_ADVANCED, FALSE); + UIShowControls(m_hwnd, idSimpleControls, SW_SHOW); + UIShowControls(m_hwnd, idAdvancedControls, SW_HIDE); + CListApplyList(GetDlgItem(m_hwnd, IDC_CLIST), GetSelectedList(m_hwnd)); +} + +void CJabberDlgPrivacyLists::btnAdvanced_OnClick(CCtrlButton *) +{ + CheckDlgButton(m_hwnd, IDC_BTN_SIMPLE, FALSE); + CheckDlgButton(m_hwnd, IDC_BTN_ADVANCED, TRUE); + UIShowControls(m_hwnd, idSimpleControls, SW_HIDE); + UIShowControls(m_hwnd, idAdvancedControls, SW_SHOW); + CListBuildList(GetDlgItem(m_hwnd, IDC_CLIST), GetSelectedList(m_hwnd)); + PostMessage(m_hwnd, WM_COMMAND, MAKEWPARAM(IDC_LB_LISTS, LBN_SELCHANGE), 0); +} + +void CJabberDlgPrivacyLists::btnAddJid_OnClick(CCtrlButton *) +{ + int len = GetWindowTextLength(GetDlgItem(m_hwnd, IDC_NEWJID))+1; + TCHAR *buf = (TCHAR *)_alloca(sizeof(TCHAR) * len); + GetWindowText(GetDlgItem(m_hwnd, IDC_NEWJID), buf, len); + SetWindowText(GetDlgItem(m_hwnd, IDC_NEWJID), _T("")); + CListAddContact(GetDlgItem(m_hwnd, IDC_CLIST), buf); +} + +void CJabberDlgPrivacyLists::btnActivate_OnClick(CCtrlButton *) +{ + if ( m_proto->m_bJabberOnline ) + { + m_proto->m_privacyListManager.Lock(); + CPrivacyList* pList = GetSelectedList(m_hwnd); + if ( pList && pList->IsModified() ) { + m_proto->m_privacyListManager.Unlock(); + MessageBox( m_hwnd, TranslateT("Please save list before activating"), TranslateT("First, save the list"), MB_OK | MB_ICONSTOP ); + return; + } + EnableWindow( GetDlgItem( m_hwnd, IDC_ACTIVATE ), FALSE ); + SetWindowLongPtr( GetDlgItem( m_hwnd, IDC_ACTIVATE ), GWLP_USERDATA, (LONG_PTR)pList ); + XmlNodeIq iq( m_proto->m_iqManager.AddHandler( &CJabberProto::OnIqResultPrivacyListActive, JABBER_IQ_TYPE_SET, NULL, 0, -1, pList ) ); + HXML query = iq << XQUERY( _T(JABBER_FEAT_PRIVACY_LISTS)); + HXML active = query << XCHILD( _T("active")); + if ( pList ) + active << XATTR( _T("name"), pList->GetListName()); + m_proto->m_privacyListManager.Unlock(); + + SetStatusText(TranslateT( JABBER_PL_BUSY_MSG )); + + m_proto->m_ThreadInfo->send( iq ); + } +} + +void CJabberDlgPrivacyLists::btnSetDefault_OnClick(CCtrlButton *) +{ + if ( m_proto->m_bJabberOnline ) + { + m_proto->m_privacyListManager.Lock(); + CPrivacyList* pList = GetSelectedList(m_hwnd); + if ( pList && pList->IsModified() ) { + m_proto->m_privacyListManager.Unlock(); + MessageBox( m_hwnd, TranslateT("Please save list before you make it the default list"), TranslateT("First, save the list"), MB_OK | MB_ICONSTOP ); + return; + } + EnableWindow( GetDlgItem( m_hwnd, IDC_SET_DEFAULT ), FALSE ); + SetWindowLongPtr( GetDlgItem( m_hwnd, IDC_SET_DEFAULT ), GWLP_USERDATA, (LONG_PTR)pList ); + + XmlNodeIq iq( m_proto->m_iqManager.AddHandler( &CJabberProto::OnIqResultPrivacyListDefault, JABBER_IQ_TYPE_SET, NULL, 0, -1, pList ) ); + HXML query = iq << XQUERY( _T(JABBER_FEAT_PRIVACY_LISTS )); + HXML defaultTag = query << XCHILD( _T("default")); + if ( pList ) + xmlAddAttr( defaultTag, _T("name"), pList->GetListName() ); + m_proto->m_privacyListManager.Unlock(); + + SetStatusText(TranslateT( JABBER_PL_BUSY_MSG )); + + m_proto->m_ThreadInfo->send( iq ); + } +} + +void CJabberDlgPrivacyLists::lbLists_OnSelChange(CCtrlListBox *) +{ + LRESULT nCurSel = SendDlgItemMessage( m_hwnd, IDC_LB_LISTS, LB_GETCURSEL, 0, 0 ); + if ( nCurSel == LB_ERR ) + return; + + LRESULT nErr = SendDlgItemMessage( m_hwnd, IDC_LB_LISTS, LB_GETITEMDATA, nCurSel, 0 ); + if ( nErr == LB_ERR ) + return; + if ( nErr == 0 ) + { + if (IsWindowVisible(GetDlgItem(m_hwnd, IDC_CLIST))) + { + CListBuildList(GetDlgItem(m_hwnd, IDC_CLIST), clc_info.pList); + CListApplyList(GetDlgItem(m_hwnd, IDC_CLIST), NULL); + } else + { + EnableWindow( GetDlgItem( m_hwnd, IDC_PL_RULES_LIST ), FALSE ); + SendDlgItemMessage( m_hwnd, IDC_PL_RULES_LIST, LB_RESETCONTENT, 0, 0 ); + SendDlgItemMessage( m_hwnd, IDC_PL_RULES_LIST, LB_ADDSTRING, 0, (LPARAM)TranslateTS(_T("No list selected"))); + } + EnableEditorControls(); + return; + } + + m_proto->m_privacyListManager.Lock(); + if (IsWindowVisible(GetDlgItem(m_hwnd, IDC_CLIST))) + { + CListBuildList(GetDlgItem(m_hwnd, IDC_CLIST), clc_info.pList); + CListApplyList(GetDlgItem(m_hwnd, IDC_CLIST), (CPrivacyList* )nErr); + } + else ShowAdvancedList((CPrivacyList* )nErr); + + m_proto->m_privacyListManager.Unlock(); + + EnableEditorControls(); +} + +void CJabberDlgPrivacyLists::lbLists_OnDblClick(CCtrlListBox *) +{ + PostMessage( m_hwnd, WM_COMMAND, MAKEWPARAM( IDC_ACTIVATE, 0 ), 0 ); +} + +void CJabberDlgPrivacyLists::lbRules_OnSelChange(CCtrlListBox *) +{ + EnableEditorControls(); +} + +void CJabberDlgPrivacyLists::lbRules_OnDblClick(CCtrlListBox *) +{ + PostMessage( m_hwnd, WM_COMMAND, MAKEWPARAM( IDC_EDIT_RULE, 0 ), 0 ); +} + +void CJabberDlgPrivacyLists::btnEditRule_OnClick(CCtrlButton *) +{ + // FIXME: potential deadlock due to PLM lock while editing rule + m_proto->m_privacyListManager.Lock(); + { + CPrivacyListRule* pRule = GetSelectedRule( m_hwnd ); + CPrivacyList* pList = GetSelectedList(m_hwnd); + if ( pList && pRule ) { + CJabberDlgPrivacyRule dlgPrivacyRule(m_proto, m_hwnd, pRule); + int nResult = dlgPrivacyRule.DoModal(); + if ( nResult ) { + pList->SetModified(); + PostMessage( m_hwnd, WM_JABBER_REFRESH, 0, 0 ); + } } } + m_proto->m_privacyListManager.Unlock(); +} + +void CJabberDlgPrivacyLists::btnAddRule_OnClick(CCtrlButton *) +{ + // FIXME: potential deadlock due to PLM lock while editing rule + m_proto->m_privacyListManager.Lock(); + { + CPrivacyList* pList = GetSelectedList(m_hwnd); + if ( pList ) { + CPrivacyListRule* pRule = new CPrivacyListRule( m_proto, Jid, _T(""), FALSE ); + CJabberDlgPrivacyRule dlgPrivacyRule(m_proto, m_hwnd, pRule); + int nResult = dlgPrivacyRule.DoModal(); + if ( nResult ) { + pList->AddRule(pRule); + pList->Reorder(); + pList->SetModified(); + PostMessage( m_hwnd, WM_JABBER_REFRESH, 0, 0 ); + } + else delete pRule; + } } + m_proto->m_privacyListManager.Unlock(); +} + +void CJabberDlgPrivacyLists::btnRemoveRule_OnClick(CCtrlButton *) +{ + m_proto->m_privacyListManager.Lock(); + { + CPrivacyList* pList = GetSelectedList(m_hwnd); + CPrivacyListRule* pRule = GetSelectedRule( m_hwnd ); + + if ( pList && pRule ) { + pList->RemoveRule( pRule ); + int nCurSel = SendDlgItemMessage( m_hwnd, IDC_PL_RULES_LIST, LB_GETCURSEL, 0, 0 ); + int nItemCount = SendDlgItemMessage( m_hwnd, IDC_PL_RULES_LIST, LB_GETCOUNT, 0, 0 ); + SendDlgItemMessage( m_hwnd, IDC_PL_RULES_LIST, LB_SETCURSEL, nCurSel != nItemCount - 1 ? nCurSel : nCurSel - 1, 0 ); + pList->Reorder(); + pList->SetModified(); + PostMessage( m_hwnd, WM_JABBER_REFRESH, 0, 0 ); + } } + + m_proto->m_privacyListManager.Unlock(); +} + +void CJabberDlgPrivacyLists::btnUpRule_OnClick(CCtrlButton *) +{ + m_proto->m_privacyListManager.Lock(); + { + CPrivacyList* pList = GetSelectedList(m_hwnd); + CPrivacyListRule* pRule = GetSelectedRule( m_hwnd ); + int nCurSel = SendDlgItemMessage( m_hwnd, IDC_PL_RULES_LIST, LB_GETCURSEL, 0, 0 ); + + if ( pList && pRule && nCurSel ) { + pRule->SetOrder( pRule->GetOrder() - 11 ); + SendDlgItemMessage( m_hwnd, IDC_PL_RULES_LIST, LB_SETCURSEL, nCurSel - 1, 0 ); + pList->Reorder(); + pList->SetModified(); + PostMessage( m_hwnd, WM_JABBER_REFRESH, 0, 0 ); + } } + + m_proto->m_privacyListManager.Unlock(); +} + +void CJabberDlgPrivacyLists::btnDownRule_OnClick(CCtrlButton *) +{ + m_proto->m_privacyListManager.Lock(); + { + CPrivacyList* pList = GetSelectedList(m_hwnd); + CPrivacyListRule* pRule = GetSelectedRule( m_hwnd ); + int nCurSel = SendDlgItemMessage( m_hwnd, IDC_PL_RULES_LIST, LB_GETCURSEL, 0, 0 ); + int nItemCount = SendDlgItemMessage( m_hwnd, IDC_PL_RULES_LIST, LB_GETCOUNT, 0, 0 ); + + if ( pList && pRule && ( nCurSel != ( nItemCount - 1 ))) { + pRule->SetOrder( pRule->GetOrder() + 11 ); + SendDlgItemMessage( m_hwnd, IDC_PL_RULES_LIST, LB_SETCURSEL, nCurSel + 1, 0 ); + pList->Reorder(); + pList->SetModified(); + PostMessage( m_hwnd, WM_JABBER_REFRESH, 0, 0 ); + } } + + m_proto->m_privacyListManager.Unlock(); +} + +void CJabberDlgPrivacyLists::btnAddList_OnClick(CCtrlButton *) +{ + // FIXME: line length is hard coded in dialog procedure + CJabberDlgPrivacyAddList dlgPrivacyAddList(m_proto, m_hwnd); + int nRetVal = dlgPrivacyAddList.DoModal(); + if ( nRetVal && _tcslen( dlgPrivacyAddList.szLine ) ) { + m_proto->m_privacyListManager.Lock(); + CPrivacyList* pList = m_proto->m_privacyListManager.FindList( dlgPrivacyAddList.szLine ); + if ( !pList ) { + m_proto->m_privacyListManager.AddList( dlgPrivacyAddList.szLine ); + pList = m_proto->m_privacyListManager.FindList( dlgPrivacyAddList.szLine ); + if ( pList ) { + pList->SetModified( TRUE ); + pList->SetLoaded( TRUE ); + } + } + if ( pList ) + pList->SetDeleted( FALSE ); + int nSelected = SendDlgItemMessage( m_hwnd, IDC_LB_LISTS, LB_SELECTSTRING, -1, (LPARAM)dlgPrivacyAddList.szLine ); + if ( nSelected == CB_ERR ) { + nSelected = SendDlgItemMessage( m_hwnd, IDC_LB_LISTS, LB_ADDSTRING, 0, (LPARAM)dlgPrivacyAddList.szLine ); + SendDlgItemMessage( m_hwnd, IDC_LB_LISTS, LB_SETITEMDATA, nSelected, (LPARAM)pList ); + SendDlgItemMessage( m_hwnd, IDC_LB_LISTS, LB_SETCURSEL, nSelected, 0 ); + } + m_proto->m_privacyListManager.Unlock(); + PostMessage( m_hwnd, WM_JABBER_REFRESH, 0, 0 ); + } +} + +void CJabberDlgPrivacyLists::btnRemoveList_OnClick(CCtrlButton *) +{ + m_proto->m_privacyListManager.Lock(); + { + CPrivacyList* pList = GetSelectedList(m_hwnd); + if ( pList ) { + TCHAR *szListName = pList->GetListName(); + if ( ( m_proto->m_privacyListManager.GetActiveListName() && !_tcscmp( szListName, m_proto->m_privacyListManager.GetActiveListName())) + || ( m_proto->m_privacyListManager.GetDefaultListName() && !_tcscmp( szListName, m_proto->m_privacyListManager.GetDefaultListName()) )) { + m_proto->m_privacyListManager.Unlock(); + MessageBox( m_hwnd, TranslateTS(_T("Can't remove active or default list")), TranslateTS(_T("Sorry")), MB_OK | MB_ICONSTOP ); + return; + } + pList->SetDeleted(); + pList->SetModified(); + } } + + m_proto->m_privacyListManager.Unlock(); + PostMessage( m_hwnd, WM_JABBER_REFRESH, 0, 0 ); +} + +void CJabberDlgPrivacyLists::btnApply_OnClick(CCtrlButton *) +{ + if ( !m_proto->m_bJabberOnline ) { + SetStatusText(TranslateT("Unable to save list because you are currently offline.")); + return; + } + + m_proto->m_privacyListManager.Lock(); + { + if (IsWindowVisible(GetDlgItem(m_hwnd, IDC_CLIST))) + CListBuildList(GetDlgItem(m_hwnd, IDC_CLIST), clc_info.pList); + + CPrivacyListModifyUserParam *pUserData = NULL; + CPrivacyList* pList = m_proto->m_privacyListManager.GetFirstList(); + while ( pList ) { + if ( pList->IsModified() ) { + CPrivacyListRule* pRule = pList->GetFirstRule(); + if ( !pRule ) + pList->SetDeleted(); + if ( pList->IsDeleted() ) { + pList->RemoveAllRules(); + pRule = NULL; + } + pList->SetModified( FALSE ); + + if ( !pUserData ) + pUserData = new CPrivacyListModifyUserParam(); + + pUserData->m_dwCount++; + + XmlNodeIq iq( m_proto->m_iqManager.AddHandler( &CJabberProto::OnIqResultPrivacyListModify, JABBER_IQ_TYPE_SET, NULL, 0, -1, pUserData )); + HXML query = iq << XQUERY( _T(JABBER_FEAT_PRIVACY_LISTS )); + HXML listTag = query << XCHILD( _T("list")) << XATTR( _T("name"), pList->GetListName() ); + + while ( pRule ) { + HXML itemTag = listTag << XCHILD( _T("item")); + switch ( pRule->GetType() ) { + case Jid: + itemTag << XATTR( _T("type"), _T("jid")); + break; + case Group: + itemTag << XATTR( _T("type"), _T("group")); + break; + case Subscription: + itemTag << XATTR( _T("type"), _T("subscription")); + break; + } + if ( pRule->GetType() != Else ) + itemTag << XATTR( _T("value"), pRule->GetValue() ); + if ( pRule->GetAction() ) + itemTag << XATTR( _T("action"), _T("allow")); + else + itemTag << XATTR( _T("action"), _T("deny")); + itemTag << XATTRI( _T("order"), pRule->GetOrder() ); + DWORD dwPackets = pRule->GetPackets(); + if ( dwPackets != JABBER_PL_RULE_TYPE_ALL ) { + if ( dwPackets & JABBER_PL_RULE_TYPE_IQ ) + itemTag << XCHILD( _T("iq")); + if ( dwPackets & JABBER_PL_RULE_TYPE_PRESENCE_IN ) + itemTag << XCHILD( _T("presence-in")); + if ( dwPackets & JABBER_PL_RULE_TYPE_PRESENCE_OUT ) + itemTag << XCHILD( _T("presence-out")); + if ( dwPackets & JABBER_PL_RULE_TYPE_MESSAGE ) + itemTag << XCHILD( _T("message")); + } + pRule = pRule->GetNext(); + } + + m_proto->m_ThreadInfo->send( iq ); + } + pList = pList->GetNext(); + } } + m_proto->m_privacyListManager.Unlock(); + SetStatusText(TranslateT( JABBER_PL_BUSY_MSG )); + PostMessage( m_hwnd, WM_JABBER_REFRESH, 0, 0 ); +} + +void CJabberDlgPrivacyLists::OnCommand_Close(HWND /*hwndCtrl*/, WORD /*idCtrl*/, WORD /*idCode*/) +{ + if (IsWindowVisible(GetDlgItem(m_hwnd, IDC_CLIST))) + CListBuildList(GetDlgItem(m_hwnd, IDC_CLIST), clc_info.pList); + + if (CanExit()) + DestroyWindow(m_hwnd); +} + +void CJabberDlgPrivacyLists::clcClist_OnUpdate(CCtrlClc::TEventInfo*) +{ + CListFilter(GetDlgItem(m_hwnd, IDC_CLIST)); + CListApplyList(GetDlgItem(m_hwnd, IDC_CLIST), GetSelectedList(m_hwnd)); +} + +void CJabberDlgPrivacyLists::clcClist_OnOptionsChanged(CCtrlClc::TEventInfo*) +{ + CListResetOptions(GetDlgItem(m_hwnd, IDC_CLIST)); + CListApplyList(GetDlgItem(m_hwnd, IDC_CLIST), GetSelectedList(m_hwnd)); +} + +void CJabberDlgPrivacyLists::clcClist_OnClick(CCtrlClc::TEventInfo *evt) +{ + HANDLE hItem; + DWORD hitFlags; + int iImage; + + if(evt->info->iColumn==-1) return; + hItem = m_clcClist.HitTest(evt->info->pt.x, evt->info->pt.y, &hitFlags); + if(hItem==NULL) return; + if(!(hitFlags&CLCHT_ONITEMEXTRA)) return; + + iImage = m_clcClist.GetExtraImage(hItem, evt->info->iColumn); + if (iImage != 0xFF) + { + if (iImage == 0) + iImage = evt->info->iColumn * 2 + 2; + else if (iImage == evt->info->iColumn * 2 + 2) + iImage = evt->info->iColumn * 2 + 1; + else + iImage = 0; + + m_clcClist.SetExtraImage(hItem, evt->info->iColumn, iImage); + + clc_info.bChanged = true; + + EnableEditorControls(); + } +} + +int CJabberDlgPrivacyLists::Resizer(UTILRESIZECONTROL *urc) +{ + switch (urc->wId) { + case IDC_HEADERBAR: + return RD_ANCHORX_LEFT|RD_ANCHORY_TOP|RD_ANCHORX_WIDTH; + case IDC_BTN_SIMPLE: + case IDC_BTN_ADVANCED: + return RD_ANCHORX_RIGHT|RD_ANCHORY_TOP; + case IDC_LB_LISTS: + return RD_ANCHORX_LEFT|RD_ANCHORY_TOP|RD_ANCHORY_HEIGHT; + case IDC_PL_RULES_LIST: + case IDC_CLIST: + return RD_ANCHORX_LEFT|RD_ANCHORY_TOP|RD_ANCHORY_HEIGHT|RD_ANCHORX_WIDTH; + case IDC_NEWJID: + case IDC_CANVAS: + return RD_ANCHORX_LEFT|RD_ANCHORX_WIDTH|RD_ANCHORY_BOTTOM; + case IDC_ADD_LIST: + case IDC_ACTIVATE: + case IDC_REMOVE_LIST: + case IDC_SET_DEFAULT: + case IDC_TXT_OTHERJID: + case IDC_ADD_RULE: + case IDC_UP_RULE: + case IDC_EDIT_RULE: + case IDC_DOWN_RULE: + case IDC_REMOVE_RULE: + return RD_ANCHORX_LEFT|RD_ANCHORY_BOTTOM; + case IDC_ADDJID: + case IDC_APPLY: + case IDCANCEL: + return RD_ANCHORX_RIGHT|RD_ANCHORY_BOTTOM; + } + return CSuper::Resizer(urc); +} + +INT_PTR __cdecl CJabberProto::OnMenuHandlePrivacyLists( WPARAM, LPARAM ) +{ + UI_SAFE_OPEN(CJabberDlgPrivacyLists, m_pDlgPrivacyLists); + return 0; +} + +void CJabberProto::QueryPrivacyLists( ThreadData *pThreadInfo ) +{ + XmlNodeIq iq( m_iqManager.AddHandler( &CJabberProto::OnIqResultPrivacyLists ) ); + iq << XQUERY( _T(JABBER_FEAT_PRIVACY_LISTS)); + if ( pThreadInfo ) + pThreadInfo->send( iq ); + else if ( m_ThreadInfo ) + m_ThreadInfo->send( iq ); +} + +///////////////////////////////////////////////////////////////////////////////////////// +// builds privacy menu + +INT_PTR __cdecl CJabberProto::menuSetPrivacyList( WPARAM, LPARAM, LPARAM iList ) +{ + m_privacyListManager.Lock(); + CPrivacyList *pList = NULL; + + if (iList) + { + pList = m_privacyListManager.GetFirstList(); + for (int i = 1; pList && (i < iList); ++i) + pList = pList->GetNext(); + } + + XmlNodeIq iq( m_iqManager.AddHandler( &CJabberProto::OnIqResultPrivacyListActive, JABBER_IQ_TYPE_SET, NULL, 0, -1, pList ) ); + HXML query = iq << XQUERY( _T(JABBER_FEAT_PRIVACY_LISTS)); + HXML active = query << XCHILD( _T("active")); + if ( pList ) + active << XATTR( _T("name"), pList->GetListName() ); + m_privacyListManager.Unlock(); + + m_ThreadInfo->send( iq ); + return 0; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// init privacy menu + +void CJabberProto::BuildPrivacyMenu() +{ + CLISTMENUITEM mi = { 0 }; + mi.cbSize = sizeof(mi); + mi.position = 200005; + mi.pszContactOwner = m_szModuleName; + mi.icolibItem = GetIconHandle(IDI_AGENTS); + mi.flags = CMIF_ROOTPOPUP | CMIF_CHILDPOPUP | CMIF_ICONFROMICOLIB | CMIF_HIDDEN; + mi.pszName = LPGEN("Privacy Lists"); + mi.hParentMenu = MO_GetProtoRootMenu( m_szModuleName ); + m_hPrivacyMenuRoot = ( HGENMENU )CallService( MS_CLIST_ADDPROTOMENUITEM, 0, ( LPARAM )&mi ); + + JCreateService( "/PrivacyLists", &CJabberProto::OnMenuHandlePrivacyLists ); + char srvFce[MAX_PATH + 64]; + mir_snprintf( srvFce, SIZEOF(srvFce), "%s/PrivacyLists", m_szModuleName ); + mi.pszService = srvFce; + mi.position = 3000040000; + mi.flags = CMIF_CHILDPOPUP | CMIF_TCHAR | CMIF_ICONFROMICOLIB; + mi.icolibItem = GetIconHandle(IDI_PRIVACY_LISTS); + mi.ptszName = LPGENT("List Editor..."); + mi.hParentMenu = m_hPrivacyMenuRoot; + CallService( MS_CLIST_ADDPROTOMENUITEM, 0, ( LPARAM )&mi ); +} + +void CJabberProto::BuildPrivacyListsMenu( bool bDeleteOld ) +{ + int i; + if ( bDeleteOld ) + for ( i=0; i < m_hPrivacyMenuItems.getCount(); i++ ) + JCallService( MO_REMOVEMENUITEM, (WPARAM)m_hPrivacyMenuItems[i], 0 ); + m_hPrivacyMenuItems.destroy(); + + m_privacyListManager.Lock(); + + i = 0; + char srvFce[MAX_PATH + 64], *svcName = srvFce+strlen( m_szModuleName ); + + CLISTMENUITEM mi = { 0 }; + mi.cbSize = sizeof(mi); + mi.position = 2000040000; + mi.flags = CMIF_CHILDPOPUP | CMIF_ICONFROMICOLIB | CMIF_TCHAR; + mi.hParentMenu = m_hPrivacyMenuRoot; + mi.pszService = srvFce; + + mir_snprintf( srvFce, SIZEOF(srvFce), "%s/menuPrivacy%d", m_szModuleName, i ); + if ( i > m_privacyMenuServiceAllocated ) { + JCreateServiceParam( svcName, &CJabberProto::menuSetPrivacyList, i ); + m_privacyMenuServiceAllocated = i; + } + mi.position++; + mi.icolibItem = LoadSkinnedIconHandle( + m_privacyListManager.GetActiveListName() ? + SKINICON_OTHER_SMALLDOT : + SKINICON_OTHER_EMPTYBLOB); + mi.ptszName = LPGENT(""); + m_hPrivacyMenuItems.insert(( HANDLE )CallService( MS_CLIST_ADDPROTOMENUITEM, 0, ( LPARAM )&mi )); + + for ( CPrivacyList *pList = m_privacyListManager.GetFirstList(); pList; pList = pList->GetNext()) { + ++i; + mir_snprintf( srvFce, SIZEOF(srvFce), "%s/menuPrivacy%d", m_szModuleName, i ); + + if ( i > m_privacyMenuServiceAllocated ) { + JCreateServiceParam( svcName, &CJabberProto::menuSetPrivacyList, i ); + m_privacyMenuServiceAllocated = i; + } + + mi.position++; + mi.icolibItem = LoadSkinnedIconHandle( + lstrcmp( m_privacyListManager.GetActiveListName(), pList->GetListName()) ? + SKINICON_OTHER_SMALLDOT : + SKINICON_OTHER_EMPTYBLOB); + mi.ptszName = pList->GetListName(); + m_hPrivacyMenuItems.insert(( HANDLE )CallService( MS_CLIST_ADDPROTOMENUITEM, 0, ( LPARAM )&mi )); + } + + m_privacyListManager.Unlock(); +} -- cgit v1.2.3