// BranchListCtrl.cpp : implementation file // #include "stdafx.h" #include "p4win.h" #include "BranchListCtrl.h" #include "MainFrm.h" #include "P4SpecDlg.h" #include "ImageList.h" #include "FilterByOwnerDlg.h" #include "Cmd_Delete.h" #include "Cmd_Describe.h" #include "Cmd_EditSpec.h" #include "Cmd_Branches.h" #include "Cmd_Integrate.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif static LPCTSTR sRegKey_ColumnNames = _T("Branch List"); enum BranchSubItem { BRANCH_NAME, BRANCH_OWNER, BRANCH_OPTIONS, BRANCH_UPDATEDATE, BRANCH_DESC, BRANCH_MAXCOL }; ///////////////////////////////////////////////////////////////////////////// // CBranchListCtrl IMPLEMENT_DYNCREATE(CBranchListCtrl, CP4ListCtrl) BEGIN_MESSAGE_MAP(CBranchListCtrl, CP4ListCtrl) ON_COMMAND(ID_BRANCH_DELETE, OnBranchDelete) ON_UPDATE_COMMAND_UI(ID_BRANCH_DELETE, OnUpdateBranchDelete) ON_COMMAND(ID_BRANCH_EDITSPEC, OnBranchEditspec) ON_UPDATE_COMMAND_UI(ID_BRANCH_EDITSPEC, OnUpdateBranchEditspec) ON_COMMAND(ID_BRANCH_NEW, OnBranchNew) ON_UPDATE_COMMAND_UI(ID_BRANCH_NEW, OnUpdateBranchNew) ON_UPDATE_COMMAND_UI(ID_VIEW_UPDATE_RIGHT, OnUpdateViewUpdate) ON_WM_CONTEXTMENU() ON_COMMAND(ID_BRANCH_INTEG, OnBranchInteg) ON_UPDATE_COMMAND_UI(ID_BRANCH_INTEG, OnUpdateBranchInteg) ON_UPDATE_COMMAND_UI(ID_BRANCH_DESCRIBE, OnUpdateBranchDescribe) ON_COMMAND(ID_BRANCH_DESCRIBE, OnDescribe) ON_UPDATE_COMMAND_UI(ID_FILTERBRANCHBYOWNER, OnUpdateFilterByOwner) ON_COMMAND(ID_FILTERBRANCHBYOWNER, OnFilterByOwner) ON_UPDATE_COMMAND_UI(ID_CLEARBRANCHOWNERFILTER, OnUpdateClearFilterByOwner) ON_COMMAND(ID_CLEARBRANCHOWNERFILTER, OnClearFilterByOwner) ON_COMMAND(ID_VIEW_UPDATE_RIGHT, OnViewUpdate) ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, OnColumnclick) ON_NOTIFY_REFLECT(LVN_DELETEITEM, OnDeleteitem) ON_NOTIFY_REFLECT(LVN_ITEMCHANGED, OnItemchanged) ON_WM_LBUTTONDBLCLK() ON_MESSAGE(WM_P4BRANCHES, OnP4BranchList ) ON_MESSAGE(WM_P4EDITSPEC, OnP4BranchSpec ) ON_MESSAGE(WM_P4ENDSPECEDIT, OnP4EndSpecEdit ) ON_MESSAGE(WM_P4DELETE, OnP4Delete ) ON_MESSAGE(WM_P4DESCRIBE, OnP4Describe ) ON_MESSAGE(WM_P4ENDDESCRIBE, OnP4EndDescribe ) ON_MESSAGE(WM_REQUESTBRANCHLIST, OnRequestBranchesList ) ON_MESSAGE(WM_NEWUSER, NewUser ) ON_WM_CREATE() ON_WM_ACTIVATE() END_MESSAGE_MAP() CBranchListCtrl::CBranchListCtrl() { m_SortAscending=TRUE; m_LastSortCol=0; m_pNewSpec = NULL; m_viewType = P4BRANCH_SPEC; m_Need2DoNew = FALSE; m_caption = m_captionplain = LoadStringResource(IDS_PERFORCE_BRANCHES); } CBranchListCtrl::~CBranchListCtrl() { } ///////////////////////////////////////////////////////////////////////////// // CBranchListCtrl diagnostics #ifdef _DEBUG void CBranchListCtrl::AssertValid() const { CP4ListCtrl::AssertValid(); } void CBranchListCtrl::Dump(CDumpContext& dc) const { CP4ListCtrl::Dump(dc); } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CBranchListCtrl message handlers void CBranchListCtrl::OnLButtonDblClk(UINT nFlags, CPoint point) { int index = GetHitItem ( point ); if( index > -1 ) { SetItemState( index, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED ); OnDescribe(); } else CP4ListCtrl::OnLButtonDblClk(nFlags, point); } LRESULT CBranchListCtrl::NewUser(WPARAM wParam, LPARAM lParam) { if (GET_P4REGPTR()->GetBranchFilteredFlags() & 0x10) Clear(); return 0; } void CBranchListCtrl::Clear() { m_Active=GetSelectedItemText(); if (!m_Active.IsEmpty()) GET_P4REGPTR()->SetLastBranch(m_Active); SetRedraw(FALSE); DeleteAllItems(); SetRedraw(TRUE); m_pNotifyWnd= NULL; CP4ListCtrl::Clear(); } void CBranchListCtrl::OnDeleteitem(NMHDR* pNMHDR, LRESULT* pResult) { NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; delete (CP4Branch *) GetItemData(pNMListView->iItem); *pResult = 0; } void CBranchListCtrl::OnItemchanged(NMHDR* pNMHDR, LRESULT* pResult) { // NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; CString str=GetSelectedItemText(); if (!str.IsEmpty()) GET_P4REGPTR()->SetLastBranch(m_Active = str); *pResult = 0; } void CBranchListCtrl::OnUpdateBranchDelete(CCmdUI* pCmdUI) { pCmdUI->Enable( OnUpdateShowMenuItem( pCmdUI, IDS_DELETE_s ) && !MainFrame()->IsModlessUp() && !SelectedItemIsLocked(BRANCH_OPTIONS) ); } void CBranchListCtrl::OnBranchDelete() { OnDelete( P4BRANCH_DEL ) ; } void CBranchListCtrl::OnUpdateBranchEditspec(CCmdUI* pCmdUI) { pCmdUI->Enable( OnUpdateShowMenuItem( pCmdUI, IDS_EDITSPEC_s ) && !MainFrame()->IsModlessUp() && !m_EditInProgress && (!SelectedItemIsLocked(BRANCH_OPTIONS) || !GetSelectedItemOwner(BRANCH_OWNER).CompareNoCase(GET_P4REGPTR()->GetP4User())) ); } void CBranchListCtrl::EditTheSpec(CString *name) { m_Active=*name; m_NewBranch=FALSE; OnEditSpec( m_Active ); } void CBranchListCtrl::OnBranchEditspec() { m_Active=GetSelectedItemText(); m_NewBranch=FALSE; OnEditSpec( m_Active ); } void CBranchListCtrl::OnUpdateBranchNew(CCmdUI* pCmdUI) { pCmdUI->SetText ( LoadStringResource( IDS_NEW ) ); pCmdUI->Enable(!SERVER_BUSY() && ! m_EditInProgress && !MainFrame()->IsModlessUp()); m_Need2DoNew = FALSE; } void CBranchListCtrl::OnBranchNew() { MainFrame()->ViewBranches(); if (SERVER_BUSY()) m_Need2DoNew = TRUE; else { m_Need2DoNew = FALSE; m_Active.Empty(); m_NewBranch=TRUE; //FIXTHIS: string OnEditSpec( CString(NEWSPECNAME) ); } } void CBranchListCtrl::OnBranchInteg() { GET_P4REGPTR()->SetLastBranch(m_Active=GetSelectedItemText()); // Ask the depot window to perform the integrate task, including // the fetching of change numbers, branch names, popping the dlg, // and getting results displayed ::SendMessage(m_depotWnd, WM_BRANCHINTEG, (WPARAM) LPCTSTR(m_Active), 0); } void CBranchListCtrl::OnUpdateBranchInteg(CCmdUI* pCmdUI) { CString prompt; prompt.FormatMessage(IDS_INTEGRATEUSING_s, TruncateString(GetSelectedItemText(),50)); pCmdUI->SetText( prompt ); pCmdUI->Enable( !SERVER_BUSY() && GetItemCount() && !GetSelectedItemText().IsEmpty( ) && !MainFrame()->IsModlessUp() && !MainFrame()->IsPendChgEditInProgress() ); } void CBranchListCtrl::OnUpdateBranchDescribe(CCmdUI* pCmdUI) { pCmdUI->Enable( OnUpdateShowMenuItem( pCmdUI, IDS_DESCRIBEIT_s ) ); } void CBranchListCtrl::OnUpdateViewUpdate(CCmdUI* pCmdUI) { pCmdUI->Enable(!SERVER_BUSY() && !MainFrame()->IsModlessUp()); } void CBranchListCtrl::OnViewUpdate() { m_Active = GetSelectedItemText(); SetCaption(); CCmd_Branches *pCmd= new CCmd_Branches; pCmd->Init( m_hWnd, RUN_ASYNC); if( pCmd->Run( ) ) { MainFrame()->UpdateStatus( LoadStringResource(IDS_REQUESTING_BRANCH_LISTING) ); MainFrame()->SetBranchUpdateTime(GetTickCount()); Clear(); CP4ListCtrl::OnViewUpdate(); } else delete pCmd; } CString CBranchListCtrl::SetCaption() { int i = GET_P4REGPTR()->GetBranchFilteredFlags(); if (i) { CString filter; CString txt; if (i & 0x10) txt = LoadStringResource(IDS_CURRENT_USER); else if (i & 0x01) txt = GET_P4REGPTR()->GetBranchFilterOwner(); filter.FormatMessage(IDS_FILTERED, txt); m_caption = LoadStringResource(IDS_PERFORCE_BRANCHES) + filter; } else m_caption = LoadStringResource(IDS_PERFORCE_BRANCHES); CP4PaneContent::GetView()->SetCaption(); return m_caption; } void CBranchListCtrl::OnContextMenu(CWnd* pWnd, CPoint point) { // make sure window is active // GetParentFrame()->ActivateFrame(); /////////////////////////////// // See ContextMenuRules.txt for order of menu commands! // create an empty context menu // CP4Menu popMenu; popMenu.CreatePopupMenu(); int index; SetIndexAndPoint( index, point ); popMenu.AppendMenu(MF_ENABLED | MF_STRING, ID_BRANCH_NEW ); if( index != -1 ) { // Make sure the item gets selected SetItemState( index, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED ); // Then add menu commands that are relevant popMenu.AppendMenu(MF_ENABLED | MF_STRING, ID_BRANCH_EDITSPEC ); popMenu.AppendMenu(MF_ENABLED | MF_STRING, ID_BRANCH_DESCRIBE ); popMenu.AppendMenu(MF_ENABLED | MF_STRING, ID_BRANCH_DELETE ); popMenu.AppendMenu( MF_SEPARATOR ); popMenu.AppendMenu(MF_ENABLED | MF_STRING, ID_BRANCH_INTEG ); } popMenu.AppendMenu( MF_SEPARATOR ); popMenu.AppendMenu( MF_ENABLED | MF_STRING, ID_FILTERBRANCHBYOWNER, LoadStringResource(IDS_FILTERBRANCHBYOWNER) ); popMenu.AppendMenu( MF_ENABLED | MF_STRING, ID_CLEARBRANCHOWNERFILTER, LoadStringResource(IDS_CLEARBRANCHOWNERFILTER) ); popMenu.AppendMenu( MF_SEPARATOR ); popMenu.AppendMenu(MF_ENABLED | MF_STRING, ID_VIEW_UPDATE, LoadStringResource(IDS_REFRESH) ); MainFrame()->AddToolsToContextMenu(&popMenu); popMenu.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, AfxGetMainWnd()); } void CBranchListCtrl::InsertBranch(CP4Branch *branch, int index) { LV_ITEM lvItem; int iActualItem = 0; CString txt; m_iImage = CP4ViewImageList::VI_BRANCH; ASSERT(branch != NULL); BOOL bFilteredOut = MainFrame()->IsBranchFilteredOut(branch); for(int subItem=0; subItem < BRANCH_MAXCOL; subItem++) { lvItem.mask=LVIF_TEXT | ((subItem==0) ? LVIF_IMAGE : 0) | ((subItem==0) ? LVIF_PARAM : 0); lvItem.iItem= (subItem==0) ? index : iActualItem; ASSERT(lvItem.iItem != -1 || bFilteredOut); lvItem.iSubItem= subItem; lvItem.iImage = CP4ViewImageList::VI_BRANCH; lvItem.lParam=(LPARAM) branch; switch(subItem) { case BRANCH_NAME: lvItem.pszText= const_cast((LPCTSTR) branch->GetBranchName()); break; case BRANCH_OWNER: lvItem.pszText = const_cast( (LPCTSTR) branch->GetOwner()); break; case BRANCH_OPTIONS: lvItem.pszText = const_cast( (LPCTSTR) branch->GetOptions()); break; case BRANCH_UPDATEDATE: lvItem.pszText= const_cast((LPCTSTR) branch->GetDate()); break; case BRANCH_DESC: txt= PadCRs(branch->GetDescription()); lvItem.pszText = const_cast( (LPCTSTR) txt); break; default: ASSERT( 0 ); lvItem.pszText = _T("@"); break; } m_ListAll.column[subItem].SetAtGrow(index, lvItem.pszText); if (bFilteredOut) continue; if(subItem==0) iActualItem=InsertItem(&lvItem); else SetItem(&lvItem); } if (bFilteredOut) delete branch; } void CBranchListCtrl::UpdateBranch(CP4Branch *branch, int index) { // After a spec edit, update the appropriate list item // First, switch the branch data CP4Branch *oldBranch= (CP4Branch *) GetItemData(index); delete oldBranch; SetItemData(index, (LPARAM) branch); // Then update the text SetItemText(index, BRANCH_NAME, const_cast((LPCTSTR) branch->GetBranchName())); SetItemText(index, BRANCH_OWNER, const_cast((LPCTSTR) branch->GetOwner())); SetItemText(index, BRANCH_OPTIONS, const_cast((LPCTSTR) branch->GetOptions())); SetItemText(index, BRANCH_UPDATEDATE, const_cast((LPCTSTR) branch->GetDate())); CString txt= PadCRs(branch->GetDescription()); SetItemText(index, BRANCH_DESC, const_cast((LPCTSTR)txt)); } void CBranchListCtrl::UpdateBranchAll(CP4Branch *branch, int index) { m_ListAll.column[BRANCH_NAME].SetAt(index, const_cast((LPCTSTR)branch->GetBranchName())); m_ListAll.column[BRANCH_OWNER].SetAt(index, const_cast((LPCTSTR)branch->GetOwner())); m_ListAll.column[BRANCH_OPTIONS].SetAt(index, const_cast((LPCTSTR)branch->GetOptions())); m_ListAll.column[BRANCH_UPDATEDATE].SetAt(index, const_cast((LPCTSTR)branch->GetDate())); CString txt= PadCRs(branch->GetDescription()); m_ListAll.column[BRANCH_DESC].SetAt(index, const_cast((LPCTSTR)txt)); } /////////////////////////////////////////////////// // Support for request of branches list, including delayed notification to // requesting window // Return a list of branches if this window is up-to-date and lParam == 0, // otherwise start a refresh of the branches list, and save the pointer of // the window to be notified when the list is ready LRESULT CBranchListCtrl::OnRequestBranchesList(WPARAM wParam, LPARAM lParam) { CWnd *pWnd= (CWnd *) wParam; ASSERT_KINDOF(CWnd, pWnd); // Clear the branches list for( int index= m_BranchesList.GetUpperBound(); index >= 0; index-- ) delete m_BranchesList.GetAt( index ); m_BranchesList.RemoveAll(); if((m_UpdateState != LIST_UPDATED) || lParam) { // Note: OnViewUpdate() calls Clear(), which resets m_pNotifyWnd to NULL, // so be sure to run OnViewUpdate() BEFORE setting the notify wnd OnViewUpdate(); m_pNotifyWnd= pWnd; } else { FillBranchesList(); m_pNotifyWnd= NULL; } // Return the branches list, even if it is still empty return (LRESULT) &m_BranchesList; } void CBranchListCtrl::FillBranchesList() { ASSERT(m_BranchesList.GetSize() == 0); // Rummage through the list, adding branch names to stringlist for(int index=0; index < GetItemCount(); index++) { CP4Branch *branch= (CP4Branch *) GetItemData(index); CP4Branch *newBranch= new CP4Branch; newBranch->Create( branch->GetBranchName(), branch->GetOwner(), branch->GetOptions(), branch->GetDate(), branch->GetDescription() ); m_BranchesList.Add( newBranch ); } if (!m_Active.IsEmpty()) GET_P4REGPTR()->SetLastBranch(m_Active); } void CBranchListCtrl::NotifyNewBranchesList() { ASSERT(m_pNotifyWnd != NULL); FillBranchesList(); try { if(m_pNotifyWnd != NULL && IsWindow(m_pNotifyWnd->m_hWnd)) { m_pNotifyWnd->SendMessage(WM_NEWBRANCHESLIST, (WPARAM) &m_BranchesList, 0); } } catch(...) { ASSERT(0); // It is possible that the window and/or the CWnd object which // we were supposed to notify is no longer in existence, so this // is an error condition that we can sweep under the rug } } /////////////////////////////////////////////////// // Messages posted by server thread LRESULT CBranchListCtrl::OnP4BranchSpec(WPARAM wParam, LPARAM lParam) { CCmd_EditSpec *pCmd= (CCmd_EditSpec *) wParam; pCmd->SetIsRequestingNew(m_NewBranch); pCmd->SetCaller(DYNAMIC_DOWNCAST(CView, GetParent())); if(!pCmd->GetError() && !m_EditInProgress && pCmd->DoSpecDlg(this)) { m_EditInProgress = TRUE; m_EditInProgressWnd = pCmd->GetSpecSheet(); } else { if ( m_pNewSpec ) delete m_pNewSpec; if (pCmd->HaveServerLock()) pCmd->ReleaseServerLock(); delete pCmd; } MainFrame()->ClearStatus(); return 0; } LRESULT CBranchListCtrl::OnP4EndSpecEdit( WPARAM wParam, LPARAM lParam ) { BOOL need2Refresh = FALSE; CCmd_EditSpec *pCmd= (CCmd_EditSpec *) wParam; if (lParam != IDCANCEL && lParam != IDABORT) { if (m_UpdateState == LIST_UPDATED) { // we have to set 'index' again in case branch's name got changed int index= FindInList(m_pNewSpec->GetBranchName()); int ixAll= FindInListAll(m_pNewSpec->GetBranchName()); if (ixAll == -1) // not in either list { ASSERT(index == -1); InsertBranch(m_pNewSpec, GetItemCount()); ReSort(); index= FindInList(m_pNewSpec->GetBranchName()); if (index == -1) index= FindInList(m_Active); } else if (index > -1) // in both lists { ASSERT(ixAll > -1); if (MainFrame()->IsBranchFilteredOut(m_pNewSpec)) // should it no longer be shown? { need2Refresh = TRUE; delete m_pNewSpec; } else { UpdateBranch(m_pNewSpec, index); UpdateBranchAll(m_pNewSpec, ixAll); } } else // not in visible list; is in list of all { if (MainFrame()->IsBranchFilteredOut(m_pNewSpec)) // should it now be shown? need2Refresh = TRUE; else UpdateBranchAll(m_pNewSpec, ixAll); delete m_pNewSpec; index= FindInList(m_Active); } EnsureVisible( index, TRUE ); SetItemState( index, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED ); } else if ( m_pNewSpec ) delete m_pNewSpec; } else if ( m_pNewSpec ) delete m_pNewSpec; if (lParam != IDABORT) { MainFrame()->ClearStatus(); if (pCmd->HaveServerLock()) pCmd->ReleaseServerLock(); CDialog *dlg = (CDialog *)pCmd->GetSpecSheet(); dlg->DestroyWindow(); } delete pCmd; m_EditInProgress = FALSE; if (need2Refresh) OnViewUpdate(); return 0; } LRESULT CBranchListCtrl::OnP4BranchList(WPARAM wParam, LPARAM lParam) { CCmd_Branches *pCmd= (CCmd_Branches *) wParam; ASSERT_KINDOF(CCmd_Branches,pCmd); if(!pCmd->GetError()) { CObList *branches= pCmd->GetList(); SetRedraw(FALSE); int index = 0; for(POSITION pos= branches->GetHeadPosition(); pos != NULL; index++) { CP4Branch *branch=(CP4Branch *) branches->GetNext(pos); ASSERT_KINDOF(CP4Branch,branch); InsertBranch(branch, index); } SetRedraw(TRUE); CString msg; msg.FormatMessage( IDS_NUMBER_OF_BRANCHES_n, index ); AddToStatus( msg, SV_COMPLETION ); ReSort(); // Make sure previous item is re-selected if(branches->GetCount() > 0) { int i = FindInList(m_Active.IsEmpty() ? GET_P4REGPTR()->GetLastBranch() : m_Active); if (i < 0) i=0; SetItemState(i, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED); EnsureVisible(i, FALSE); m_Active=GetSelectedItemText(); } // If another window was waiting for a list of branches, send it the list if(m_pNotifyWnd != NULL) NotifyNewBranchesList(); CP4ListCtrl::SetUpdateDone(); if (m_Need2DoNew) OnBranchNew(); else { // Notify the mainframe that we have finished getting the branches, // hence the entire set of async command have finished. MainFrame()->ExpandDepotIfNeedBe(); } if (m_PostViewUpdateMsg) PostMessage(m_PostViewUpdateMsg, m_PostViewUpdateWParam, m_PostViewUpdateLParam); } else { CP4ListCtrl::SetUpdateFailed(); m_Need2DoNew = FALSE; } delete pCmd; m_PostViewUpdateMsg = 0; MainFrame()->ClearStatus(); return 0; } ////////////////////////////////////////////////////////////////////////// // Sort callback, not in class int CBranchListCtrl::OnCompareItems(LPARAM lParam1, LPARAM lParam2, int subItem) { ASSERT(lParam1 && lParam2); CP4Branch const *branch1 = (CP4Branch const*)lParam1; CP4Branch const *branch2 = (CP4Branch const*)lParam2; ASSERT_KINDOF(CP4Branch,branch1); ASSERT_KINDOF(CP4Branch,branch2); CString txt1, txt2; switch(subItem) { case BRANCH_NAME: // branch name txt1= branch1->GetBranchName(); txt2= branch2->GetBranchName(); break; case BRANCH_OWNER: // branch owner txt1= branch1->GetOwner(); txt2= branch2->GetOwner(); break; case BRANCH_OPTIONS: // branch options txt1= branch1->GetOptions(); txt2= branch2->GetOptions(); break; case BRANCH_UPDATEDATE: // branch update date txt1= branch1->GetDate(); txt2= branch2->GetDate(); ConvertDates( txt1, txt2 ); break; case BRANCH_DESC: // branch root txt1= branch1->GetDescription(); txt2= branch2->GetDescription(); break; default: ASSERT(0); return 0; } txt1.MakeUpper(); txt2.MakeUpper(); int rc; if(m_SortAscending) rc = txt1.Compare(txt2); else rc = txt2.Compare(txt1); return rc; } void CBranchListCtrl::OnEditSpec( LPCTSTR sItem ) { if (m_EditInProgress) { CantEditRightNow(IDS_BRANCH); return; } m_pNewSpec = new CP4Branch; CCmd_EditSpec *pCmd= new CCmd_EditSpec; pCmd->Init( m_hWnd, RUN_ASYNC, TRUE ); if( pCmd->Run( P4BRANCH_SPEC, sItem, m_pNewSpec ) ) MainFrame()->UpdateStatus( LoadStringResource(IDS_EDITING_BRANCH_SPEC) ) ; else { delete pCmd; delete m_pNewSpec; } } int CBranchListCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CP4ListCtrl::OnCreate(lpCreateStruct) == -1) return -1; CStringArray colnames; colnames.Add ( LoadStringResource(IDS_BRANCH) ); colnames.Add ( LoadStringResource(IDS_OWNER) ); colnames.Add ( LoadStringResource(IDS_LOCKSTR) ); colnames.Add ( LoadStringResource(IDS_DATE) ); colnames.Add ( LoadStringResource(IDS_DESCRIPTION) ); ASSERT( BRANCH_MAXCOL == colnames.GetSize( ) ); //FIXTHIS: move default widths into resource int width[BRANCH_MAXCOL]={90,90,60,90,250}; RestoreSavedWidths(width, colnames.GetSize( ), sRegKey_ColumnNames); if (width[BRANCH_UPDATEDATE] > 5000 && width[BRANCH_DESC] > 5000) width[BRANCH_OPTIONS] = width[BRANCH_UPDATEDATE] = width[BRANCH_DESC] = 90; InsertColumnHeaders( colnames, width ); return 0; } void CBranchListCtrl::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized) { CP4ListCtrl::OnActivate(nState, pWndOther, bMinimized); if(nState != WA_INACTIVE && m_Active.IsEmpty() && GetItemCount() > 1) { int i = FindInList(GET_P4REGPTR()->GetLastBranch()); if (i < 0) i=0; SetItemState(i, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED); EnsureVisible(i, FALSE); m_Active=GetSelectedItemText(); } else { m_Active=GetSelectedItemText(); if (!m_Active.IsEmpty()) GET_P4REGPTR()->SetLastBranch(m_Active); } } void CBranchListCtrl::OnUpdateFilterByOwner(CCmdUI* pCmdUI) { pCmdUI->Enable( MainFrame()->SetMenuIcon(pCmdUI, !SERVER_BUSY()) ); } void CBranchListCtrl::OnFilterByOwner() { CFilterByOwnerDlg dlg; dlg.m_NotUser = GET_P4REGPTR()->GetBranchFilteredFlags() & 0x01; dlg.m_Owner = GET_P4REGPTR()->GetBranchFilterOwner(); dlg.m_bShowIncBlanks = FALSE; if (dlg.DoModal() == IDOK) { GET_P4REGPTR()->SetBranchFilteredFlags(dlg.m_NotUser ? 0x01 : 0x10); GET_P4REGPTR()->SetBranchFilterOwner(dlg.m_Owner); OnViewUpdate(); } } void CBranchListCtrl::OnUpdateClearFilterByOwner(CCmdUI* pCmdUI) { pCmdUI->Enable( MainFrame()->SetMenuIcon(pCmdUI, GET_P4REGPTR()->GetBranchFilteredFlags() && !SERVER_BUSY()) ); } void CBranchListCtrl::OnClearFilterByOwner() { GET_P4REGPTR()->SetBranchFilteredFlags(0); OnViewUpdate(); }