|
|
// qryprop.cpp - Query Property Page Implementation
#include "stdafx.h"
#include "resource.h"
#include "qryprop.h"
#include "compdata.h"
#include "scopenode.h"
#include "query.h"
#include "cmndlgs.h"
#include "util.h"
#include "namemap.h"
#define SECURITY_WIN32
#include <security.h> // TranslateName
#include <windowsx.h>
#include <algorithm>
#undef SubclassWindow
int GetDateTimeString(FILETIME* pftime, LPWSTR pszBuf, int cBuf); void LoadObjectCB(CComboBox& ComboBox, QueryObjVector& vObj);
#define CHECK_OFF INDEXTOSTATEIMAGEMASK(1)
#define CHECK_ON INDEXTOSTATEIMAGEMASK(2)
///////////////////////////////////////////////////////////////////////////////////////////
// CQueryGeneralPage
CQueryGeneralPage::CQueryGeneralPage(CQueryEditObj* pEditObj) : m_EditObject(*pEditObj) { ASSERT(pEditObj != NULL); m_EditObject.AddRef(); }
CQueryGeneralPage::~CQueryGeneralPage() { m_EditObject.Release(); }
LRESULT CQueryGeneralPage::OnInitDialog(UINT mMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { if( !m_EditObject.m_spQueryNode ) return 0;
// display query node icon
HICON hIcon = ::LoadIcon(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDI_QUERYNODE)); Static_SetIcon(GetDlgItem(IDC_QUERYICON), hIcon);
// fill dialog fields with query node info
tstring strTempQuery; m_EditObject.m_spQueryNode->ExpandQuery(strTempQuery);
CQueryNode* pQNode = m_EditObject.m_spQueryNode; SetDlgItemText( IDC_NAME, m_EditObject.m_spQueryNode->GetName() ); SetDlgItemText( IDC_FILTER, strTempQuery.c_str() );
tstring strComment; m_EditObject.m_spQueryNode->GetComment(strComment); SetDlgItemText( IDC_COMMENTS, strComment.c_str() );
Edit_LimitText(GetDlgItem(IDC_COMMENTS), 255);
// set scope source toggle button
UINT uButton = m_EditObject.m_spQueryNode->UseLocalScope() ? IDC_LOCALSCOPE : IDC_QUERYSCOPE; Button_SetCheck(GetDlgItem(uButton), BST_CHECKED);
tstring strScope = m_EditObject.m_spQueryNode->Scope(); tstring strDisplay; GetScopeDisplayString(strScope, strDisplay); SetDlgItemText( IDC_SCOPE, strDisplay.c_str() );
// if using local scope, then set the persisted scope equal to the local scope so that the
// user won't see an obsolete scope that may have been saved when creating the node.
if( m_EditObject.m_spQueryNode->UseLocalScope() ) m_EditObject.m_spQueryNode->SetScope(strScope.c_str());
// if classes known, display comma separated class names
if( m_EditObject.m_vObjInfo.size() != 0 ) { DisplayNameMap* pNameMap = DisplayNames::GetClassMap(); ASSERT(pNameMap != NULL); if( pNameMap != NULL ) { QueryObjVector::iterator itQObj = m_EditObject.m_vObjInfo.begin(); tstring strClasses = pNameMap->GetAttributeDisplayName(itQObj->Name());
for( itQObj++; itQObj != m_EditObject.m_vObjInfo.end(); ++itQObj ) { strClasses += L", "; strClasses += pNameMap->GetAttributeDisplayName(itQObj->Name()); }
SetDlgItemText( IDC_OBJCLASS, strClasses.c_str() ); } }
return TRUE; }
LRESULT CQueryGeneralPage::OnScopeChange(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { if( !m_EditObject.m_spQueryNode ) return 0;
// if user changes scope selection then display the correct scope
tstring strScope;
if( Button_GetCheck(GetDlgItem(IDC_LOCALSCOPE)) == BST_CHECKED ) strScope = GetLocalDomain(); else strScope = m_EditObject.m_spQueryNode->QueryScope();
tstring strDisplay; GetScopeDisplayString(strScope, strDisplay);
SetDlgItemText( IDC_SCOPE, strDisplay.c_str() );
SetModified(TRUE); return 0; }
LRESULT CQueryGeneralPage::OnChange(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { SetModified(TRUE); return 0; }
//------------------------------------------------------------------------------------
// CRootGeneralPage::OnClose
//
// This method is invoked when an edit box receives an Esc char. The method converts
// the WM_CLOSE message into a command to close the property sheet. Otherwise the
// WM_CLOSE message has no effect.
//------------------------------------------------------------------------------------
LRESULT CQueryGeneralPage::OnClose( UINT mMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled ) { // Simulate press of Cancel button
::PropSheet_PressButton(GetParent(), PSBTN_CANCEL);
return 0; }
BOOL CQueryGeneralPage::OnSetActive() { m_EditObject.PageActive(m_hWnd); return TRUE; }
BOOL CQueryGeneralPage::OnApply() { if( !m_EditObject.m_spQueryNode ) return FALSE;
tstring strComment; GetItemText(GetDlgItem(IDC_COMMENTS), strComment); m_EditObject.m_spQueryNode->SetComment(strComment.c_str());
bool bLocal = (Button_GetCheck(GetDlgItem(IDC_LOCALSCOPE)) == BST_CHECKED); m_EditObject.m_spQueryNode->SetLocalScope(bLocal);
return m_EditObject.ApplyChanges(m_hWnd); }
///////////////////////////////////////////////////////////////////////////////////////////
// CQueryMenuPage
CQueryMenuPage::CQueryMenuPage(CQueryEditObj* pEditObj) : m_EditObject(*pEditObj), m_pObjSel(NULL), m_bLoading(FALSE) { ASSERT(pEditObj != NULL); m_EditObject.AddRef(); }
CQueryMenuPage::~CQueryMenuPage() { m_ObjectCB.Detach(); m_EditObject.Release(); }
LRESULT CQueryMenuPage::OnInitDialog( UINT mMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled ) { HWND hwndList = GetDlgItem(IDC_MENULIST); ASSERT( hwndList );
if( hwndList ) { m_MenuLV.SubclassWindow(hwndList);
RECT rc; BOOL bStat = m_MenuLV.GetClientRect(&rc); ASSERT(bStat);
int iWidth = (rc.right - rc.left) - GetSystemMetrics(SM_CXVSCROLL);
CString strName;
strName.LoadString(IDS_MENUITEM); int iCol = m_MenuLV.InsertColumn(0, strName, LVCFMT_LEFT, (iWidth + 1)/2, 0); ASSERT(iCol == 0);
strName.LoadString(IDS_TYPE); iCol = m_MenuLV.InsertColumn(1, strName, LVCFMT_LEFT, iWidth/2, 1); ASSERT(iCol == 1);
m_MenuLV.SetExtendedListViewStyle(LVS_EX_CHECKBOXES|LVS_EX_FULLROWSELECT); }
HWND hwndCombo = GetDlgItem(IDC_OBJECTLIST); ASSERT(hwndCombo); if( hwndCombo ) { m_ObjectCB.Attach(hwndCombo);
LoadObjectCB(m_ObjectCB, m_EditObject.m_vObjInfo);
if( m_EditObject.m_vObjInfo.size() != 0 ) { m_ObjectCB.SetCurSel(0); m_pObjSel = reinterpret_cast<CQueryObjInfo*>(m_ObjectCB.GetItemDataPtr(0));
if( hwndList ) { DisplayMenus(); } } }
return TRUE; }
void CQueryMenuPage::DisplayMenus() { if( m_pObjSel == NULL ) return;
if( !m_EditObject.m_spQueryNode ) return;
m_bLoading = TRUE;
m_MenuLV.DeleteAllItems();
m_DefaultID = 0;
CRootNode* pRootNode = m_EditObject.m_spQueryNode->GetRootNode(); if( !pRootNode ) return;
CClassInfo* pClassInfo = pRootNode->FindClass(m_pObjSel->Name()); if( pClassInfo != NULL ) { int iIndex = 0;
menuref_vector& vMenuRefs = m_pObjSel->MenuRefs(); menuref_vector::iterator itMenuRef;
menucmd_vector& vMenuCmds = pClassInfo->Menus(); menucmd_vector::iterator itMenuCmd;
// First add all root menu items that are not yet ref'd by the query node
for( itMenuCmd = vMenuCmds.begin(); itMenuCmd != vMenuCmds.end(); ++itMenuCmd ) { if( std::find(vMenuRefs.begin(), vMenuRefs.end(), (*itMenuCmd)->ID()) != vMenuRefs.end() ) break;
// Add menu to displayed list in an enabled state
DisplayMenuItem(iIndex++, *itMenuCmd, TRUE); }
// For each query menu reference
for( itMenuRef = vMenuRefs.begin(); itMenuRef != vMenuRefs.end(); ++itMenuRef ) { // Find the matching root menu cmd
for( itMenuCmd = vMenuCmds.begin(); itMenuCmd != vMenuCmds.end(); ++itMenuCmd ) { if( (*itMenuCmd)->ID() == itMenuRef->ID() ) break; }
// if menu was deleted at the root node, then skip it
if( itMenuCmd == vMenuCmds.end() ) continue;
// Display the menu item
DisplayMenuItem(iIndex++, *(itMenuCmd++), itMenuRef->IsEnabled());
// If this is the default menu item save its ID
if( itMenuRef->IsDefault() ) { ASSERT(m_DefaultID == 0); m_DefaultID = itMenuRef->ID(); }
// Display any following root items that aren't in the query list
while( itMenuCmd != vMenuCmds.end() && std::find(vMenuRefs.begin(), vMenuRefs.end(), (*itMenuCmd)->ID()) == vMenuRefs.end() ) { DisplayMenuItem(iIndex++, *(itMenuCmd++), TRUE); } } }
// Disable buttons until selection made
EnableDlgItem( m_hWnd, IDC_MOVEUP, FALSE ); EnableDlgItem( m_hWnd, IDC_MOVEDOWN, FALSE ); EnableDlgItem( m_hWnd, IDC_DEFAULTMENU, FALSE );
// Uncheck default button until default item selected
Button_SetCheck(GetDlgItem(IDC_DEFAULTMENU), BST_UNCHECKED);
// Set Property Menu Checkbox
Button_SetCheck(GetDlgItem(IDC_PROPERTYMENU), m_pObjSel->HasPropertyMenu() ? BST_CHECKED : BST_UNCHECKED);
m_bLoading = FALSE; }
void CQueryMenuPage::DisplayMenuItem(int iIndex, CMenuCmd* pMenuCmd, BOOL bEnabled) { if( !pMenuCmd ) return;
static CString strShellCmd; static CString strADCmd;
LV_ITEM lvi; lvi.mask = LVIF_TEXT | LVIF_PARAM; lvi.iItem = iIndex; lvi.iSubItem = 0; lvi.pszText = const_cast<LPWSTR>(pMenuCmd->Name()); lvi.lParam = static_cast<LPARAM>(pMenuCmd->ID());
int iPos = m_MenuLV.InsertItem(&lvi); ASSERT(iPos == iIndex);
lvi.iSubItem = 1; lvi.mask = LVIF_TEXT;
switch( pMenuCmd->MenuType() ) { case MENUTYPE_SHELL: if( strShellCmd.IsEmpty() ) strShellCmd.LoadString(IDS_SHELLCMD);
lvi.pszText = (LPWSTR)(LPCWSTR)strShellCmd; break;
case MENUTYPE_ACTDIR: if( strADCmd.IsEmpty() ) strADCmd.LoadString(IDS_DISPSPEC);
lvi.pszText = (LPWSTR)(LPCWSTR)strADCmd; break;
default: ASSERT(FALSE); }
m_MenuLV.SetItem(&lvi);
m_MenuLV.SetCheckState(iIndex, bEnabled); }
LRESULT CQueryMenuPage::OnObjectSelect( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled ) { int iItem = m_ObjectCB.GetCurSel();
// Double-clicking an empty combo box can call this with no selection
if( iItem >= 0 ) { SaveMenuSet();
m_pObjSel = reinterpret_cast<CQueryObjInfo*>(m_ObjectCB.GetItemDataPtr(iItem));
DisplayMenus(); }
return 0; }
LRESULT CQueryMenuPage::OnMoveUpDown( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled ) { int iItem = m_MenuLV.GetNextItem(-1, LVNI_SELECTED); ASSERT(iItem >= 0);
// Get the selected item data
WCHAR szName[100];
LVITEM lvi; lvi.mask = LVIF_TEXT|LVIF_PARAM|LVIF_STATE; lvi.stateMask = 0xFFFFFFFF; lvi.iSubItem = 0; lvi.iItem = iItem; lvi.pszText = szName; lvi.cchTextMax = sizeof(szName); m_MenuLV.GetItem(&lvi);
WCHAR szType[100]; m_MenuLV.GetItemText(iItem, 1, szType, sizeof(szType));
// Set loading flag to avoid intermediate button enable/disables
m_bLoading = TRUE;
// Delete and insert at new position
m_MenuLV.DeleteItem(iItem);
lvi.iItem += (wID == IDC_MOVEUP) ? -1 : 1; m_MenuLV.InsertItem(&lvi); m_MenuLV.SetItemText(lvi.iItem, 1, szType);
// re-establish checked state (insert doesn't retain it)
if( lvi.state & CHECK_ON ) m_MenuLV.SetCheckState(lvi.iItem, TRUE);
m_bLoading = FALSE;
SetModified(TRUE);
// update button states
EnableDlgItem( m_hWnd, IDC_MOVEUP, (lvi.iItem > 0) ); EnableDlgItem( m_hWnd, IDC_MOVEDOWN, (lvi.iItem < (m_MenuLV.GetItemCount() - 1)) );
return 0; }
LRESULT CQueryMenuPage::OnMenuChanged(int idCtrl, LPNMHDR pNMHDR, BOOL& bHandled) { if( !pNMHDR ) return 0;
if( !m_bLoading ) { LPNMLISTVIEW pnmv = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
// if state has changed
if( pnmv->uChanged & LVIF_STATE ) { // if checkbox state change
if( (pnmv->uNewState ^ pnmv->uOldState) & LVIS_STATEIMAGEMASK ) { // if the changed item is currently selected
if( m_MenuLV.GetItemState(pnmv->iItem, LVIS_SELECTED) & LVIS_SELECTED ) { // Change the state of all selcted items to match
BOOL bNewState = ((pnmv->uNewState & LVIS_STATEIMAGEMASK) == CHECK_ON);
m_bLoading = TRUE; int iItem = -1; while( (iItem = m_MenuLV.GetNextItem(iItem, LVNI_SELECTED)) >= 0 ) { m_MenuLV.SetCheckState(iItem, bNewState); } m_bLoading = FALSE;
}
SetModified(TRUE); }
if( (pnmv->uNewState ^ pnmv->uOldState) & LVIS_SELECTED ) { int nItems = m_MenuLV.GetItemCount(); int iItem = m_MenuLV.GetNextItem(-1, LVNI_SELECTED); int nSelected = m_MenuLV.GetSelectedCount();
BOOL bDefault = (nSelected == 1) && (m_MenuLV.GetItemData(iItem) == m_DefaultID); Button_SetCheck(GetDlgItem(IDC_DEFAULTMENU), bDefault ? BST_CHECKED : BST_UNCHECKED);
EnableDlgItem( m_hWnd, IDC_MOVEUP, ((iItem > 0) && (nSelected == 1)) ); EnableDlgItem( m_hWnd, IDC_MOVEDOWN, ((iItem >= 0) && (iItem < (nItems - 1)) && (nSelected == 1)) ); EnableDlgItem( m_hWnd, IDC_DEFAULTMENU, (nSelected == 1) ); }
} }
return TRUE; }
LRESULT CQueryMenuPage::OnDefaultChanged(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { // if user checks the default then save currently selected menu ID as default
if( Button_GetCheck(GetDlgItem(IDC_DEFAULTMENU)) == BST_CHECKED ) { // button should be disabled unless there is one menu item selected
ASSERT(m_MenuLV.GetSelectedCount() == 1);
int iItem = m_MenuLV.GetNextItem(-1, LVNI_SELECTED); m_DefaultID = m_MenuLV.GetItemData(iItem); } else { // if user unchecks box there is no default
m_DefaultID = 0; }
SetModified(TRUE); return 0; }
LRESULT CQueryMenuPage::OnPropertyMenuChanged(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { SetModified(TRUE); return 0; }
void CQueryMenuPage::SaveMenuSet() { if( m_pObjSel == NULL ) return;
m_pObjSel->m_vMenuRefs.clear();
LVITEM lvi; lvi.mask = LVIF_PARAM | LVIF_STATE; lvi.stateMask = LVIS_STATEIMAGEMASK; lvi.iSubItem = 0;
int nItems = m_MenuLV.GetItemCount(); for( int iIndex = 0; iIndex < nItems; iIndex++ ) { lvi.iItem = iIndex; BOOL bStat = m_MenuLV.GetItem(&lvi); ASSERT(bStat);
CMenuRef menuref; menuref.m_menuID = static_cast<MenuID>(lvi.lParam); menuref.SetEnable((lvi.state & LVIS_STATEIMAGEMASK) == CHECK_ON); menuref.SetDefault(menuref.m_menuID == m_DefaultID);
m_pObjSel->m_vMenuRefs.push_back(menuref); }
m_pObjSel->SetPropertyMenu( Button_GetCheck(GetDlgItem(IDC_PROPERTYMENU)) == BST_CHECKED ); }
BOOL CQueryMenuPage::OnSetActive() { m_EditObject.PageActive(m_hWnd); return TRUE; }
BOOL CQueryMenuPage::OnApply() { SaveMenuSet();
return m_EditObject.ApplyChanges(m_hWnd); }
///////////////////////////////////////////////////////////////////////////////////////////
// CQueryViewPage
CQueryViewPage::CQueryViewPage(CQueryEditObj* pEditObj) : m_EditObject(*pEditObj), m_bLoading(FALSE), m_pObjSel(NULL) { ASSERT(pEditObj != NULL); m_EditObject.AddRef(); }
CQueryViewPage::~CQueryViewPage() { m_ObjectCB.Detach(); m_EditObject.Release(); }
LRESULT CQueryViewPage::OnInitDialog( UINT mMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled ) { HWND hwndList = GetDlgItem(IDC_COLUMNLIST); if( hwndList ) { m_ColumnLV.SubclassWindow(hwndList);
RECT rc; BOOL bStat = m_ColumnLV.GetClientRect(&rc); ASSERT(bStat);
int iCol = m_ColumnLV.InsertColumn(0, NULL, LVCFMT_LEFT, (rc.right - rc.left), 0); ASSERT(iCol == 0);
m_ColumnLV.SetExtendedListViewStyle(LVS_EX_CHECKBOXES); }
HWND hwndCombo = GetDlgItem(IDC_OBJECTLIST); if( hwndCombo ) { m_ObjectCB.Attach(hwndCombo);
LoadObjectCB(m_ObjectCB, m_EditObject.m_vObjInfo);
if( m_EditObject.m_vObjInfo.size() != 0 ) { m_ObjectCB.SetCurSel(0); m_pObjSel = reinterpret_cast<CQueryObjInfo*>(m_ObjectCB.GetItemDataPtr(0));
if( hwndList ) { DisplayColumns(); } } }
return TRUE; }
LRESULT CQueryViewPage::OnObjectSelect( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled ) { int iItem = m_ObjectCB.GetCurSel();
// Double-clicking an empty combo box can call this with no selection
if( iItem >= 0 ) { SaveColumnSet();
m_pObjSel = reinterpret_cast<CQueryObjInfo*>(m_ObjectCB.GetItemDataPtr(iItem));
DisplayColumns(); }
return 0; }
void CQueryViewPage::DisplayColumns() { if( !m_pObjSel ) return; if( !m_EditObject.m_spQueryNode ) return;
m_bLoading = TRUE;
m_ColumnLV.DeleteAllItems();
LV_ITEM lvi; lvi.mask = LVIF_TEXT | LVIF_PARAM; lvi.iItem = 0; lvi.iSubItem = 0;
CRootNode* pRootNode = m_EditObject.m_spQueryNode->GetRootNode(); if( !pRootNode ) return;
CClassInfo* pClassInfo = pRootNode->FindClass(m_pObjSel->Name()); if( pClassInfo != NULL ) { DisplayNameMap* pNameMap = DisplayNames::GetMap(m_pObjSel->Name()); ASSERT(pNameMap != NULL);
if( pNameMap == NULL ) return;
string_vector& vDisabledCols = m_pObjSel->DisabledColumns();
string_vector::iterator itstrCol; for( itstrCol = pClassInfo->Columns().begin(); itstrCol != pClassInfo->Columns().end(); ++itstrCol ) { lvi.pszText = const_cast<LPWSTR>(pNameMap->GetAttributeDisplayName(itstrCol->c_str())); lvi.lParam = reinterpret_cast<LPARAM>(itstrCol->c_str()); int iPos = m_ColumnLV.InsertItem(&lvi); ASSERT(iPos >= 0);
//Enable all columns that aren't excluded by the query node
if( std::find(vDisabledCols.begin(), vDisabledCols.end(), *itstrCol) == vDisabledCols.end() ) m_ColumnLV.SetCheckState(iPos, TRUE); } }
m_bLoading = FALSE; }
LRESULT CQueryViewPage::OnColumnChanged(int idCtrl, LPNMHDR pNMHDR, BOOL& bHandled) { if( !pNMHDR ) return 0;
if( !m_bLoading ) { LPNMLISTVIEW pnmv = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
// if checked state has changed
if( (pnmv->uChanged & LVIF_STATE) && ((pnmv->uNewState ^ pnmv->uOldState) & LVIS_STATEIMAGEMASK) ) { // if the changed item is currently selected
if( m_ColumnLV.GetItemState(pnmv->iItem, LVIS_SELECTED) & LVIS_SELECTED ) { // Change the state of all selcted items to match
BOOL bNewState = ((pnmv->uNewState & LVIS_STATEIMAGEMASK) == CHECK_ON);
m_bLoading = TRUE; int iItem = -1; while( (iItem = m_ColumnLV.GetNextItem(iItem, LVNI_SELECTED)) >= 0 ) { m_ColumnLV.SetCheckState(iItem, bNewState); } m_bLoading = FALSE;
}
SetModified(TRUE); } }
return TRUE; }
void CQueryViewPage::SaveColumnSet() { if( m_pObjSel == NULL ) return;
string_vector vstrNewCols;
int nItems = m_ColumnLV.GetItemCount(); for( int iIndex = 0; iIndex < nItems; iIndex++ ) { // Save list of disabled columns
if( !m_ColumnLV.GetCheckState(iIndex) ) { LVITEM lvi; lvi.mask = LVIF_PARAM; lvi.iItem = iIndex; lvi.iSubItem = 0; BOOL bStat = m_ColumnLV.GetItem(&lvi); ASSERT(bStat);
vstrNewCols.push_back(reinterpret_cast<LPCWSTR>(lvi.lParam)); } }
m_pObjSel->m_vstrDisabledColumns = vstrNewCols; }
typedef struct { HWND hwndList; int iCol; } COMPAREPARAM, *LPCOMPAREPARAM;
int CALLBACK ColumnCompare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) { if( !lParamSort ) return 0;
LPCOMPAREPARAM pcmp = reinterpret_cast<LPCOMPAREPARAM>(lParamSort);
WCHAR sz1[MAX_PATH]; ListView_GetItemText(pcmp->hwndList, lParam1, pcmp->iCol, sz1, MAX_PATH);
WCHAR sz2[MAX_PATH]; ListView_GetItemText(pcmp->hwndList, lParam2, pcmp->iCol, sz2, MAX_PATH);
return wcscmp(sz1,sz2); }
LRESULT CQueryViewPage::OnColumnClick(int idCtrl, LPNMHDR pNMHDR, BOOL& bHandled) { if( !pNMHDR ) return 0;
LPNMLISTVIEW pnmv = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
COMPAREPARAM cmp; cmp.hwndList = pnmv->hdr.hwndFrom; cmp.iCol = pnmv->iSubItem;
ListView_SortItemsEx(pnmv->hdr.hwndFrom, &ColumnCompare, &cmp);
return TRUE; }
BOOL CQueryViewPage::OnSetActive() { DisplayColumns(); m_EditObject.PageActive(m_hWnd);
return TRUE; }
BOOL CQueryViewPage::OnApply() { SaveColumnSet();
return m_EditObject.ApplyChanges(m_hWnd); }
///////////////////////////////////////////////////////////////////////////////////////////
// CQueryNodeMenuPage
CQueryNodeMenuPage::CQueryNodeMenuPage(CQueryEditObj* pEditObj) : m_EditObject(*pEditObj) { ASSERT(pEditObj != NULL); m_EditObject.AddRef(); }
CQueryNodeMenuPage::~CQueryNodeMenuPage() { m_MenuLV.Detach(); m_EditObject.Release(); }
LRESULT CQueryNodeMenuPage::OnInitDialog( UINT mMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled ) { m_MenuLV.Attach(GetDlgItem(IDC_MENULIST));
::ConfigSingleColumnListView(GetDlgItem(IDC_MENULIST));
return TRUE; }
BOOL CQueryNodeMenuPage::OnSetActive() { m_EditObject.PageActive(m_hWnd); DisplayMenus();
return TRUE; }
void CQueryNodeMenuPage::DisplayMenus() { if( !m_EditObject.m_spQueryNode ) return;
HWND hwndLV = GetDlgItem(IDC_MENULIST);
ASSERT(::IsWindow(hwndLV));
ListView_DeleteAllItems(hwndLV);
// make sure menu names have been loaded
CRootNode* pRootNode = m_EditObject.m_spQueryNode->GetRootNode(); if( !pRootNode ) return;
CComponentData* pCompData = pRootNode->GetCompData(); if( !pCompData ) return;
IStringTable* pStringTable = pCompData->GetStringTable(); ASSERT(pStringTable != NULL); if( !pStringTable ) return;
m_EditObject.LoadStrings(pStringTable);
LV_ITEM lvi; lvi.mask = LVIF_TEXT | LVIF_PARAM; lvi.iItem = 0; lvi.iSubItem = 0;
menucmd_vector::iterator itMenu; for( itMenu = m_EditObject.Menus().begin(); itMenu != m_EditObject.Menus().end(); ++itMenu ) { lvi.pszText = const_cast<LPWSTR>((*itMenu)->Name()); lvi.lParam = (*itMenu)->ID();
int iPos = ListView_InsertItem(hwndLV, &lvi); ASSERT(iPos >= 0);
lvi.iItem++; }
EnableDlgItem( m_hWnd, IDC_ADDMENU, TRUE ); EnableDlgItem( m_hWnd, IDC_REMOVEMENU, FALSE ); EnableDlgItem( m_hWnd, IDC_EDITMENU, FALSE ); EnableDlgItem( m_hWnd, IDC_MOVEUP, FALSE ); EnableDlgItem( m_hWnd, IDC_MOVEDOWN, FALSE ); }
LRESULT CQueryNodeMenuPage::OnAddMenu( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled ) { if( !m_EditObject.m_spQueryNode ) return 0;
CAddQNMenuDlg dlg(m_EditObject);
if( dlg.DoModal() == IDOK ) { CMenuCmd* pMenuNew = dlg.GetMenu(); ASSERT(pMenuNew != NULL); if( !pMenuNew ) return 0;
// Add new menu to list
HWND hwndList = GetDlgItem(IDC_MENULIST);
// Set name to add it to string table and generate the menu ID
CRootNode* pRootNode = m_EditObject.m_spQueryNode->GetRootNode(); if( !pRootNode ) return 0;
CComponentData* pCompData = pRootNode->GetCompData(); ASSERT( pCompData ); if( !pCompData ) return 0;
IStringTable* pStringTable = pCompData->GetStringTable(); ASSERT( pStringTable ); if( !pStringTable ) return 0;
// Use temp string because string fails an assignement like: strX = strX.c_str()
// (it relases the private buffer first and then assigns the string)
tstring strName = pMenuNew->Name(); pMenuNew->SetName(pStringTable, strName.c_str());
LVITEM lvi; lvi.mask = LVIF_PARAM | LVIF_TEXT; lvi.iSubItem = 0; lvi.iItem = ListView_GetItemCount(hwndList); lvi.lParam = pMenuNew->ID(); lvi.pszText = const_cast<LPWSTR>(pMenuNew->Name()); ListView_InsertItem(hwndList,&lvi);
// Add to menu vector (note that temp CMenuCmdPtr will delete pMenuNew)
m_EditObject.m_vMenus.push_back(CMenuCmdPtr(pMenuNew));
SetModified(TRUE); }
return 0; }
LRESULT CQueryNodeMenuPage::OnEditMenu( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled ) { if( !m_EditObject.m_spQueryNode ) return 0;
HWND hwndList = GetDlgItem(IDC_MENULIST);
int iIndex = ListView_GetNextItem(hwndList, -1, LVNI_SELECTED); ASSERT(iIndex != -1);
LVITEM lvi; lvi.mask = LVIF_PARAM; lvi.iSubItem = 0; lvi.iItem = iIndex;
ListView_GetItem(hwndList, &lvi);
// Locate selected menu by it's ID (lparam)
menucmd_vector& vMenus = m_EditObject.Menus();
menucmd_vector::iterator itMenu; itMenu = std::find(vMenus.begin(), vMenus.end(), lvi.lParam); ASSERT(itMenu != vMenus.end());
CMenuCmd* pMenu = *itMenu; if( !pMenu ) return 0;
CAddQNMenuDlg dlg(m_EditObject, pMenu);
if( dlg.DoModal() == IDOK ) { CMenuCmd* pMenuNew = dlg.GetMenu(); ASSERT(pMenuNew != NULL); if( !pMenuNew ) return 0;
// Set the name again in case it was changed
CRootNode* pRootNode = m_EditObject.m_spQueryNode->GetRootNode(); if( !pRootNode ) return 0;
CComponentData* pCompData = pRootNode->GetCompData(); if( !pCompData ) return 0;
IStringTable* pStringTable = pCompData->GetStringTable(); ASSERT(pStringTable != NULL); if( !pStringTable ) return 0;
// Use temp string because string fails an assignement like: strX = strX.c_str()
// (it relases the private buffer first and then assigns the string)
tstring strName = pMenuNew->Name(); pMenuNew->SetName(pStringTable, strName.c_str());
// locate object again because the vector may have been reallocated
menucmd_vector& vMenusNew = m_EditObject.Menus();
// locate with the old ID because it will be different if the name was changed
itMenu = std::find(vMenusNew.begin(), vMenusNew.end(), pMenu->ID()); ASSERT(itMenu != vMenusNew.end());
// Replace menu with new one
*itMenu = pMenuNew;
// Update the list
lvi.mask = LVIF_PARAM | LVIF_TEXT; lvi.lParam = pMenuNew->ID(); lvi.pszText = const_cast<LPWSTR>(pMenuNew->Name()); ListView_SetItem(hwndList,&lvi);
SetModified(TRUE); }
return 0; }
LRESULT CQueryNodeMenuPage::OnRemoveMenu( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled ) { HWND hwndList = GetDlgItem(IDC_MENULIST);
UINT uiMsg = (ListView_GetSelectedCount(hwndList) == 1) ? IDS_MENU_REMOVE_ONE : IDS_MENU_REMOVE; int iRet = DisplayMessageBox(m_hWnd, IDS_MENU_REMOVE_TITLE, uiMsg, MB_YESNO|MB_ICONWARNING); if( iRet != IDYES ) return 0;
menucmd_vector& vMenus = m_EditObject.Menus();
LVITEM lvi; lvi.mask = LVIF_PARAM; lvi.iSubItem = 0;
int iIndex = -1; while( (iIndex = ListView_GetNextItem(hwndList, iIndex, LVNI_SELECTED)) >= 0 ) { lvi.iItem = iIndex; ListView_GetItem(hwndList, &lvi);
// Locate menu by its ID
menucmd_vector::iterator itMenu = std::find(vMenus.begin(), vMenus.end(), lvi.lParam); ASSERT(itMenu != vMenus.end());
vMenus.erase(itMenu);
ListView_DeleteItem(hwndList, iIndex); iIndex--; }
EnableDlgItem( m_hWnd, IDC_REMOVEMENU, FALSE ); EnableDlgItem( m_hWnd, IDC_EDITMENU, FALSE ); EnableDlgItem( m_hWnd, IDC_MOVEUP, FALSE ); EnableDlgItem( m_hWnd, IDC_MOVEDOWN, FALSE );
SetModified(TRUE);
return 0; }
LRESULT CQueryNodeMenuPage::OnMoveUpDown( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled ) { HWND hwndList = GetDlgItem(IDC_MENULIST); int iItem = ListView_GetNextItem(hwndList, -1, LVNI_SELECTED); ASSERT(iItem >= 0);
// Determine new position for selected item
if( wID == IDC_MOVEUP ) iItem--; else iItem++;
// Now swap the selected item with the item at its new position
// Do it by moving the unselected item to avoid state change notifications
// because they will cause unwanted butten enables/disables.
LVITEM lvi; lvi.mask = LVIF_PARAM; lvi.iSubItem = 0; lvi.iItem = iItem; ListView_GetItem(hwndList, &lvi);
// Move the menu item in the menu vector
menucmd_vector& vMenus = m_EditObject.Menus();
menucmd_vector::iterator itMenu = std::find(vMenus.begin(), vMenus.end(), lvi.lParam); ASSERT(itMenu != vMenus.end());
menucmd_vector::iterator itMenuOld = itMenu; if( wID == IDC_MOVEUP ) itMenu++; else itMenu--;
// swap the items
std::iter_swap (itMenuOld, itMenu);
//Now delete and reinsert it in the list view
ListView_DeleteItem(hwndList, lvi.iItem);
if( wID == IDC_MOVEUP ) lvi.iItem++; else lvi.iItem--; lvi.mask = LVIF_PARAM | LVIF_TEXT; lvi.pszText = const_cast<LPWSTR>((*itMenu)->Name()); ListView_InsertItem(hwndList, &lvi);
// Update Up/Down buttons
EnableDlgItem( m_hWnd, IDC_MOVEUP, (iItem > 0) ); EnableDlgItem( m_hWnd, IDC_MOVEDOWN, (iItem < (ListView_GetItemCount(hwndList) - 1)) );
SetModified(TRUE);
return 0; }
LRESULT CQueryNodeMenuPage::OnMenuListChanged(int idCtrl, LPNMHDR pNMHDR, BOOL& bHandled) { HWND hwndList = GetDlgItem(IDC_MENULIST);
int nItemSel = ListView_GetSelectedCount(hwndList); int iItem = ListView_GetNextItem(hwndList, -1, LVNI_SELECTED);
EnableDlgItem( m_hWnd, IDC_REMOVEMENU, (nItemSel > 0) ); EnableDlgItem( m_hWnd, IDC_EDITMENU, (nItemSel == 1) ); EnableDlgItem( m_hWnd, IDC_MOVEUP, ((nItemSel == 1) && (iItem > 0)) ); EnableDlgItem( m_hWnd, IDC_MOVEDOWN, ((nItemSel == 1) && (iItem < (ListView_GetItemCount(hwndList) - 1))) );
return TRUE; }
LRESULT CQueryNodeMenuPage::OnMenuListDblClk(int idCtrl, LPNMHDR pNMHDR, BOOL& bHandled) { if( ListView_GetSelectedCount(GetDlgItem(IDC_MENULIST)) ) ::SendMessage(GetDlgItem(IDC_EDITMENU), BM_CLICK, (WPARAM)0, (LPARAM)0);
return 0; }
BOOL CQueryNodeMenuPage::OnApply() { return m_EditObject.ApplyChanges(m_hWnd); }
/////////////////////////////////////////////////////////////////////////////////////////////////
// CQueryEditObj
void CQueryEditObj::PageActive(HWND hwndPage) { ASSERT(::IsWindow(hwndPage));
// track the highest created page number for ApplyChanges method
int iPage = PropSheet_HwndToIndex(GetParent(hwndPage), hwndPage); if( iPage > m_iPageMax ) m_iPageMax = iPage; }
BOOL CQueryEditObj::ApplyChanges(HWND hwndPage) { if( !m_spQueryNode ) return FALSE;
ASSERT(::IsWindow(hwndPage));
// Don't apply changes until called from highest activated page
if( PropSheet_HwndToIndex(GetParent(hwndPage), hwndPage) < m_iPageMax ) return TRUE;
// replace original query objects with edited copies
m_spQueryNode->Objects() = m_vObjInfo; m_spQueryNode->Menus() = m_vMenus;
if( m_spQueryNode ) { CRootNode* pRootNode = m_spQueryNode->GetRootNode(); if( pRootNode ) { pRootNode->UpdateModifyTime(); } }
return TRUE; }
/////////////////////////////////////////////////////////////////////////////////////////////////
// Helper functions
void LoadObjectCB(CComboBox& ComboBox, QueryObjVector& vObj) { ComboBox.ResetContent();
DisplayNameMap* pNameMap = DisplayNames::GetClassMap(); ASSERT(pNameMap != NULL); if( pNameMap == NULL ) return;
for( QueryObjVector::iterator itObj = vObj.begin(); itObj != vObj.end(); ++itObj ) { int iIndex = ComboBox.AddString(pNameMap->GetAttributeDisplayName(itObj->Name())); ASSERT(iIndex >= 0); ComboBox.SetItemDataPtr(iIndex, &(*itObj)); } }
|