/*========================================================================= * * EDTSubm.cpp : popup menu * * * Version 1.0 * Creation date * Revision date * * FBF *=======================================================================*/ #include "stdafx.h" #include "acp_base.h" #include "itf/customid.h" #ifdef ACTIVE_EDITOR #include "itf/CPAsubm.hpp" #include "itf/CPADLLb.hpp" /////////////////////////////////////////////////////////////////////////////// // MACROS /////////////////////////////////////////////////////////////////////////////// #define M_Entry(p_oElement) ( (EDT_SubMenuEntry*) p_oElement ) #define M_Menu(p_oElement) ( (EDT_SubMenu*) p_oElement ) //----------------------------------------------------------------------------------- //----------------------------------------------------------------------------------- // class EDT_SubMenuEntry //----------------------------------------------------------------------------------- //----------------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // Description : constructor // ---------------------------------------------------------------------------- EDT_SubMenuEntry::EDT_SubMenuEntry(CPA_EditorBase *pOwner, char *p_cText, UINT uiMsgID, UINT uiIntID, BOOL _bCheck /*=FALSE*/, BOOL _bEnable /*=TRUE*/) :EDT_SubMenuElement(C_SMEEntry) { ASSERT( p_cText ); m_p_cText = (char*)malloc(strlen(p_cText)+1); strcpy(m_p_cText, p_cText); m_pOwner = pOwner; m_IDCmdMsg = uiMsgID; m_uiID = uiIntID; m_bChecked = _bCheck; m_bEnabled = _bEnable; } // ---------------------------------------------------------------------------- // Description : destructor // ---------------------------------------------------------------------------- EDT_SubMenuEntry::~EDT_SubMenuEntry() { if(m_p_cText) free(m_p_cText); } // ---------------------------------------------------------------------------- // Description : call handle function // ---------------------------------------------------------------------------- UINT EDT_SubMenuEntry::SendCommand(EDT_SubMenu *_p_oSubMenu) { if (m_pOwner) m_pOwner->_OnSubMenuCommand(_p_oSubMenu,m_IDCmdMsg); return NULL; } //----------------------------------------------------------------------------------- //----------------------------------------------------------------------------------- // class EDT_SubMenu //----------------------------------------------------------------------------------- //----------------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // Description : constructor // ---------------------------------------------------------------------------- EDT_SubMenu::EDT_SubMenu(tde_SubMenu _eSubMenu,UINT _uiIDStart /*=C_CustomIDUserEnd*/) :EDT_SubMenuElement(C_SMEMenu) { m_eSubMenu = _eSubMenu; m_uiInternalID = m_uiInternalIDStart = _uiIDStart; m_bHasFather = FALSE; m_p_oFather = NULL; m_szName = NULL; RemoveAll(); } // ---------------------------------------------------------------------------- // Description : destructor // ---------------------------------------------------------------------------- EDT_SubMenu::~EDT_SubMenu() { Clear(); if(m_szName) free(m_szName); } // ---------------------------------------------------------------------------- // Description : clear SubMenu content // ---------------------------------------------------------------------------- void EDT_SubMenu::Clear() { POSITION stPos = GetHeadPosition(); while(stPos) { EDT_SubMenuElement *p_oElement = GetNext( stPos ); if( p_oElement -> mfn_eGetElementType() == C_SMEMenu ) { // p_oElement is a SubMenu M_Menu(p_oElement) -> Clear(); } delete p_oElement; } RemoveAll(); m_uiInternalID = m_uiInternalIDStart; } // ---------------------------------------------------------------------------- // Description : return SubMenuType // ---------------------------------------------------------------------------- tde_SubMenu EDT_SubMenu::GetSubMenuType() { return m_eSubMenu; } // ---------------------------------------------------------------------------- // Description : set father of SubMenu // ---------------------------------------------------------------------------- void EDT_SubMenu::fn_vSetFather(EDT_SubMenu *_p_oFather) { ASSERT( _p_oFather ); m_bHasFather = TRUE; m_p_oFather = _p_oFather; } // ---------------------------------------------------------------------------- // Description : set SubMenu name // ---------------------------------------------------------------------------- void EDT_SubMenu::fn_vSetName(char *_szName) { ASSERT( _szName ); m_szName = (char*)malloc(strlen(_szName)+1); strcpy(m_szName, _szName); } // ---------------------------------------------------------------------------- // Description : return next internal ID // ---------------------------------------------------------------------------- UINT EDT_SubMenu::mfn_vGetNextInternalID() { if( m_bHasFather ) return m_p_oFather -> mfn_vGetNextInternalID(); else return m_uiInternalID++; } // ---------------------------------------------------------------------------- // Description : build SubMenu // ---------------------------------------------------------------------------- void EDT_SubMenu::Build(CMenu *pPopupMenu /*=NULL*/) { if(pPopupMenu) { EDT_SubMenuElement *p_oElement; CMenu *p_oMenu; UINT uiFlags; // delete SubMenu DeleteEntirePopupMenu(pPopupMenu); // if last entry is a separator, remove it if (!IsEmpty()) { // check last element p_oElement = GetTail(); if (p_oElement->mfn_eGetElementType() == C_SMESeparator) RemoveTail(); } // add all entries POSITION stPos = GetHeadPosition(); while(stPos) { p_oElement = GetNext(stPos); // add entry switch ( p_oElement -> mfn_eGetElementType() ) { case C_SMESeparator: // add a separator pPopupMenu -> AppendMenu(MF_SEPARATOR); break; case C_SMEEntry: // add an item uiFlags = MF_STRING | (M_Entry(p_oElement)->GetCheck() ? MF_CHECKED : MF_UNCHECKED ) | (M_Entry(p_oElement)->GetEnable() ? MF_ENABLED : MF_GRAYED ); pPopupMenu -> AppendMenu(uiFlags, M_Entry(p_oElement)->GetInternalID(), M_Entry(p_oElement)->GetText()); break; case C_SMEMenu: // add a SubMenu // create SubMenu p_oMenu = new CMenu(); p_oMenu -> CreatePopupMenu(); // fill it M_Menu(p_oElement) -> Build( p_oMenu ); // add to current SubMenu pPopupMenu -> AppendMenu ( MF_STRING|MF_POPUP|MF_ENABLED , (UINT)p_oMenu -> Detach() , M_Menu(p_oElement) -> m_szName ) ; delete p_oMenu; break; } } } } // ---------------------------------------------------------------------------- // Description : delete CMenu content // ---------------------------------------------------------------------------- void EDT_SubMenu::DeleteEntirePopupMenu(CMenu* pPopupMenu) { while(pPopupMenu->GetMenuItemCount() > 0) { UINT uiState = pPopupMenu->GetMenuState(0,MF_BYPOSITION); if(HIWORD(uiState) != 0) { // first item is a SubMenu DeleteEntirePopupMenu(pPopupMenu->GetSubMenu(0)); } pPopupMenu->DeleteMenu(0,MF_BYPOSITION); } } // ---------------------------------------------------------------------------- // Description : get a new SubMenu (must uses it as sub menu of 'this') // ---------------------------------------------------------------------------- EDT_SubMenu *EDT_SubMenu::fn_p_oGetNewSubMenu(char *_szName, tde_SubMenu _eMenuType /*=C_SubSubMenu*/) { ASSERT( _szName ); EDT_SubMenu *p_oResult = new EDT_SubMenu( _eMenuType == C_SubSubMenu ? GetSubMenuType() : _eMenuType ); p_oResult -> fn_vSetName( _szName ); p_oResult -> fn_vSetFather( this ); return p_oResult; } // ---------------------------------------------------------------------------- // Description : add a separator // ---------------------------------------------------------------------------- void EDT_SubMenu::AddASeparator() { AddTail(new EDT_SubMenuSeparator()); } // ---------------------------------------------------------------------------- // Description : add an entry from DLL // ---------------------------------------------------------------------------- void EDT_SubMenu::AddAnEntry(CPA_EditorBase *p_oOwner, char *p_cText, UINT uiEntryID, BOOL _bCheck /*=FALSE*/, BOOL _bEnable /*=TRUE*/) { AddTail(new EDT_SubMenuEntry(p_oOwner, p_cText, uiEntryID, mfn_vGetNextInternalID(), _bCheck, _bEnable)); } // ---------------------------------------------------------------------------- // Description : add a SubMenu // ---------------------------------------------------------------------------- void EDT_SubMenu::AddASubMenu(EDT_SubMenu *_p_oSubMenu) { ASSERT( _p_oSubMenu ); // SubMenu must be child of current SubMenu ASSERT( _p_oSubMenu -> m_p_oFather == this ); // add SubMenu AddTail( (EDT_SubMenuElement*)_p_oSubMenu ); } // ---------------------------------------------------------------------------- // Description : handle selected item // ---------------------------------------------------------------------------- UINT EDT_SubMenu::_OnCommand(UINT uiInternalID) { POSITION stPos; EDT_SubMenuElement *p_oElement; stPos = GetHeadPosition(); while(stPos) { p_oElement = GetNext(stPos); if( (p_oElement -> mfn_eGetElementType() == C_SMEEntry) && (M_Entry(p_oElement) -> GetInternalID() == uiInternalID) ) { // entry found!, launch command on owner return M_Entry(p_oElement) -> SendCommand(this); } else if( (p_oElement -> mfn_eGetElementType() == C_SMEMenu) ) { // search on submenu UINT uiResult = M_Menu(p_oElement) -> _OnCommand( uiInternalID ); if( uiResult ) // entry found return uiResult; } } return NULL; } // ---------------------------------------------------------------------------- // Description : handle selected item // ---------------------------------------------------------------------------- BOOL EDT_SubMenu::fn_bFindCmdID (UINT uiInternalID, CPA_EditorBase **pOwner, UINT *CmdID) { EDT_SubMenuElement *pElem; POSITION pos; pos = GetHeadPosition(); while(pos) { pElem = GetNext(pos); if ((pElem->mfn_eGetElementType() == C_SMEEntry) && (M_Entry(pElem)->GetInternalID() == uiInternalID)) { // entry found *CmdID = M_Entry(pElem)->GetCmdID(); if (pOwner) *pOwner = M_Entry(pElem)->GetOwner(); return TRUE; } else if ((pElem->mfn_eGetElementType() == C_SMEMenu)) { // search on submenu if (M_Menu(pElem)->fn_bFindCmdID(uiInternalID,pOwner,CmdID)) return TRUE; } } // entry not found return FALSE; } // JMD char EDT_SubMenu::fn_cGrayedItem (CMenu *pPopupMenu, char *szItem) { char cFinish = 0 ; if(pPopupMenu) { EDT_SubMenuElement *p_oElement; int iID ; LPCTSTR szText ; // add all entries POSITION stPos = GetHeadPosition(); while(stPos && !cFinish) { p_oElement = GetNext(stPos); // add entry switch ( p_oElement -> mfn_eGetElementType() ) { case C_SMEEntry: // add an item iID = M_Entry(p_oElement)->GetInternalID(); szText = M_Entry(p_oElement)->GetText(); if ( !stricmp (szItem, szText) ) { pPopupMenu->EnableMenuItem ( iID, MF_GRAYED | MF_BYCOMMAND ) ; cFinish = 1 ; } break; case C_SMEMenu: // add a SubMenu iID = M_Menu(p_oElement)->m_uiInternalID; szText = M_Menu(p_oElement)->m_szName ; if ( !stricmp (szItem, szText) ) { //pPopupMenu->EnableMenuItem ( iID, MF_BYCOMMAND ) ; M_Menu(p_oElement)->fn_vGrayedAllMenuItem( pPopupMenu ); cFinish = 1 ; } else cFinish = M_Menu(p_oElement)->fn_cGrayedItem( pPopupMenu, szItem ); break; } } } return (cFinish) ; } void EDT_SubMenu::fn_vGrayedAllMenuItem ( CMenu *pPopupMenu ){ EDT_SubMenuElement *p_oElement; int iID ; // add all entries POSITION stPos = GetHeadPosition(); while(stPos) { p_oElement = GetNext(stPos); // add entry switch ( p_oElement -> mfn_eGetElementType() ) { case C_SMEEntry: // add an item iID = M_Entry(p_oElement)->GetInternalID(); pPopupMenu->EnableMenuItem ( iID, MF_GRAYED | MF_BYCOMMAND ) ; break; case C_SMEMenu: // add a SubMenu M_Menu(p_oElement)->fn_vGrayedAllMenuItem( pPopupMenu ); break; } } } #endif //ACTIVE_EDITOR