|
|
/////////////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 1997 Active Voice Corporation. All Rights Reserved.
//
// Active Agent(r) and Unified Communications(tm) are trademarks of Active Voice Corporation.
//
// Other brand and product names used herein are trademarks of their respective owners.
//
// The entire program and user interface including the structure, sequence, selection,
// and arrangement of the dialog, the exclusively "yes" and "no" choices represented
// by "1" and "2," and each dialog message are protected by copyrights registered in
// the United States and by international treaties.
//
// Protected by one or more of the following United States patents: 5,070,526, 5,488,650,
// 5,434,906, 5,581,604, 5,533,102, 5,568,540, 5,625,676, 5,651,054.
//
// Active Voice Corporation
// Seattle, Washington
// USA
//
/////////////////////////////////////////////////////////////////////////////////////////
// ConfExplorerDetailsView.cpp : Implementation of CConfExplorerDetailsView
#include "stdafx.h"
#include <stdio.h>
#include "TapiDialer.h"
#include "avTapi.h"
#include "CEDetailsVw.h"
#include "CETreeView.h"
#include "ConfExp.h"
#include "SDPBlb.h"
static UINT arCols[] = { IDS_EXPLORE_COLUMN_NAME, IDS_EXPLORE_COLUMN_PURPOSE, IDS_EXPLORE_COLUMN_STARTS, IDS_EXPLORE_COLUMN_ENDS, IDS_EXPLORE_COLUMN_ORIGINATOR };
// Sort function
static int CALLBACK CompareFunc( LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort ) { CConfExplorerDetailsView *p = (CConfExplorerDetailsView *) lParamSort; return ((CConfDetails *) lParam1)->Compare( (CConfDetails *) lParam2, p->IsSortAscending(), p->GetSortColumn(), p->GetSecondarySortColumn() ); }
/////////////////////////////////////////////////////////////////////////////
// CConfExplorerDetailsView
CConfExplorerDetailsView::CConfExplorerDetailsView() { m_pIConfExplorer = NULL; m_nSortColumn = 0; m_bSortAscending = true;
m_nUpdateCount = 0; }
void CConfExplorerDetailsView::FinalRelease() { ATLTRACE(_T(".enter.CConfExplorerDetailsView::FinalRelease().\n"));
DeleteAllItems(); put_hWnd( NULL ); put_ConfExplorer( NULL );
CComObjectRootEx<CComMultiThreadModel>::FinalRelease(); }
STDMETHODIMP CConfExplorerDetailsView::get_hWnd(HWND * pVal) { *pVal = m_wndList.m_hWnd; return S_OK; }
STDMETHODIMP CConfExplorerDetailsView::put_hWnd(HWND newVal) { // Load up image lists items for conferences
if ( IsWindow(newVal) ) { // Make sure the window isn't already subclassed
if ( m_wndList.m_hWnd ) m_wndList.UnsubclassWindow();
// Load listbox with items
if ( m_wndList.SubclassWindow(newVal)) { // Take over window to get sorting messages and other things
m_wndList.m_pDetailsView = this; m_wndList.PostMessage( WM_MYCREATE, 0, 0 ); } } else if ( IsWindow(m_wndList.m_hWnd) ) { put_Columns(); DeleteAllItems(); m_wndList.UnsubclassWindow(); m_wndList.m_pDetailsView = NULL; m_wndList.m_hWnd = NULL; }
return S_OK; }
bool CConfExplorerDetailsView::IsSortColumnDateBased(int nCol) const { bool bRet = false; switch ( nCol ) { case COL_STARTS: case COL_ENDS: bRet = true; break; }
return bRet; }
int CConfExplorerDetailsView::GetSecondarySortColumn() const { return (m_nSortColumn) ? COL_NAME : COL_STARTS; }
void CConfExplorerDetailsView::get_Columns() { #define CONFEXP_DEFAULT_WIDTH 125
// Load column settings from registry
USES_CONVERSION; CRegKey regKey; TCHAR szReg[255], szEntry[50];
LV_COLUMN lvc; lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; lvc.fmt = LVCFMT_LEFT; lvc.pszText = szReg;
LoadString( _Module.GetResourceInstance(), IDN_REG_CONFSERV_VIEW_KEY, szReg, ARRAYSIZE(szReg) ); regKey.Open( HKEY_CURRENT_USER, szReg, KEY_READ );
// Add the columns.
for ( int i = 0; i < ARRAYSIZE(arCols); i++ ) { lvc.iSubItem = i; lvc.cx = CONFEXP_DEFAULT_WIDTH;
// Load registry stuff if exists
if ( regKey.m_hKey ) { DWORD dwVal = 0;
// Get sort column and sort direction
LoadString( _Module.GetResourceInstance(), IDN_REG_CONFSERV_SORT_COLUMN, szReg, ARRAYSIZE(szReg) ); regKey.QueryValue( dwVal, szReg ); m_nSortColumn = (int) max(0, ((int)min(dwVal,ARRAYSIZE(arCols))));
LoadString( _Module.GetResourceInstance(), IDN_REG_CONFSERV_SORT_ASCENDING, szReg, ARRAYSIZE(szReg) ); regKey.QueryValue( dwVal, szReg ); m_bSortAscending = (bool) (dwVal > 0);
// Column Widths
LoadString( _Module.GetResourceInstance(), IDN_REG_CONFSERV_ENTRY, szReg, ARRAYSIZE(szReg) ); _sntprintf( szEntry, ARRAYSIZE(szEntry), szReg, i ); szEntry[ARRAYSIZE(szEntry)-1] = _T('\0'); dwVal = 0; if ( (regKey.QueryValue(dwVal, szEntry) == ERROR_SUCCESS) && (dwVal > 0) ) lvc.cx = (int) max(MIN_COL_WIDTH, min( 5000, dwVal ));
}
LoadString( _Module.GetResourceInstance(), arCols[i], szReg, ARRAYSIZE(szReg) ); ListView_InsertColumn( m_wndList.m_hWnd, i, &lvc ); } }
void CConfExplorerDetailsView::put_Columns() { // Save column setting to registry
USES_CONVERSION; CRegKey regKey; TCHAR szReg[100], szEntry[50];
LoadString( _Module.GetResourceInstance(), IDN_REG_CONFSERV_VIEW_KEY, szReg, ARRAYSIZE(szReg) ); if ( regKey.Create(HKEY_CURRENT_USER, szReg) == ERROR_SUCCESS ) { // Save sort column and sort direction
LoadString( _Module.GetResourceInstance(), IDN_REG_CONFSERV_SORT_COLUMN, szReg, ARRAYSIZE(szReg) ); regKey.SetValue( m_nSortColumn, szReg ); LoadString( _Module.GetResourceInstance(), IDN_REG_CONFSERV_SORT_ASCENDING, szReg, ARRAYSIZE(szReg) ); regKey.SetValue( m_bSortAscending, szReg );
// Save column widths
int nWidth; for ( int i = 0; i < ARRAYSIZE(arCols); i++ ) { nWidth = ListView_GetColumnWidth( m_wndList.m_hWnd, i );
LoadString( _Module.GetResourceInstance(), IDN_REG_CONFSERV_ENTRY, szReg, ARRAYSIZE(szReg) ); _sntprintf( szEntry, ARRAYSIZE(szEntry), szReg, i ); szEntry[ARRAYSIZE(szEntry)-1] = _T('\0'); regKey.SetValue( nWidth, szEntry ); } } }
STDMETHODIMP CConfExplorerDetailsView::Refresh() { HRESULT hr;
IConfExplorer *pConfExplorer; if ( SUCCEEDED(hr = get_ConfExplorer(&pConfExplorer)) ) { // Show hourglass
HCURSOR hCurOld = SetCursor( LoadCursor(NULL, IDC_WAIT) );
IConfExplorerTreeView *pView; if ( SUCCEEDED(hr = pConfExplorer->get_TreeView(&pView)) ) { BSTR bstrLocation = NULL, bstrServer = NULL; if ( SUCCEEDED(hr = pView->GetSelection(&bstrLocation, &bstrServer)) ) { pView->ForceConfServerForEnum( bstrServer ); DeleteAllItems(); }
SysFreeString( bstrLocation ); SysFreeString( bstrServer ); pView->Release(); }
put_Columns();
// Restore wait cursor
SetCursor( hCurOld ); pConfExplorer->Release(); } return hr; }
HRESULT CConfExplorerDetailsView::ShowConferencesAndPersons(BSTR bstrServer ) { USES_CONVERSION; IConfExplorer *pConfExplorer; ITDirectory *pDir;
//
// We should initialize the ocal variable
//
HRESULT hr = E_FAIL;
if ( SUCCEEDED(get_ConfExplorer(&pConfExplorer)) ) { if ( SUCCEEDED(hr = pConfExplorer->get_ConfDirectory(NULL, (IDispatch **) &pDir)) ) { // Enumerate through conferences adding them as we go along
IEnumDirectoryObject *pEnum; ITDirectoryObject *pITDirObject; long nCount;
// Enumerate list of conferences
if ( SUCCEEDED(hr = pDir->EnumerateDirectoryObjects(OT_CONFERENCE, A2BSTR("*"), &pEnum)) ) { nCount = 0; m_critConfList.Lock(); DELETE_LIST(m_lstConfs); while ( (nCount++ < MAX_ENUMLISTSIZE) && ((hr = pEnum->Next(1, &pITDirObject, NULL)) == S_OK) ) { _ASSERT( pITDirObject ); CConfDetails *p = AddListItem( bstrServer, pITDirObject, m_lstConfs ); pITDirObject->Release(); } m_critConfList.Unlock(); pEnum->Release(); }
// Retrieve the people in the ILS server
if ( SUCCEEDED(hr = pDir->EnumerateDirectoryObjects(OT_USER, A2BSTR("*"), &pEnum)) ) { nCount = 0; m_critConfList.Lock(); DELETE_LIST(m_lstPersons); while ( (nCount++ < MAX_ENUMLISTSIZE) && ((hr = pEnum->Next(1, &pITDirObject, NULL)) == S_OK) ) { _ASSERT( pITDirObject ); CPersonDetails *p = AddListItemPerson( bstrServer, pITDirObject, m_lstPersons ); pITDirObject->Release(); } m_critConfList.Unlock(); pEnum->Release(); }
pDir->Release();
// Put conferences in the listbox
UpdateConfList( NULL ); } pConfExplorer->Release(); }
return hr; }
STDMETHODIMP CConfExplorerDetailsView::get_Selection(DATE *pdateStart, DATE *pdateEnd, BSTR *pVal ) { if ( !IsWindow(m_wndList.m_hWnd) ) return E_PENDING;
HRESULT hr = E_FAIL;
m_critConfList.Lock(); for ( int i = 0; i < ListView_GetItemCount(m_wndList.m_hWnd); i++ ) { if ( ListView_GetItemState(m_wndList.m_hWnd, i, LVIS_SELECTED) ) { LV_ITEM lvi = {0}; lvi.iItem = i; lvi.mask = LVIF_PARAM; if ( ListView_GetItem(m_wndList.m_hWnd, &lvi) && lvi.lParam ) { *pVal = SysAllocString( ((CConfDetails *) lvi.lParam)->m_bstrName );
if ( pdateStart ) *pdateStart = ((CConfDetails *) lvi.lParam)->m_dateStart; if ( pdateEnd ) *pdateEnd = ((CConfDetails *) lvi.lParam)->m_dateEnd; hr = S_OK; break; } } } m_critConfList.Unlock();
return hr; }
STDMETHODIMP CConfExplorerDetailsView::get_ConfExplorer(IConfExplorer **ppVal) { HRESULT hr = E_PENDING; Lock(); if ( m_pIConfExplorer ) hr = m_pIConfExplorer->QueryInterface(IID_IConfExplorer, (void **) ppVal ); Unlock();
return hr; }
STDMETHODIMP CConfExplorerDetailsView::put_ConfExplorer(IConfExplorer * newVal) { HRESULT hr = S_OK;
Lock(); RELEASE( m_pIConfExplorer ); if ( newVal ) hr = newVal->QueryInterface( IID_IConfExplorer, (void **) &m_pIConfExplorer ); Unlock();
return hr; }
STDMETHODIMP CConfExplorerDetailsView::OnColumnClicked(long nColumn) { ATLTRACE(_T(".enter.CConfExplorerDetailsView::OnColumnClicked(%ld).\n"), nColumn ); if ( !IsWindow(m_wndList.m_hWnd) ) return E_PENDING; if ( ListView_GetColumnWidth(m_wndList.m_hWnd, nColumn) == 0 ) return E_INVALIDARG;
// Sort on column selected; if new column sort ascending
if ( m_nSortColumn == nColumn ) { m_bSortAscending = !m_bSortAscending; } else { m_nSortColumn = nColumn; m_bSortAscending = true; }
ListView_SortItems( m_wndList.m_hWnd, CompareFunc, (LPARAM) this ); return S_OK; }
void CConfExplorerDetailsView::DeleteAllItems() { if ( IsWindow(m_wndList.m_hWnd) ) ListView_DeleteAllItems( m_wndList.m_hWnd );
DELETE_CRITLIST(m_lstConfs, m_critConfList); DELETE_CRITLIST(m_lstPersons, m_critConfList); }
long CConfExplorerDetailsView::OnGetDispInfo( LV_DISPINFO *pInfo ) { USES_CONVERSION;
if ( pInfo && (pInfo->hdr.hwndFrom == m_wndList.m_hWnd) ) { switch( pInfo->hdr.code ) { case LVN_GETDISPINFO: // Write out the text
if ( pInfo->item.lParam ) { CConfDetails *pDetails = (CConfDetails *) pInfo->item.lParam;
///////////////////////////////////////////// Set image for item
if ( pInfo->item.mask & LVIF_IMAGE ) { CComPtr<IAVGeneralNotification> pAVGen;
if ( SUCCEEDED(_Module.get_AVGenNot(&pAVGen)) && (pAVGen->fire_IsReminderSet(pDetails->m_bstrServer, pDetails->m_bstrName) == S_OK) ) { // User has set a reminder
pInfo->item.iImage = IMAGE_REMINDER; } else { // Is the conference in session
DATE dateNow; SYSTEMTIME st; GetLocalTime( &st ); SystemTimeToVariantTime( &st, &dateNow ); DATE dateStart = pDetails->m_dateStart - (DATE) (.125 / 12 ); // drop back 15 minutes
if ( (dateStart <= dateNow) && (pDetails->m_dateEnd >= dateNow) ) pInfo->item.iImage = IMAGE_INSESSION; else pInfo->item.iImage = IMAGE_NONE; } }
////////////////////////////////////////////////////////// item state
if ( pInfo->item.mask & LVIF_STATE ) { // What type of media does the conference support?
switch ( pDetails->m_sdp.m_nConfMediaType ) { case CConfSDP::MEDIA_AUDIO: pInfo->item.state += INDEXTOSTATEIMAGEMASK( IMAGE_STATE_AUDIO ); break;
case CConfSDP::MEDIA_VIDEO: pInfo->item.state += INDEXTOSTATEIMAGEMASK( IMAGE_STATE_VIDEO ); break; } }
///////////////////////////////////////// Set text for item
if ( pInfo->item.mask & LVIF_TEXT ) { BSTR bstrTemp = NULL; switch ( pInfo->item.iSubItem ) { case COL_NAME: bstrTemp = SysAllocString( pDetails->m_bstrName ); break; case COL_PURPOSE: bstrTemp = SysAllocString( pDetails->m_bstrDescription ); break; case COL_ORIGINATOR: bstrTemp = SysAllocString( pDetails->m_bstrOriginator ); break; case COL_STARTS: VarBstrFromDate( pDetails->m_dateStart, LOCALE_USER_DEFAULT, NULL, &bstrTemp ); break; case COL_ENDS: VarBstrFromDate( pDetails->m_dateEnd, LOCALE_USER_DEFAULT, NULL, &bstrTemp ); break; default: _ASSERT( false ); } // Copy string
_tcsncpy( pInfo->item.pszText, (bstrTemp) ? OLE2CT(bstrTemp) : _T(""), pInfo->item.cchTextMax ); pInfo->item.pszText[pInfo->item.cchTextMax - 1] = 0; SysFreeString( bstrTemp ); } } break;
case LVN_SETDISPINFO: break; } }
return 0; }
STDMETHODIMP CConfExplorerDetailsView::UpdateConfList(long * pList) { // Keep count on the number of requests to update the conference
m_critUpdateList.Lock(); m_nUpdateCount++; m_critUpdateList.Unlock();
// If failed, request is queued
if ( TryEnterCriticalSection(&m_critConfList.m_sec) == FALSE ) return E_PENDING;
// Disable redraw
::SendMessage( m_wndList.m_hWnd, WM_SETREDRAW, false, 0 );
for ( ;; ) { // Check to see how many times we need to update the conference list
m_critUpdateList.Lock(); if ( m_nUpdateCount == 0 ) break; else m_nUpdateCount--; m_critUpdateList.Unlock();
///////////////////////////////////////////////////////////////////////////////////
// Clear out all items from the listbox
ListView_DeleteAllItems( m_wndList.m_hWnd );
// Copy list over
CONFDETAILSLIST::iterator i, iEnd; if ( pList ) { DELETE_LIST(m_lstConfs); iEnd = ((CONFDETAILSLIST *) pList)->end(); for ( i = ((CONFDETAILSLIST *) pList)->begin(); i != iEnd; i++ ) { CConfDetails *pDetails = new CConfDetails; if ( pDetails ) { *pDetails = *(*i); m_lstConfs.push_back( pDetails ); } } }
// Populate the details view
LV_ITEM lvi = {0}; lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE; lvi.pszText = LPSTR_TEXTCALLBACK; lvi.iImage = I_IMAGECALLBACK;
iEnd = m_lstConfs.end(); for ( i = m_lstConfs.begin(); i != iEnd; i++ ) { lvi.lParam = (LPARAM) *i; ListView_InsertItem( m_wndList.m_hWnd, &lvi ); } }
// Enable redraw prior to exiting crit
::SendMessage( m_wndList.m_hWnd, WM_SETREDRAW, true, 0 ); m_critConfList.Unlock(); m_critUpdateList.Unlock();
// Sort the list of items
ListView_SortItems( m_wndList.m_hWnd, CompareFunc, (LPARAM) this ); ::InvalidateRect(m_wndList.m_hWnd, NULL, true);
return S_OK; }
CConfDetails* CConfExplorerDetailsView::AddListItem( BSTR bstrServer, ITDirectoryObject *pITDirObject, CONFDETAILSLIST& lstConfs ) { _ASSERT( pITDirObject ); USES_CONVERSION;
// Create list box item and add to list
CConfDetails *p = new CConfDetails; if ( p ) { p->Populate( bstrServer, pITDirObject ); lstConfs.push_front( p ); }
return NULL; }
CPersonDetails* CConfExplorerDetailsView::AddListItemPerson( BSTR bstrServer, ITDirectoryObject *pITDirObject, PERSONDETAILSLIST& lstPersons ) { _ASSERT( pITDirObject ); USES_CONVERSION;
// Create list box item and add to list
CPersonDetails *p = new CPersonDetails; if ( p ) { p->Populate( bstrServer, pITDirObject ); lstPersons.push_front( p ); }
return NULL; }
STDMETHODIMP CConfExplorerDetailsView::get_bSortAscending(VARIANT_BOOL * pVal) { Lock(); *pVal = m_bSortAscending; Unlock();
return S_OK; }
STDMETHODIMP CConfExplorerDetailsView::get_nSortColumn(long * pVal) { Lock(); *pVal = m_nSortColumn; Unlock();
return S_OK; }
STDMETHODIMP CConfExplorerDetailsView::put_nSortColumn(long newVal) { return OnColumnClicked( newVal ); }
STDMETHODIMP CConfExplorerDetailsView::IsConferenceSelected() { if ( !IsWindow(m_wndList.m_hWnd) ) return E_PENDING;
for ( int i = 0; i < ListView_GetItemCount(m_wndList.m_hWnd); i++ ) { if ( ListView_GetItemState(m_wndList.m_hWnd, i, LVIS_SELECTED) ) return S_OK; }
return S_FALSE; }
STDMETHODIMP CConfExplorerDetailsView::get_SelectedConfDetails(long ** ppVal) { if ( !IsWindow(m_wndList.m_hWnd) ) return E_PENDING;
HRESULT hr = E_FAIL;
m_critConfList.Lock(); for ( int i = 0; i < ListView_GetItemCount(m_wndList.m_hWnd); i++ ) { if ( ListView_GetItemState(m_wndList.m_hWnd, i, LVIS_SELECTED) ) { LV_ITEM lvi = {0}; lvi.iItem = i; lvi.mask = LVIF_PARAM; if ( ListView_GetItem(m_wndList.m_hWnd, &lvi) && lvi.lParam ) { CConfDetails *pNew = new CConfDetails; if ( pNew ) { // copy this over
*pNew = *((CConfDetails *) lvi.lParam); *ppVal = (long *) pNew; hr = S_OK; } break; } } } m_critConfList.Unlock();
return hr; }
|