From 1e8caccd5764b8beba8a6b8d04cb6b4da8d2878e Mon Sep 17 00:00:00 2001 From: Nick Gammon Date: Thu, 21 Oct 2010 12:08:03 +1100 Subject: [PATCH] Preliminary work on TreeView controls for world configuration --- dialogs/world_prefs/GenPropertyPage.h | 65 +- dialogs/world_prefs/configuration.cpp | 14 +- dialogs/world_prefs/genpropertypage.cpp | 951 ++++++++++++++++----- dialogs/world_prefs/prefspropertypages.cpp | 280 +++++- dialogs/world_prefs/prefspropertypages.h | 22 +- 5 files changed, 1083 insertions(+), 249 deletions(-) diff --git a/dialogs/world_prefs/GenPropertyPage.h b/dialogs/world_prefs/GenPropertyPage.h index 15ccf156..a7266e5e 100644 --- a/dialogs/world_prefs/GenPropertyPage.h +++ b/dialogs/world_prefs/GenPropertyPage.h @@ -11,6 +11,8 @@ typedef CTypedPtrMap CObjectMap; typedef int (* t_CompareObjects) (const int iColumn, const CObject * item1, const CObject * item2); +#define ID_TREEVIEW (WM_USER + 1004) + typedef struct t_gen_sort_param { // initialise via constructor - makes sure we don't leave something out! @@ -61,6 +63,7 @@ class CGenPropertyPage : public CPropertyPage CFindInfo * m_pObjectFindInfo; // the findinfo structure CListCtrl * m_ctlList; // the list control which displays the items CStatic * m_ctlSummary; // count of items shown + bool m_bWantTreeControl; // true if it wants to show a tree control instead of a list control // count of columns is used for arrays below int m_iColumnCount; // how many columns there are @@ -76,27 +79,39 @@ class CGenPropertyPage : public CPropertyPage BOOL m_reverse; // if true, reverse sort t_CompareObjects m_CompareObjects; // for comparing when sorting + CTreeCtrl m_cTreeCtrl; // for the tree views + map m_GroupsMap; // for inserting into groups + // set up variables for use later on -void CGenPropertyPage::SetUpPage (CString strObjectType, - CObjectMap * ObjectMap, - CListCtrl * ctlList, - CStatic * ctlSummary, - t_CompareObjects CompareObjects, - CFindInfo * pFindInfo, - const unsigned long iMask); + void CGenPropertyPage::SetUpPage (CString strObjectType, + CObjectMap * ObjectMap, + CListCtrl * ctlList, + CStatic * ctlSummary, + t_CompareObjects CompareObjects, + CFindInfo * pFindInfo, + const unsigned long iMask, + const bool bWantTreeControl); // add an new item void OnAddItem(CDialog & dlg); // adds a new item to the list void OnChangeItem(CDialog & dlg); // changes an existing item + bool ChangeOneItem(CDialog & dlg, CString * pstrObjectName, const int nItem, HTREEITEM hdlItem); // changes one existing item + bool DeleteOneItem(CString * pstrObjectName, int & iIncluded, int & iExecuting); // deletes one existing item void OnDeleteItem() ; // delete an item from the list void OnCopyItem() ; // copy an item to the clipboard in XML + bool CopyOneItem(CString * pstrObjectName, CArchive & ar) ; // copy an item to the clipboard in XML void OnPasteItem() ; // paste an item from the clipboard in XML void OnColumnclickItemList(NMHDR* pNMHDR, LRESULT* pResult); void LoadList (void); // load up list initially or after load from file bool EditFilterText (CString & sText); // edit the filter text - + void SortItems (void); // sort the tree/list control + int GetSelectedItemCount () const; // how many items are selected? + int GetItemCount () const; // how many items are there in the list/tree? + void CheckParentHasChildren (HTREEITEM hdlParent); // if this group is empty, delete it + + // ================== start of virtual functions ======================= // dialog management - initialise, load, unload, check if changed, get name @@ -121,6 +136,10 @@ void CGenPropertyPage::SetUpPage (CString strObjectType, virtual __int64 GetModificationNumber (CObject * pItem) const = 0; // get modification number virtual CString GetScriptName (CObject * pItem) const = 0; // get script subroutine name virtual CString GetLabel (CObject * pItem) const = 0; // get item label + virtual CString GetGroup (CObject * pItem) const = 0; // get item group + virtual CString GetDescription (CObject * pItem) const = 0; // get item description for tree control + virtual int GetSequence (CObject * pItem) const = 0; // get item sequence for sorting + virtual CString GetFindText (CObject * pItem) const = 0; // get text for searching on // list management - add the item to the list control virtual int AddItem (CObject * pItem, // add one item to the list control @@ -139,12 +158,18 @@ void CGenPropertyPage::SetUpPage (CString strObjectType, // ================== end of virtual functions ======================= - // add a single item - returns new item number + // add a single list control item - returns new item number + + int add_list_item (CObject * pItem, + const CString * pstrObjectName, + const int nItem, + const BOOL bInsert); + + // add a single tree control item - returns new item number + + HTREEITEM add_tree_item (CObject * pItem, + const CString * pstrObjectName); - int add_item (CObject * pItem, - const CString * pstrObjectName, - const int nItem, - const BOOL bInsert); // Overrides // ClassWizard generate virtual function overrides @@ -173,12 +198,20 @@ void CGenPropertyPage::SetUpPage (CString strObjectType, // for finding + // finds item n in the tree control + static HTREEITEM get_tree_item (CTreeCtrl * pTree, const int n); + static void InitiateSearch (const CObject * pObject, CFindInfo & FindInfo); - static bool GetNextLine (const CObject * pObject, - CFindInfo & FindInfo, - CString & strLine); + static bool GetNextListLine (const CObject * pObject, + CFindInfo & FindInfo, + CString & strLine); + + + static bool GetNextTreeLine (const CObject * pObject, + CFindInfo & FindInfo, + CString & strLine); void DoFind (bool bAgain); diff --git a/dialogs/world_prefs/configuration.cpp b/dialogs/world_prefs/configuration.cpp index 6e4e2c12..6ec21a69 100644 --- a/dialogs/world_prefs/configuration.cpp +++ b/dialogs/world_prefs/configuration.cpp @@ -205,7 +205,8 @@ void CMUSHclientDoc:: LoadPrefsP7 (CPrefsP7 &page7) &page7.m_ctlSummary, page7.CompareObjects, &m_AliasesFindInfo, - XML_ALIASES); + XML_ALIASES, + true); // tree control page7.m_iColumnCount = CPrefsP7::eColumnCount; page7.m_iColWidth = new int [CPrefsP7::eColumnCount]; @@ -246,7 +247,8 @@ void CMUSHclientDoc:: LoadPrefsP8 (CPrefsP8 &page8) &page8.m_ctlSummary, page8.CompareObjects, &m_TriggersFindInfo, - XML_TRIGGERS); + XML_TRIGGERS, + true); // tree control page8.m_iColumnCount = CPrefsP8::eColumnCount; page8.m_iColWidth = new int [CPrefsP8::eColumnCount]; @@ -582,7 +584,9 @@ void CMUSHclientDoc:: LoadPrefsP16 (CPrefsP16 &page16) &page16.m_ctlSummary, page16.CompareObjects, &m_TimersFindInfo, - XML_TIMERS); + XML_TIMERS, + true); // tree control + page16.m_iColumnCount = CPrefsP16::eColumnCount; page16.m_iColWidth = new int [CPrefsP16::eColumnCount]; @@ -672,7 +676,9 @@ void CMUSHclientDoc:: LoadPrefsP18 (CPrefsP18 &page18) &page18.m_ctlSummary, page18.CompareObjects, &m_VariablesFindInfo, - XML_VARIABLES); + XML_VARIABLES, + false); // NOT tree control + page18.m_iColumnCount = CPrefsP18::eColumnCount; page18.m_iColWidth = new int [CPrefsP18::eColumnCount]; diff --git a/dialogs/world_prefs/genpropertypage.cpp b/dialogs/world_prefs/genpropertypage.cpp index 9b2e7881..f7c7cd58 100644 --- a/dialogs/world_prefs/genpropertypage.cpp +++ b/dialogs/world_prefs/genpropertypage.cpp @@ -26,9 +26,10 @@ CGenPropertyPage::CGenPropertyPage(const UINT nID) : m_reverse = FALSE; m_iColWidth = NULL; - m_iColJust = NULL; + m_iColJust = NULL; m_strColumnHeadings = NULL; - m_iColumnCount = 0; + m_iColumnCount = 0; + m_bWantTreeControl = false; } @@ -67,7 +68,8 @@ void CGenPropertyPage::SetUpPage (CString strObjectType, CStatic * ctlSummary, t_CompareObjects CompareObjects, CFindInfo * pFindInfo, - const unsigned long iMask) + const unsigned long iMask, + const bool bWantTreeControl) { m_strObjectType = strObjectType; m_ObjectMap = ObjectMap; @@ -77,9 +79,71 @@ void CGenPropertyPage::SetUpPage (CString strObjectType, m_pObjectFindInfo = pFindInfo; m_nUpdateNumber = App.GetUniqueNumber (); m_iMask = iMask; + m_bWantTreeControl = bWantTreeControl; } + +int CGenPropertyPage::GetSelectedItemCount () const + { + + int iCount = 0; + + if (m_bWantTreeControl) + { + + for (HTREEITEM hGroup = m_cTreeCtrl.GetRootItem (); + hGroup; + hGroup = m_cTreeCtrl.GetNextSiblingItem (hGroup)) + { + + for (HTREEITEM hItem = m_cTreeCtrl.GetChildItem (hGroup); + hItem; + hItem = m_cTreeCtrl.GetNextSiblingItem (hItem)) + { + if (m_cTreeCtrl.GetItemState (hItem, TVIS_SELECTED) & TVIS_SELECTED) + iCount++; + } // end for each item + + } // end for each group + + + return iCount; + } // end of tree control + + return m_ctlList->GetSelectedCount (); + + } // end of CGenPropertyPage::GetSelectedItemCount + +int CGenPropertyPage::GetItemCount () const + { + + int iCount = 0; + + if (m_bWantTreeControl) + { + + for (HTREEITEM hGroup = m_cTreeCtrl.GetRootItem (); + hGroup; + hGroup = m_cTreeCtrl.GetNextSiblingItem (hGroup)) + { + + for (HTREEITEM hItem = m_cTreeCtrl.GetChildItem (hGroup); + hItem; + hItem = m_cTreeCtrl.GetNextSiblingItem (hItem)) + iCount++; + + } // end for each group + + + return iCount; + } // end of tree control + + return m_ctlList->GetItemCount (); + + } // end of CGenPropertyPage::GetSelectedItemCount + + ///////////////////////////////////////////////////////////////////////////// // OnAddItem @@ -134,13 +198,16 @@ void CGenPropertyPage::OnAddItem(CDialog & dlg) CString * pstrObjectName = new CString (strObjectName); // add this item to the list view - add_item (pItem, pstrObjectName, 0, TRUE); + if (m_bWantTreeControl) + add_tree_item (pItem, pstrObjectName); + else + add_list_item (pItem, pstrObjectName, 0, TRUE); SetInternalName (pItem, strObjectName); // set name so we can delete one-shot items // resort the list - t_gen_sort_param sort_param (m_ObjectMap, m_last_col, m_reverse, m_CompareObjects); - m_ctlList->SortItems (CompareFunc, (LPARAM) &sort_param); + + SortItems (); // redraw the list if (GetFilterFlag ()) @@ -162,19 +229,35 @@ void CGenPropertyPage::OnAddItem(CDialog & dlg) } // end of CGenPropertyPage::OnAddItem ///////////////////////////////////////////////////////////////////////////// -// OnChangeItem +// CheckParentHasChildren -void CGenPropertyPage::OnChangeItem(CDialog & dlg) -{ -CString strMsg; - -// iterate through list in case we implement multiple selection one day -for (int nItem = -1; - (nItem = m_ctlList->GetNextItem(nItem, LVNI_SELECTED)) != -1;) +void CGenPropertyPage::CheckParentHasChildren (HTREEITEM hdlParent) { + if (m_cTreeCtrl.GetChildItem (hdlParent) == NULL) + { + // get (old) group name + CString strParent = m_cTreeCtrl.GetItemText (hdlParent); + + // delete group from tree view + m_cTreeCtrl.DeleteItem (hdlParent); + + // find parent in map + map::iterator it = m_GroupsMap.find (strParent); + // delete from map of parents (groups) as well + if (it != m_GroupsMap.end ()) + m_GroupsMap.erase (it); - // get the lower-case name of this item's object - CString * pstrObjectName = (CString *) m_ctlList->GetItemData (nItem); + } // end of no children + + } // end of CGenPropertyPage::CheckParentHasChildren + + +///////////////////////////////////////////////////////////////////////////// +// ChangeOneItem + +bool CGenPropertyPage::ChangeOneItem (CDialog & dlg, CString * pstrObjectName, const int nItem, HTREEITEM hdlItem) + { +CString strMsg; ASSERT (pstrObjectName != NULL); @@ -183,8 +266,17 @@ for (int nItem = -1; // check object is still there (it might have gone while we looked at the list box) if (!m_ObjectMap->Lookup (*pstrObjectName, pItem)) { - m_ctlList->DeleteItem (nItem); // it's gone, so delete it from the list view - m_ctlList->RedrawItems (0, m_ctlList->GetItemCount () - 1); // redraw the list + if (hdlItem) + { + HTREEITEM hdlParent = m_cTreeCtrl.GetParentItem (hdlItem); + m_cTreeCtrl.DeleteItem (hdlItem); + CheckParentHasChildren (hdlParent); + } + else + { + m_ctlList->DeleteItem (nItem); // it's gone, so delete it from the list view + m_ctlList->RedrawItems (0, m_ctlList->GetItemCount () - 1); // redraw the list + } // in the case of one-shot timers, unnamed items might be removed from the list if (pstrObjectName->Left (1) == "*") @@ -200,7 +292,7 @@ for (int nItem = -1; ::UMessageBox (strMsg); delete pstrObjectName; // and get rid of its name string - continue; + return false; } ASSERT_VALID (pItem); @@ -212,13 +304,22 @@ for (int nItem = -1; // put up the dialog, give up if they cancel if (dlg.DoModal () != IDOK) - continue; + return false; // lookup this object, to make sure it still exists if (!m_ObjectMap->Lookup (*pstrObjectName, pItem)) { - m_ctlList->DeleteItem (nItem); // it's gone, so delete it from the list view - m_ctlList->RedrawItems (0, m_ctlList->GetItemCount () - 1); // redraw the list + if (hdlItem) + { + HTREEITEM hdlParent = m_cTreeCtrl.GetParentItem (hdlItem); + m_cTreeCtrl.DeleteItem (hdlItem); + CheckParentHasChildren (hdlParent); + } + else + { + m_ctlList->DeleteItem (nItem); // it's gone, so delete it from the list view + m_ctlList->RedrawItems (0, m_ctlList->GetItemCount () - 1); // redraw the list + } // in the case of one-shot timers, unnamed items might be removed from the list if (pstrObjectName->Left (1) == "*") @@ -233,7 +334,7 @@ for (int nItem = -1; delete pstrObjectName; // and get rid of its name string ::UMessageBox (strMsg); - continue; + return false; } ASSERT_VALID (pItem); @@ -245,7 +346,7 @@ for (int nItem = -1; (LPCTSTR) m_strObjectType, (LPCTSTR) *pstrObjectName); ::UMessageBox (strMsg); - return; // can't modify included items + return true; // can't modify included items } // check object still has the same modification number @@ -256,7 +357,7 @@ for (int nItem = -1; (LPCTSTR) m_strObjectType, (LPCTSTR) *pstrObjectName); ::UMessageBox (strMsg); - continue; + return false; } // check for name change @@ -279,7 +380,7 @@ for (int nItem = -1; (LPCTSTR) strObjectName, (LPCTSTR) m_strObjectType); ::UMessageBox (strMsg); - continue; + return false; } // remove old entry and re-add under new name @@ -293,7 +394,10 @@ for (int nItem = -1; pstrObjectName = new CString (strObjectName); // record item's new name as the list object data - m_ctlList->SetItemData(nItem, (DWORD) pstrObjectName); + if (hdlItem) + m_cTreeCtrl.SetItemData (hdlItem, (DWORD) pstrObjectName); + else + m_ctlList->SetItemData (nItem, (DWORD) pstrObjectName); } // end of label changing // see if the user changed anything, anyway @@ -308,10 +412,32 @@ for (int nItem = -1; if (!CheckIfTemporary (pItem)) m_doc->SetModifiedFlag (TRUE); - // re-setup list with amended details - int nNewItem = add_item (pItem, pstrObjectName, nItem, FALSE); - m_ctlList->RedrawItems (nNewItem, nNewItem); + if (m_bWantTreeControl) + { + // group may have changed, delete and re-add + HTREEITEM hdlParent = m_cTreeCtrl.GetParentItem (hdlItem); + m_cTreeCtrl.DeleteItem (hdlItem); + HTREEITEM hItem = add_tree_item (pItem, pstrObjectName); + + // if deleting item deletes only one in group, remove group as well + CheckParentHasChildren (hdlParent); + + SortItems (); + + // get its new parent + hdlParent = m_cTreeCtrl.GetParentItem (hItem); + m_cTreeCtrl.SetItemState (hdlParent, TVIS_EXPANDED, TVIS_EXPANDED); // expand group (parent) + // select the new item + m_cTreeCtrl.SelectItem (hItem); + m_cTreeCtrl.EnsureVisible (hItem); // may have changed groups + } + else + { + // re-setup list with amended details + int nNewItem = add_list_item (pItem, pstrObjectName, nItem, FALSE); // replace + m_ctlList->RedrawItems (nNewItem, nNewItem); + } } // end of item changing @@ -330,72 +456,79 @@ for (int nItem = -1; ::UMessageBox (strMessage, MB_ICONINFORMATION); } - } // end of dealing with each selected item + return false; + } // end of CGenPropertyPage::ChangeOneItem - // redraw the list - if (GetFilterFlag ()) - LoadList (); // full reload because it may have changed filter requirements +///////////////////////////////////////////////////////////////////////////// +// OnChangeItem - // resort the list - t_gen_sort_param sort_param (m_ObjectMap, m_last_col, m_reverse, m_CompareObjects); - m_ctlList->SortItems (CompareFunc, (LPARAM) &sort_param); +void CGenPropertyPage::OnChangeItem(CDialog & dlg) +{ -} // end of CGenPropertyPage::OnChangeItem + if (m_bWantTreeControl) + { + for (HTREEITEM hGroup = m_cTreeCtrl.GetRootItem (); + hGroup; + hGroup = m_cTreeCtrl.GetNextSiblingItem (hGroup)) + { -///////////////////////////////////////////////////////////////////////////// -// OnDeleteItem + for (HTREEITEM hItem = m_cTreeCtrl.GetChildItem (hGroup); + hItem; + hItem = m_cTreeCtrl.GetNextSiblingItem (hItem)) + { + UINT iState = m_cTreeCtrl.GetItemState (hItem, TVIS_SELECTED); -void CGenPropertyPage::OnDeleteItem() -{ + if (iState & TVIS_SELECTED) + { + if (ChangeOneItem (dlg, (CString *) m_cTreeCtrl.GetItemData (hItem), 0, hItem)) + break; + } // end if selected + + } // end for each item + + } // end for each group -CUIntArray arySelected; -int iCount = m_ctlList->GetSelectedCount (); -int nItem, - i, - iIncluded = 0, - iExecuting = 0; - arySelected.SetSize (iCount); + } // end of tree control + else + { + // iterate through list in case we implement multiple selection one day + for (int nItem = -1; + (nItem = m_ctlList->GetNextItem(nItem, LVNI_SELECTED)) != -1;) + { - // first, remember selected items -for (nItem = -1, i = 0; - (nItem = m_ctlList->GetNextItem(nItem, LVNI_SELECTED)) != -1;) - arySelected [i++] = nItem; + if (ChangeOneItem (dlg, (CString *) m_ctlList->GetItemData (nItem), nItem, NULL)) + break; -if (iCount == 0) - return; + } // end of dealing with each selected item -if (App.m_bTriggerRemoveCheck) - { - // mucking around to make it plural properly - CString sName = m_strObjectType; - if (iCount > 1) - if (sName == "alias") - sName += "es"; - else - sName += "s"; + } // end of list control - if (::UMessageBox (TFormat ("Delete %i %s - are you sure?", - iCount, sName), MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON2) - != IDYES ) - return; - } // end of wanting to confirm + // redraw the list + if (GetFilterFlag ()) + LoadList (); // full reload because it may have changed filter requirements + + // resort the list + + SortItems (); + +} // end of CGenPropertyPage::OnChangeItem -// we do it this way because deleting items buggers up the position in the array -for (i = iCount - 1; i >= 0; i--) + +///////////////////////////////////////////////////////////////////////////// +// DeleteOneItem + +bool CGenPropertyPage::DeleteOneItem(CString * pstrObjectName, int & iIncluded, int & iExecuting) { - nItem = arySelected [i]; - // get the lower-case name of this item's object - CString * pstrObjectName = (CString *) m_ctlList->GetItemData (nItem); ASSERT (pstrObjectName != NULL); CObject * pItem; // see if in the map if (!m_ObjectMap->Lookup (*pstrObjectName, pItem)) - continue; // already deleted! + return true; // already deleted! ASSERT_VALID (pItem); ASSERT( pItem->IsKindOf( RUNTIME_CLASS( CObject ) ) ); @@ -403,13 +536,13 @@ for (i = iCount - 1; i >= 0; i--) if (CheckIfIncluded (pItem)) { iIncluded++; // don't do message here in case hundreds of them - continue; + return true; } if (CheckIfExecuting (pItem)) { iExecuting++; // don't do message here in case hundreds of them - continue; + return true; } // They can no longer cancel the property sheet, the document has changed @@ -422,14 +555,105 @@ for (i = iCount - 1; i >= 0; i--) // delete the item itself delete pItem; - - // and remove from the dialog list control - m_ctlList->DeleteItem (nItem); // delete its item string delete pstrObjectName; - } // end of dealing with each selected item + return false; // OK return + } + +///////////////////////////////////////////////////////////////////////////// +// OnDeleteItem + +void CGenPropertyPage::OnDeleteItem() +{ + +int iCount = GetSelectedItemCount (); +int nItem, + i, + iIncluded = 0, + iExecuting = 0; + + + if (iCount == 0) + return; + + if (App.m_bTriggerRemoveCheck) + { + // mucking around to make it plural properly + CString sName = m_strObjectType; + if (iCount > 1) + if (sName == "alias") + sName += "es"; + else + sName += "s"; + + if (::UMessageBox (TFormat ("Delete %i %s - are you sure?", + iCount, sName), MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON2) + != IDYES ) + return; + } // end of wanting to confirm + + + // tree control ................ + if (m_bWantTreeControl) + { + // go through entire tree control + for (HTREEITEM hGroup = m_cTreeCtrl.GetRootItem (); + hGroup; + hGroup = m_cTreeCtrl.GetNextSiblingItem (hGroup)) + { + + // find selected items + for (HTREEITEM hItem = m_cTreeCtrl.GetChildItem (hGroup); + hItem; + hItem = m_cTreeCtrl.GetNextSiblingItem (hItem)) + { + UINT iState = m_cTreeCtrl.GetItemState (hItem, TVIS_SELECTED); + + if (iState & TVIS_SELECTED) + { + CString * pstrObjectName = (CString *) m_cTreeCtrl.GetItemData (hItem); + + if (!DeleteOneItem (pstrObjectName, iIncluded, iExecuting)) + { + HTREEITEM hdlParent = m_cTreeCtrl.GetParentItem (hItem); + m_cTreeCtrl.DeleteItem (hItem); + CheckParentHasChildren (hdlParent); + } + + } // end if selected + + } // end for each item + + } // end for each group + + } // end of tree control + else + // list control ................ + { + CUIntArray arySelected; + arySelected.SetSize (iCount); + + // first, remember selected items + for (nItem = -1, i = 0; + (nItem = m_ctlList->GetNextItem(nItem, LVNI_SELECTED)) != -1;) + arySelected [i++] = nItem; + + // we do it this way because deleting items buggers up the position in the array + for (i = iCount - 1; i >= 0; i--) + { + nItem = arySelected [i]; + + // get the lower-case name of this item's object + CString * pstrObjectName = (CString *) m_ctlList->GetItemData (nItem); + + if (!DeleteOneItem (pstrObjectName, iIncluded, iExecuting)) + m_ctlList->DeleteItem (nItem); + + } // end of dealing with each selected item + + } // end of list control if (iIncluded) { @@ -454,6 +678,118 @@ for (i = iCount - 1; i >= 0; i--) } // end of CGenPropertyPage::OnDeleteItem +///////////////////////////////////////////////////////////////////////////// +// OnColumnclickItemList + +void CGenPropertyPage::OnColumnclickItemList(NMHDR* pNMHDR, LRESULT* pResult) +{ + NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; + +int col = pNMListView->iSubItem; + + if (col == m_last_col) + m_reverse = !m_reverse; + else + m_reverse = FALSE; + + m_last_col = col; + + t_gen_sort_param sort_param (m_ObjectMap, m_last_col, m_reverse, m_CompareObjects); + + m_ctlList->SortItems (CompareFunc, (LPARAM) &sort_param); + + *pResult = 0; +} // end of CGenPropertyPage::OnColumnclickItemList + + +///////////////////////////////////////////////////////////////////////////// +// add_list_item + +int CGenPropertyPage::add_list_item (CObject * pItem, + const CString * pstrObjectName, + const int nItem, + const BOOL bInsert) + { + + ASSERT_VALID (pItem); + ASSERT( pItem->IsKindOf( RUNTIME_CLASS( CObject ) ) ); + ASSERT (pstrObjectName != NULL); + + // add to control + int nNewItem = AddItem (pItem, nItem, bInsert); + + // record item's name as the list object data + m_ctlList->SetItemData(nNewItem, (DWORD) pstrObjectName); + + // stamp with a number so we know if it was updated without our knowledge + SetModificationNumber (pItem, m_nUpdateNumber); + + return nNewItem; + + } // end of CGenPropertyPage::add_list_item + + +///////////////////////////////////////////////////////////////////////////// +// add_tree_item + +HTREEITEM CGenPropertyPage::add_tree_item (CObject * pItem, + const CString * pstrObjectName) + { + ASSERT_VALID (pItem); + ASSERT( pItem->IsKindOf( RUNTIME_CLASS( CObject ) ) ); + ASSERT (pstrObjectName != NULL); + + // get group name + CString strGroup = GetGroup (pItem); + if (strGroup.IsEmpty ()) + strGroup = Translate ("(ungrouped)"); + + // see if group exists already + map::const_iterator it; + + it = m_GroupsMap.find (strGroup); + + HTREEITEM hParent; + + // if it exists, find the group tree item (the parent) + // if not, create it + if (it == m_GroupsMap.end ()) + { + hParent = m_cTreeCtrl.InsertItem (strGroup,TVI_ROOT); + m_GroupsMap [strGroup] = hParent; + } + else + hParent = it->second; + + // get the description for the tree control + CString strDescription = GetDescription (pItem); + + // truncate if ridiculously long + if (strDescription.GetLength () > 100) + strDescription = strDescription.Left (100) + " ..."; + + CString strLabel = GetLabel (pItem); + + // add the label if it exists + if (!strLabel.IsEmpty ()) + { + strDescription = strDescription + " ["; + strDescription = strDescription + strLabel; + strDescription = strDescription + "]"; + } + + // insert it + HTREEITEM hNewItem = m_cTreeCtrl.InsertItem (strDescription, hParent); + + // record item's name as the list object data + m_cTreeCtrl.SetItemData (hNewItem, (DWORD) pstrObjectName); + + // stamp with a number so we know if it was updated without our knowledge + SetModificationNumber (pItem, m_nUpdateNumber); + + return hNewItem; + } // end of CGenPropertyPage::add_tree_item + ///////////////////////////////////////////////////////////////////////////// // CompareFunc @@ -500,53 +836,38 @@ int iResult = (*pCompare) (psort_param->sortkey, item1, item2); ///////////////////////////////////////////////////////////////////////////// -// OnColumnclickItemList - -void CGenPropertyPage::OnColumnclickItemList(NMHDR* pNMHDR, LRESULT* pResult) -{ - NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; - -int col = pNMListView->iSubItem; - - if (col == m_last_col) - m_reverse = !m_reverse; - else - m_reverse = FALSE; +// SortItems - m_last_col = col; +void CGenPropertyPage::SortItems (void) + { t_gen_sort_param sort_param (m_ObjectMap, m_last_col, m_reverse, m_CompareObjects); - m_ctlList->SortItems (CompareFunc, (LPARAM) &sort_param); - - *pResult = 0; -} // end of CGenPropertyPage::OnColumnclickItemList - - -///////////////////////////////////////////////////////////////////////////// -// add_item - -int CGenPropertyPage::add_item (CObject * pItem, - const CString * pstrObjectName, - const int nItem, - const BOOL bInsert) - { + if (m_bWantTreeControl) + { + // sort root level into groups + m_cTreeCtrl.SortChildren (TVI_ROOT); - ASSERT_VALID (pItem); - ASSERT( pItem->IsKindOf( RUNTIME_CLASS( CObject ) ) ); - ASSERT (pstrObjectName != NULL); + TVSORTCB cbinfo; + cbinfo.lpfnCompare = CompareFunc; + cbinfo.lParam = (LPARAM) &sort_param; - int nNewItem = AddItem (pItem, nItem, bInsert); + // now sort each child + HTREEITEM hdlItem = m_cTreeCtrl.GetNextItem (NULL, TVGN_ROOT); - // record item's name as the list object data - m_ctlList->SetItemData(nNewItem, (DWORD) pstrObjectName); + while (hdlItem) + { + cbinfo.hParent = hdlItem; + m_cTreeCtrl.SortChildrenCB (&cbinfo ); + hdlItem = m_cTreeCtrl.GetNextItem (hdlItem, TVGN_NEXT); + } - // stamp with a number so we know if it was updated without our knowledge - SetModificationNumber (pItem, m_nUpdateNumber); + } + else + m_ctlList->SortItems (CompareFunc, (LPARAM) &sort_param); - return nNewItem; - } // end of CGenPropertyPage::add_item + } // end of CGenPropertyPage::SortItems ///////////////////////////////////////////////////////////////////////////// // LoadList @@ -602,13 +923,34 @@ void CGenPropertyPage::LoadList (void) bFiltering = false; } - // remove all old items (we used the item data to key to the item) + // we delete from both the list and the tree in case we are switching + // from list view to tree view or vice-versa + + // remove all old list items (we used the item data to key to the item) for (int nItem = 0; nItem < m_ctlList->GetItemCount (); nItem++) delete (CString *) m_ctlList->GetItemData (nItem); m_ctlList->DeleteAllItems (); + + // and now all old tree items + for (HTREEITEM hGroup = m_cTreeCtrl.GetRootItem (); + hGroup; + hGroup = m_cTreeCtrl.GetNextSiblingItem (hGroup)) + { + + for (HTREEITEM hItem = m_cTreeCtrl.GetChildItem (hGroup); + hItem; + hItem = m_cTreeCtrl.GetNextSiblingItem (hItem)) + delete (CString *) m_cTreeCtrl.GetItemData (hItem); + + } // end for each group + + m_cTreeCtrl.DeleteAllItems (); + // since all is deleted, we don't have any groups any more + m_GroupsMap.erase (m_GroupsMap.begin (), m_GroupsMap.end ()); + CString strObjectName; CObject * pItem; @@ -646,14 +988,15 @@ void CGenPropertyPage::LoadList (void) if (bUse) // add to list if passed filter { CString * pstrObjectName = new CString (strObjectName); - add_item (pItem, pstrObjectName, 0, TRUE); + if (m_bWantTreeControl) + add_tree_item (pItem, pstrObjectName); + else + add_list_item (pItem, pstrObjectName, 0, TRUE); iCount++; } } - t_gen_sort_param sort_param (m_ObjectMap, m_last_col, m_reverse, m_CompareObjects); - - m_ctlList->SortItems (CompareFunc, (LPARAM) &sort_param); + SortItems (); // set the 1st item to be selected - we do this here because sorting the // list means our first item is not necessarily the 1st item in the list @@ -687,7 +1030,7 @@ LRESULT CGenPropertyPage::OnKickIdle(WPARAM, LPARAM) void CGenPropertyPage::OnUpdateNeedSelection(CCmdUI* pCmdUI) { - pCmdUI->Enable (m_ctlList->GetSelectedCount () != 0); + pCmdUI->Enable (GetSelectedItemCount () != 0); } // end of CGenPropertyPage::OnUpdateNeedSelection ///////////////////////////////////////////////////////////////////////////// @@ -695,10 +1038,43 @@ void CGenPropertyPage::OnUpdateNeedSelection(CCmdUI* pCmdUI) void CGenPropertyPage::OnUpdateNeedEntries(CCmdUI* pCmdUI) { - pCmdUI->Enable (m_ctlList->GetItemCount () != 0); + pCmdUI->Enable (GetItemCount () > 0); } // end of CGenPropertyPage::OnUpdateNeedEntries +///////////////////////////////////////////////////////////////////////////// +// get_tree_item + +HTREEITEM CGenPropertyPage::get_tree_item (CTreeCtrl * pTree, const int n) + { + HTREEITEM hItem = NULL; + int iCount = 0; + bool bFound = false; + + for (HTREEITEM hGroup = pTree->GetRootItem (); + hGroup && !bFound; + hGroup = pTree->GetNextSiblingItem (hGroup)) + { + for (hItem = pTree->GetChildItem (hGroup); + hItem && !bFound; + hItem = pTree->GetNextSiblingItem (hItem)) + { + if (iCount == n) + { + bFound = true; + break; + } + iCount++; + } + } // end for each group + + if (bFound) + return hItem; + + return NULL; + + } // end of CGenPropertyPage::get_tree_item + ///////////////////////////////////////////////////////////////////////////// // DoFind @@ -706,55 +1082,100 @@ void CGenPropertyPage::DoFind (bool bAgain) { m_pObjectFindInfo->m_bAgain = bAgain; -m_pObjectFindInfo->m_nTotalLines = m_ctlList->GetItemCount (); +m_pObjectFindInfo->m_nTotalLines = GetItemCount (); + +bool found; + + if (m_bWantTreeControl) + { + + found = FindRoutine (this, // passed back to callback routines + *m_pObjectFindInfo, // finding structure + InitiateSearch, // how to re-initiate a find + GetNextTreeLine); // get the next line + // unselect everything first + for (HTREEITEM hGroup = m_cTreeCtrl.GetRootItem (); + hGroup; + hGroup = m_cTreeCtrl.GetNextSiblingItem (hGroup)) + { + for (HTREEITEM hItem = m_cTreeCtrl.GetChildItem (hGroup); + hItem; + hItem = m_cTreeCtrl.GetNextSiblingItem (hItem)) + m_cTreeCtrl.SetItemState (hItem, 0, TVIS_SELECTED); + } // end for each group + + if (found) + { + + HTREEITEM hItem = get_tree_item (&m_cTreeCtrl, m_pObjectFindInfo->m_nCurrentLine); -bool found = FindRoutine (m_ctlList, // passed back to callback routines + if (!hItem) + return; + + // select the new item + m_cTreeCtrl.SelectItem (hItem); + m_cTreeCtrl.EnsureVisible (hItem); + + } + + } // end of tree control + else + { + found = FindRoutine (this, // passed back to callback routines *m_pObjectFindInfo, // finding structure InitiateSearch, // how to re-initiate a find - GetNextLine); // get the next line + GetNextListLine); // get the next line + // unselect everything first + for (int i = 0; i < m_ctlList->GetItemCount (); i++) + m_ctlList->SetItemState (i, 0, LVIS_FOCUSED | LVIS_SELECTED); -// unselect everything first + if (found) + { + m_ctlList->SetItemState (m_pObjectFindInfo->m_nCurrentLine, + LVIS_FOCUSED | LVIS_SELECTED, + LVIS_FOCUSED | LVIS_SELECTED); + m_ctlList->EnsureVisible (m_pObjectFindInfo->m_nCurrentLine, false); + m_ctlList->RedrawItems (m_pObjectFindInfo->m_nCurrentLine, + m_pObjectFindInfo->m_nCurrentLine); -for (int i = 0; i < m_ctlList->GetItemCount (); i++) - m_ctlList->SetItemState (i, 0, LVIS_FOCUSED | LVIS_SELECTED); + } + + } -if (found) - { - m_ctlList->SetItemState (m_pObjectFindInfo->m_nCurrentLine, - LVIS_FOCUSED | LVIS_SELECTED, - LVIS_FOCUSED | LVIS_SELECTED); - m_ctlList->EnsureVisible (m_pObjectFindInfo->m_nCurrentLine, false); - m_ctlList->RedrawItems (m_pObjectFindInfo->m_nCurrentLine, - m_pObjectFindInfo->m_nCurrentLine); - } } // end of CGenPropertyPage::DoFind +///////////////////////////////////////////////////////////////////////////// +// InitiateSearch + void CGenPropertyPage::InitiateSearch (const CObject * pObject, CFindInfo & FindInfo) { -CListCtrl* pList = (CListCtrl*) pObject; - if (FindInfo.m_bAgain) FindInfo.m_pFindPosition = (POSITION) FindInfo.m_nCurrentLine; else if (FindInfo.m_bForwards) FindInfo.m_pFindPosition = 0; else - FindInfo.m_pFindPosition = (POSITION) pList->GetItemCount () - 1; + FindInfo.m_pFindPosition = (POSITION) FindInfo.m_nTotalLines - 1; } // end of CGenPropertyPage::InitiateSearch -bool CGenPropertyPage::GetNextLine (const CObject * pObject, - CFindInfo & FindInfo, - CString & strLine) +///////////////////////////////////////////////////////////////////////////// +// GetNextListLine + +bool CGenPropertyPage::GetNextListLine (const CObject * pObject, + CFindInfo & FindInfo, + CString & strLine) { -CListCtrl* pList = (CListCtrl*) pObject; +CGenPropertyPage * pPropPage = (CGenPropertyPage *) pObject; + +CListCtrl* pList = pPropPage->m_ctlList; if ((long) FindInfo.m_pFindPosition < 0 || - (long) FindInfo.m_pFindPosition >= pList->GetItemCount ()) + (long) FindInfo.m_pFindPosition >= FindInfo.m_nTotalLines) return true; @@ -774,13 +1195,88 @@ CListCtrl* pList = (CListCtrl*) pObject; FindInfo.m_pFindPosition--; return false; - } // end of CGenPropertyPage::GetNextLine + } // end of CGenPropertyPage::GetNextListLine + +///////////////////////////////////////////////////////////////////////////// +// GetNextTreeLine + +bool CGenPropertyPage::GetNextTreeLine (const CObject * pObject, + CFindInfo & FindInfo, + CString & strLine) + { +CGenPropertyPage * pPropPage = (CGenPropertyPage *) pObject; + +CTreeCtrl* pTree = &pPropPage->m_cTreeCtrl; + + if ((long) FindInfo.m_pFindPosition < 0 || + (long) FindInfo.m_pFindPosition >= FindInfo.m_nTotalLines) + return true; + + + HTREEITEM hItem = get_tree_item (pTree, (int) FindInfo.m_pFindPosition); + + if (!hItem) + return true; + + + CString * pstrObjectName = (CString *) pTree->GetItemData (hItem); + + + ASSERT (pstrObjectName != NULL); + + CObject * pItem; + + if (!pPropPage->m_ObjectMap->Lookup (*pstrObjectName, pItem)) + return true; + + ASSERT_VALID (pItem); + ASSERT( pItem->IsKindOf( RUNTIME_CLASS( CObject ) ) ); + + strLine = pPropPage->GetFindText (pItem); + + if (FindInfo.m_bForwards) + FindInfo.m_pFindPosition++; + else + FindInfo.m_pFindPosition--; + + return false; + } // end of CGenPropertyPage::GetNextTreeLine +///////////////////////////////////////////////////////////////////////////// +// OnInitDialog + BOOL CGenPropertyPage::OnInitDialog() { CPropertyPage::OnInitDialog(); + // Tree View stuff + + WINDOWPLACEMENT wndpl; // where original control is + m_ctlList->GetWindowPlacement (&wndpl); + + // add in the tree control + m_cTreeCtrl.CWnd::CreateEx(WS_EX_CLIENTEDGE, + WC_TREEVIEW, + NULL, + WS_CHILD|WS_VISIBLE|WS_TABSTOP|TVS_SHOWSELALWAYS| + TVS_HASLINES|TVS_LINESATROOT|TVS_HASBUTTONS, + wndpl.rcNormalPosition.left, + wndpl.rcNormalPosition.top, + wndpl.rcNormalPosition.right - wndpl.rcNormalPosition.left, + wndpl.rcNormalPosition.bottom - wndpl.rcNormalPosition.top, + GetSafeHwnd(), + (HMENU)ID_TREEVIEW); + + + // now hide one of the controls + if (m_bWantTreeControl) + m_ctlList->ShowWindow (SW_HIDE); + else + m_cTreeCtrl.ShowWindow (SW_HIDE); + + // end tree view stuff + CString strDescription = m_strObjectType; strDescription += " list"; @@ -809,6 +1305,9 @@ BOOL CGenPropertyPage::OnInitDialog() // EXCEPTION: OCX Property Pages should return FALSE } +///////////////////////////////////////////////////////////////////////////// +// OnDestroy + void CGenPropertyPage::OnDestroy() { @@ -818,10 +1317,20 @@ void CGenPropertyPage::OnDestroy() // delete the object names which we stored as the item data for (int nItem = 0; nItem < m_ctlList->GetItemCount (); nItem++) + delete (CString *) m_ctlList->GetItemData (nItem); + + // and now all old tree items + for (HTREEITEM hGroup = m_cTreeCtrl.GetRootItem (); + hGroup; + hGroup = m_cTreeCtrl.GetNextSiblingItem (hGroup)) { - CString * pstrObjectName = (CString *) m_ctlList->GetItemData (nItem); - delete pstrObjectName; - } + + for (HTREEITEM hItem = m_cTreeCtrl.GetChildItem (hGroup); + hItem; + hItem = m_cTreeCtrl.GetNextSiblingItem (hItem)) + delete (CString *) m_cTreeCtrl.GetItemData (hItem); + + } // end for each group App.SaveColumnConfiguration (strDescription, m_iColumnCount, *m_ctlList, m_last_col, m_reverse); @@ -830,17 +1339,72 @@ void CGenPropertyPage::OnDestroy() } +///////////////////////////////////////////////////////////////////////////// +// OnFind + void CGenPropertyPage::OnFind() { DoFind (false); } // end of CGenPropertyPage::OnFind +///////////////////////////////////////////////////////////////////////////// +// OnFindNext + void CGenPropertyPage::OnFindNext() { DoFind (true); } // end of CGenPropertyPage::OnFindNext +///////////////////////////////////////////////////////////////////////////// +// CopyOneItem + +bool CGenPropertyPage::CopyOneItem(CString * pstrObjectName, CArchive & ar) + { + ASSERT (pstrObjectName != NULL); + + CObject * pItem; + + // check object is still there (it might have gone while we looked at the list box) + if (!m_ObjectMap->Lookup (*pstrObjectName, pItem)) + { + CString strMsg; + + // in the case of one-shot timers, unnamed items might be removed from the list + if (pstrObjectName->Left (1) == "*") + strMsg = TFormat ("The %s you selected is no longer in the %s list", + (LPCTSTR) m_strObjectType, + (LPCTSTR) m_strObjectType); + else + strMsg = TFormat ("The %s named \"%s\" is no longer in the %s list", + (LPCTSTR) m_strObjectType, + (LPCTSTR) *pstrObjectName, + (LPCTSTR) m_strObjectType); + + ::UMessageBox (strMsg); + + delete pstrObjectName; // and get rid of its name string + return true; + } + + ASSERT_VALID (pItem); + ASSERT( pItem->IsKindOf( RUNTIME_CLASS( CObject ) ) ); + + // turn into XML + + if (m_strObjectType == "trigger") + m_doc->Save_One_Trigger_XML (ar, (CTrigger *) pItem); + else if (m_strObjectType == "alias") + m_doc->Save_One_Alias_XML (ar, (CAlias *) pItem); + else if (m_strObjectType == "timer") + m_doc->Save_One_Timer_XML (ar, (CTimer *) pItem); + else if (m_strObjectType == "variable") + m_doc->Save_One_Variable_XML (ar, (CVariable *) pItem); + + return false; + + } // end of CGenPropertyPage::CopyOneItem + ///////////////////////////////////////////////////////////////////////////// // OnCopyItem @@ -860,56 +1424,46 @@ try else m_doc->Save_Header_XML (ar, m_strObjectType + "s", false); // timers, triggers etc. - for (int nItem = -1; - (nItem = m_ctlList->GetNextItem(nItem, LVNI_SELECTED)) != -1;) - { - - // get the lower-case name of this item's object - CString * pstrObjectName = (CString *) m_ctlList->GetItemData (nItem); - ASSERT (pstrObjectName != NULL); - - CObject * pItem; - - // check object is still there (it might have gone while we looked at the list box) - if (!m_ObjectMap->Lookup (*pstrObjectName, pItem)) + if (m_bWantTreeControl) + { + for (HTREEITEM hGroup = m_cTreeCtrl.GetRootItem (); + hGroup; + hGroup = m_cTreeCtrl.GetNextSiblingItem (hGroup)) { - CString strMsg; - - m_ctlList->DeleteItem (nItem); // it's gone, so delete it from the list view - m_ctlList->RedrawItems (0, m_ctlList->GetItemCount () - 1); // redraw the list - // in the case of one-shot timers, unnamed items might be removed from the list - if (pstrObjectName->Left (1) == "*") - strMsg = TFormat ("The %s you selected is no longer in the %s list", - (LPCTSTR) m_strObjectType, - (LPCTSTR) m_strObjectType); - else - strMsg = TFormat ("The %s named \"%s\" is no longer in the %s list", - (LPCTSTR) m_strObjectType, - (LPCTSTR) *pstrObjectName, - (LPCTSTR) m_strObjectType); + for (HTREEITEM hItem = m_cTreeCtrl.GetChildItem (hGroup); + hItem; + hItem = m_cTreeCtrl.GetNextSiblingItem (hItem)) + { + UINT iState = m_cTreeCtrl.GetItemState (hItem, TVIS_SELECTED); - ::UMessageBox (strMsg); + if (iState & TVIS_SELECTED) + { + if (CopyOneItem ((CString *) m_cTreeCtrl.GetItemData (hItem), ar)) + { + m_cTreeCtrl.DeleteItem (hItem); + } + } // end if selected - delete pstrObjectName; // and get rid of its name string - continue; - } - - ASSERT_VALID (pItem); - ASSERT( pItem->IsKindOf( RUNTIME_CLASS( CObject ) ) ); + } // end for each item - // turn into XML + } // end for each group - if (m_strObjectType == "trigger") - m_doc->Save_One_Trigger_XML (ar, (CTrigger *) pItem); - else if (m_strObjectType == "alias") - m_doc->Save_One_Alias_XML (ar, (CAlias *) pItem); - else if (m_strObjectType == "timer") - m_doc->Save_One_Timer_XML (ar, (CTimer *) pItem); - else if (m_strObjectType == "variable") - m_doc->Save_One_Variable_XML (ar, (CVariable *) pItem); - } // end of dealing with each selected item + } // end of tree control + else + { // list control + for (int nItem = -1; + (nItem = m_ctlList->GetNextItem(nItem, LVNI_SELECTED)) != -1;) + { + if (CopyOneItem ((CString *) m_ctlList->GetItemData (nItem), ar)) + { + m_ctlList->DeleteItem (nItem); // it's gone, so delete it from the list view + m_ctlList->RedrawItems (0, m_ctlList->GetItemCount () - 1); // redraw the list + } + + } // end of dealing with each selected item + } // end of list control if (m_strObjectType == "alias") m_doc->Save_Footer_XML (ar, "aliases"); @@ -940,6 +1494,9 @@ catch (CException* e) } // end of CGenPropertyPage::OnCopyItem +///////////////////////////////////////////////////////////////////////////// +// OnPasteItem + void CGenPropertyPage::OnPasteItem() { CString strContents; @@ -974,6 +1531,8 @@ CString strContents; } // end of CGenPropertyPage::OnPasteItem +///////////////////////////////////////////////////////////////////////////// +// EditFilterText bool CGenPropertyPage::EditFilterText (CString & sText)// edit the filter text { @@ -995,5 +1554,5 @@ CEditMultiLine dlg; sText = dlg.m_strText; return true; - } + } // end of CGenPropertyPage::EditFilterText diff --git a/dialogs/world_prefs/prefspropertypages.cpp b/dialogs/world_prefs/prefspropertypages.cpp index 124178c0..ffc51cd1 100644 --- a/dialogs/world_prefs/prefspropertypages.cpp +++ b/dialogs/world_prefs/prefspropertypages.cpp @@ -2576,6 +2576,7 @@ BEGIN_MESSAGE_MAP(CPrefsP7, CGenPropertyPage) ON_UPDATE_COMMAND_UI(IDC_USE_DEFAULT_ALIASES, OnUpdateHaveDefaults) ON_UPDATE_COMMAND_UI(IDC_MOVE_UP, OnUpdateCanSequence) ON_UPDATE_COMMAND_UI(IDC_MOVE_DOWN, OnUpdateCanSequence) + ON_NOTIFY(NM_DBLCLK, ID_TREEVIEW, OnDblclkAliasesList) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// @@ -2745,6 +2746,55 @@ CString CPrefsP7::GetLabel (CObject * pItem) const } // end of CPrefsP7::GetLabel +CString CPrefsP7::GetGroup (CObject * pItem) const + { + CAlias * alias_item = (CAlias *) pItem; + + ASSERT_VALID (alias_item); + ASSERT( alias_item->IsKindOf( RUNTIME_CLASS( CAlias ) ) ); + + return alias_item->strGroup; + + } // end of CPrefsP7::GetGroup + +CString CPrefsP7::GetDescription (CObject * pItem) const + { + CAlias * alias_item = (CAlias *) pItem; + + ASSERT_VALID (alias_item); + ASSERT( alias_item->IsKindOf( RUNTIME_CLASS( CAlias ) ) ); + + return alias_item->name; + + } // end of CPrefsP7::GetDescription + +int CPrefsP7::GetSequence (CObject * pItem) const + { + CAlias * alias_item = (CAlias *) pItem; + + ASSERT_VALID (alias_item); + ASSERT( alias_item->IsKindOf( RUNTIME_CLASS( CAlias ) ) ); + + return alias_item->iSequence; + + } // end of CPrefsP7::GetSequence + +CString CPrefsP7::GetFindText (CObject * pItem) const + { + CAlias * alias_item = (CAlias *) pItem; + + ASSERT_VALID (alias_item); + ASSERT( alias_item->IsKindOf( RUNTIME_CLASS( CAlias ) ) ); + + + CString strResult = alias_item->name; + + strResult += "\t" + alias_item->contents + "\t" + alias_item->strLabel + "\t" + alias_item->strGroup; + + return strResult; + + } // end of CPrefsP7::GetFindText + void CPrefsP7::SetDispatchID (CObject * pItem, const DISPID dispid) { CAlias * alias_item = (CAlias *) pItem; @@ -2976,7 +3026,7 @@ int nItem; return nItem; - } // end of CPrefsP7::add_item + } // end of CPrefsP7::AddItem BOOL CPrefsP7::OnInitDialog() @@ -3067,18 +3117,26 @@ for (int nItem = -1; m_doc->SetModifiedFlag (TRUE); // re-setup list with amended details - add_item (pItem, pstrObjectName, nItem, FALSE); + + if (m_bWantTreeControl) + { + // m_cTreeCtrl.DeleteItem (hdlItem); + // HTREEITEM hItem = add_tree_item (pItem, pstrObjectName); + } + else + add_list_item (pItem, pstrObjectName, nItem, FALSE); } } // end of dealing with each selected item // resort the list - t_gen_sort_param sort_param (m_ObjectMap, m_last_col, m_reverse, m_CompareObjects); - m_ctlList->SortItems (CompareFunc, (LPARAM) &sort_param); - m_ctlList->RedrawItems (0, m_ctlList->GetItemCount () - 1); // redraw the list + SortItems (); + + if (!m_bWantTreeControl) + m_ctlList->RedrawItems (0, m_ctlList->GetItemCount () - 1); // redraw the list -} +} // end of CPrefsP7::OnMoveUp void CPrefsP7::OnMoveDown() { @@ -3151,19 +3209,26 @@ for (int nItem = -1; m_doc->SetModifiedFlag (TRUE); // re-setup list with amended details - add_item (pItem, pstrObjectName, nItem, FALSE); + if (m_bWantTreeControl) + { + // m_cTreeCtrl.DeleteItem (hdlItem); + // HTREEITEM hItem = add_tree_item (pItem, pstrObjectName); + } + else + add_list_item (pItem, pstrObjectName, nItem, FALSE); } } // end of dealing with each selected item // resort the list - t_gen_sort_param sort_param (m_ObjectMap, m_last_col, m_reverse, m_CompareObjects); - m_ctlList->SortItems (CompareFunc, (LPARAM) &sort_param); - m_ctlList->RedrawItems (0, m_ctlList->GetItemCount () - 1); // redraw the list + SortItems (); + + if (!m_bWantTreeControl) + m_ctlList->RedrawItems (0, m_ctlList->GetItemCount () - 1); // redraw the list -} +} // end of CPrefsP7::OnMoveDown void CPrefsP7::OnUpdateNotUsingDefaults(CCmdUI* pCmdUI) { @@ -3179,14 +3244,16 @@ void CPrefsP7::OnUpdateHaveDefaults(CCmdUI* pCmdUI) void CPrefsP7::OnUpdateNeedSelection(CCmdUI* pCmdUI) { - pCmdUI->Enable (m_ctlList->GetSelectedCount () != 0 && + + pCmdUI->Enable (GetSelectedItemCount () != 0 && (m_ctlUseDefaultAliases.GetCheck () == 0 || App.m_strDefaultAliasesFile.IsEmpty ())); } // end of CPrefsP7::OnUpdateNeedSelection void CPrefsP7::OnUpdateNeedOneSelection(CCmdUI* pCmdUI) { - pCmdUI->Enable (m_ctlList->GetSelectedCount () == 1 && + + pCmdUI->Enable (GetSelectedItemCount () == 1 && (m_ctlUseDefaultAliases.GetCheck () == 0 || App.m_strDefaultAliasesFile.IsEmpty ())); } // end of CPrefsP7::OnUpdateNeedOneSelection @@ -3426,6 +3493,7 @@ BEGIN_MESSAGE_MAP(CPrefsP8, CGenPropertyPage) ON_UPDATE_COMMAND_UI(IDC_ADD_TRIGGER, OnUpdateNotUsingDefaults) ON_UPDATE_COMMAND_UI(IDC_LOAD_TRIGGER, OnUpdateNotUsingDefaults) ON_UPDATE_COMMAND_UI(IDC_USE_DEFAULT_TRIGGERS, OnUpdateHaveDefaults) + ON_NOTIFY(NM_DBLCLK, ID_TREEVIEW, OnDblclkTriggersList) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// @@ -3730,6 +3798,55 @@ CString CPrefsP8::GetLabel (CObject * pItem) const } // end of CPrefsP8::GetLabel +CString CPrefsP8::GetGroup (CObject * pItem) const + { + CTrigger * trigger_item = (CTrigger *) pItem; + + ASSERT_VALID (trigger_item); + ASSERT( trigger_item->IsKindOf( RUNTIME_CLASS( CTrigger ) ) ); + + return trigger_item->strGroup; + + } // end of CPrefsP8::GetGroup + +CString CPrefsP8::GetDescription (CObject * pItem) const + { + CTrigger * trigger_item = (CTrigger *) pItem; + + ASSERT_VALID (trigger_item); + ASSERT( trigger_item->IsKindOf( RUNTIME_CLASS( CTrigger ) ) ); + + return trigger_item->trigger; + + } // end of CPrefsP8::GetDescription + +int CPrefsP8::GetSequence (CObject * pItem) const + { + CTrigger * trigger_item = (CTrigger *) pItem; + + ASSERT_VALID (trigger_item); + ASSERT( trigger_item->IsKindOf( RUNTIME_CLASS( CTrigger ) ) ); + + return trigger_item->iSequence; + + } // end of CPrefsP8::GetSequence + +CString CPrefsP8::GetFindText (CObject * pItem) const + { + CTrigger * trigger_item = (CTrigger *) pItem; + + ASSERT_VALID (trigger_item); + ASSERT( trigger_item->IsKindOf( RUNTIME_CLASS( CTrigger ) ) ); + + + CString strResult = trigger_item->trigger; + + strResult += "\t" + trigger_item->contents + "\t" + trigger_item->strLabel + "\t" + trigger_item->strGroup; + + return strResult; + + } // end of CPrefsP8::GetFindText + void CPrefsP8::SetDispatchID (CObject * pItem, const DISPID dispid) { CTrigger * trigger_item = (CTrigger *) pItem; @@ -4034,7 +4151,7 @@ int nItem; return nItem; - } // end of CPrefsP8::add_item + } // end of CPrefsP8::AddItem void CPrefsP8::OnMoveUp() { @@ -4106,18 +4223,25 @@ for (int nItem = -1; m_doc->SetModifiedFlag (TRUE); // re-setup list with amended details - add_item (pItem, pstrObjectName, nItem, FALSE); + if (m_bWantTreeControl) + { + // m_cTreeCtrl.DeleteItem (hdlItem); + // HTREEITEM hItem = add_tree_item (pItem, pstrObjectName); + } + else + add_list_item (pItem, pstrObjectName, nItem, FALSE); } } // end of dealing with each selected item // resort the list - t_gen_sort_param sort_param (m_ObjectMap, m_last_col, m_reverse, m_CompareObjects); - m_ctlList->SortItems (CompareFunc, (LPARAM) &sort_param); - m_ctlList->RedrawItems (0, m_ctlList->GetItemCount () - 1); // redraw the list + SortItems (); + + if (!m_bWantTreeControl) + m_ctlList->RedrawItems (0, m_ctlList->GetItemCount () - 1); // redraw the list -} +} // end of CPrefsP8::OnMoveUp void CPrefsP8::OnMoveDown() { @@ -4190,19 +4314,26 @@ for (int nItem = -1; m_doc->SetModifiedFlag (TRUE); // re-setup list with amended details - add_item (pItem, pstrObjectName, nItem, FALSE); + if (m_bWantTreeControl) + { + // m_cTreeCtrl.DeleteItem (hdlItem); + // HTREEITEM hItem = add_tree_item (pItem, pstrObjectName); + } + else + add_list_item (pItem, pstrObjectName, nItem, FALSE); } } // end of dealing with each selected item // resort the list - t_gen_sort_param sort_param (m_ObjectMap, m_last_col, m_reverse, m_CompareObjects); - m_ctlList->SortItems (CompareFunc, (LPARAM) &sort_param); - m_ctlList->RedrawItems (0, m_ctlList->GetItemCount () - 1); // redraw the list + SortItems (); + + if (!m_bWantTreeControl) + m_ctlList->RedrawItems (0, m_ctlList->GetItemCount () - 1); // redraw the list -} +} // end of CPrefsP8::OnMoveDown void CPrefsP8::OnUpdateCanSequence(CCmdUI* pCmdUI) { @@ -4227,14 +4358,14 @@ void CPrefsP8::OnUpdateHaveDefaults(CCmdUI* pCmdUI) void CPrefsP8::OnUpdateNeedSelection(CCmdUI* pCmdUI) { - pCmdUI->Enable (m_ctlList->GetSelectedCount () != 0 && + pCmdUI->Enable (GetSelectedItemCount () != 0 && (m_ctlUseDefaultTriggers.GetCheck () == 0 || App.m_strDefaultTriggersFile.IsEmpty ())); } // end of CGenPropertyPage::OnUpdateNeedSelection void CPrefsP8::OnUpdateNeedOneSelection(CCmdUI* pCmdUI) { - pCmdUI->Enable (m_ctlList->GetSelectedCount () == 1 && + pCmdUI->Enable (GetSelectedItemCount () == 1 && (m_ctlUseDefaultTriggers.GetCheck () == 0 || App.m_strDefaultTriggersFile.IsEmpty ())); } // end of CGenPropertyPage::OnUpdateNeedOneSelection @@ -5986,6 +6117,7 @@ BEGIN_MESSAGE_MAP(CPrefsP16, CGenPropertyPage) ON_UPDATE_COMMAND_UI(IDC_FIND_NEXT, OnUpdateNeedEntries) ON_UPDATE_COMMAND_UI(IDC_LOAD_TIMERS, OnUpdateNotUsingDefaults) ON_UPDATE_COMMAND_UI(IDC_USE_DEFAULT_TIMERS, OnUpdateHaveDefaults) + ON_NOTIFY(NM_DBLCLK, ID_TREEVIEW, OnDblclkTimersList) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// @@ -6128,7 +6260,95 @@ CString CPrefsP16::GetLabel (CObject * pItem) const return timer_item->strLabel; } // end of CPrefsP16::GetLabel + +CString CPrefsP16::GetGroup (CObject * pItem) const + { + CTimer * timer_item = (CTimer *) pItem; + + ASSERT_VALID (timer_item); + ASSERT( timer_item->IsKindOf( RUNTIME_CLASS( CTimer ) ) ); + + return timer_item->strGroup; + + } // end of CPrefsP16::GetGroup +CString CPrefsP16::GetDescription (CObject * pItem) const + { + CTimer * timer_item = (CTimer *) pItem; + + ASSERT_VALID (timer_item); + ASSERT( timer_item->IsKindOf( RUNTIME_CLASS( CTimer ) ) ); + +CString strType; +CString strWhen; + + switch (timer_item->iType) + { + case CTimer::eAtTime: + strType = "At: "; + strWhen.Format ("%02i:%02i:%04.2f", + timer_item->iAtHour, + timer_item->iAtMinute, + timer_item->fAtSecond); + break; + + case CTimer::eInterval: + strType = "Every: "; + if (timer_item->iOffsetHour || + timer_item->iOffsetMinute || + timer_item->fOffsetSecond != 0.0) + strWhen.Format ("%02i:%02i:%04.2f offset %02i:%02i:%04.2f", + timer_item->iEveryHour, + timer_item->iEveryMinute, + timer_item->fEverySecond, + timer_item->iOffsetHour, + timer_item->iOffsetMinute, + timer_item->fOffsetSecond); + else + strWhen.Format ("%02i:%02i:%04.2f", + timer_item->iEveryHour, + timer_item->iEveryMinute, + timer_item->fEverySecond); + + break; + + default: strType = "Unknown: "; + strWhen = "00:00:00.00"; + break; + } + + strType = strType + strWhen; + return strType; + + } // end of CPrefsP16::GetDescription + +int CPrefsP16::GetSequence (CObject * pItem) const + { + CTimer * timer_item = (CTimer *) pItem; + + ASSERT_VALID (timer_item); + ASSERT( timer_item->IsKindOf( RUNTIME_CLASS( CTimer ) ) ); + + return 0; + + } // end of CPrefsP16::GetSequence + +CString CPrefsP16::GetFindText (CObject * pItem) const + { + CTimer * timer_item = (CTimer *) pItem; + + ASSERT_VALID (timer_item); + ASSERT( timer_item->IsKindOf( RUNTIME_CLASS( CTimer ) ) ); + + + CString strResult = timer_item->strContents; + + strResult += timer_item->strLabel + "\t" + timer_item->strGroup; + + return strResult; + + } // end of CPrefsP16::GetFindText + void CPrefsP16::SetDispatchID (CObject * pItem, const DISPID dispid) { CTimer * timer_item = (CTimer *) pItem; @@ -6461,7 +6681,7 @@ CString strWhen; return nItem; - } // end of CPrefsP16::add_item + } // end of CPrefsP16::AddItem BOOL CPrefsP16::OnInitDialog() @@ -6499,14 +6719,14 @@ void CPrefsP16::OnUpdateHaveDefaults(CCmdUI* pCmdUI) void CPrefsP16::OnUpdateNeedSelection(CCmdUI* pCmdUI) { - pCmdUI->Enable (m_ctlList->GetSelectedCount () != 0 && + pCmdUI->Enable (GetSelectedItemCount () != 0 && (m_ctlUseDefaultTimers.GetCheck () == 0 || App.m_strDefaultTimersFile.IsEmpty ())); } // end of CPrefsP16::OnUpdateNeedSelection void CPrefsP16::OnUpdateNeedOneSelection(CCmdUI* pCmdUI) { - pCmdUI->Enable (m_ctlList->GetSelectedCount () == 1 && + pCmdUI->Enable (GetSelectedItemCount () == 1 && (m_ctlUseDefaultTimers.GetCheck () == 0 || App.m_strDefaultTimersFile.IsEmpty ())); } // end of CPrefsP16::OnUpdateNeedOneSelection @@ -7403,7 +7623,7 @@ int nItem; return nItem; - } // end of CPrefsP18::add_item + } // end of CPrefsP18::AddItem void CPrefsP18::OnFind() { diff --git a/dialogs/world_prefs/prefspropertypages.h b/dialogs/world_prefs/prefspropertypages.h index 3d1750ea..ee05d1be 100644 --- a/dialogs/world_prefs/prefspropertypages.h +++ b/dialogs/world_prefs/prefspropertypages.h @@ -593,7 +593,11 @@ class CPrefsP7 : public CGenPropertyPage // get info about the object virtual __int64 GetModificationNumber (CObject * pItem) const; // get modification number virtual CString GetScriptName (CObject * pItem) const; // get script subroutine name - virtual CString GetLabel (CObject * pItem) const; // get label name + virtual CString GetLabel (CObject * pItem) const; // get label name + virtual CString GetGroup (CObject * pItem) const; // get item group + virtual CString GetDescription (CObject * pItem) const; // get item description for tree control + virtual int GetSequence (CObject * pItem) const; // get item sequence for sorting + virtual CString GetFindText (CObject * pItem) const; // get text for searching on // list management - add the item to the list control virtual int AddItem (CObject * pItem, // add one item to the list control @@ -716,7 +720,11 @@ class CPrefsP8 : public CGenPropertyPage // get info about the object virtual __int64 GetModificationNumber (CObject * pItem) const; // get modification number virtual CString GetScriptName (CObject * pItem) const; // get script subroutine name - virtual CString GetLabel (CObject * pItem) const; // get label name + virtual CString GetLabel (CObject * pItem) const; // get label name + virtual CString GetGroup (CObject * pItem) const; // get item group + virtual CString GetDescription (CObject * pItem) const; // get item description for tree control + virtual int GetSequence (CObject * pItem) const; // get item sequence for sorting + virtual CString GetFindText (CObject * pItem) const; // get text for searching on // list management - add the item to the list control virtual int AddItem (CObject * pItem, // add one item to the list control @@ -1303,7 +1311,11 @@ class CPrefsP16 : public CGenPropertyPage // get info about the object virtual __int64 GetModificationNumber (CObject * pItem) const; // get modification number virtual CString GetScriptName (CObject * pItem) const; // get script subroutine name - virtual CString GetLabel (CObject * pItem) const; // get label name + virtual CString GetLabel (CObject * pItem) const; // get label name + virtual CString GetGroup (CObject * pItem) const; // get item group + virtual CString GetDescription (CObject * pItem) const; // get item description for tree control + virtual int GetSequence (CObject * pItem) const; // get item sequence for sorting + virtual CString GetFindText (CObject * pItem) const; // get text for searching on // list management - add the item to the list control virtual int AddItem (CObject * pItem, // add one item to the list control @@ -1513,6 +1525,10 @@ class CPrefsP18 : public CGenPropertyPage virtual __int64 GetModificationNumber (CObject * pItem) const; // get modification number virtual CString GetScriptName (CObject * pItem) const; // get script subroutine name virtual CString GetLabel (CObject * pItem) const; // get label name + virtual CString GetGroup (CObject * pItem) const { return ""; }; // get item group + virtual CString GetDescription (CObject * pItem) const { return ""; }; // get item description for tree control + virtual int GetSequence (CObject * pItem) const { return 0; }; // get item sequence for sorting + virtual CString GetFindText (CObject * pItem) const { return ""; }; // get text for searching on // list management - add the item to the list control virtual int AddItem (CObject * pItem, // add one item to the list control