// UserListCtrl.cpp : implementation file // #include "stdafx.h" #include "p4win.h" #include "UserView.h" #include "MainFrm.h" #include "cmd_editspec.h" #include "cmd_describe.h" #include "cmd_delete.h" #include "cmd_users.h" #include "newclientdlg.h" #include "setpwddlg.h" #include "ImageList.h" #include #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif static LPCTSTR sRegValue_UserList = _T("User List"); enum UserSubItem { USER_NAME, USER_EMAIL, USER_FULLNAME, USER_DATEACCESS, USER_MAXCOL }; ///////////////////////////////////////////////////////////////////////////// // CUserListCtrl BEGIN_MESSAGE_MAP(CUserListCtrl, CP4ListCtrl) ON_COMMAND(ID_USER_DELETE, OnUserDelete) ON_UPDATE_COMMAND_UI(ID_USER_DELETE, OnUpdateUserDelete) ON_UPDATE_COMMAND_UI(ID_VIEW_UPDATE_RIGHT, OnUpdateViewUpdate) ON_WM_CONTEXTMENU() ON_UPDATE_COMMAND_UI(ID_USER_DESCRIBE, OnUpdateUserDescribe) ON_WM_LBUTTONDBLCLK() ON_COMMAND(ID_USER_CREATENEWUSER, OnUserCreatenewuser) ON_UPDATE_COMMAND_UI(ID_USER_SWITCHTOUSER, OnUpdateUserSwitchtouser) ON_COMMAND(ID_USER_SWITCHTOUSER, OnUserSwitchtouser) ON_UPDATE_COMMAND_UI(ID_SETDEFUSER, OnUpdateSetDefUser) ON_COMMAND(ID_SETDEFUSER, OnSetDefUser) ON_UPDATE_COMMAND_UI(ID_USER_PASSWORD, OnUpdateUserPassword) ON_WM_CREATE() ON_COMMAND(ID_USER_DESCRIBE, OnDescribe) ON_COMMAND(ID_VIEW_UPDATE_RIGHT, OnViewUpdate) ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, OnColumnclick) ON_NOTIFY_REFLECT(LVN_DELETEITEM, OnDeleteitem) ON_COMMAND(ID_USER_PASSWORD, OnUserPassword) ON_UPDATE_COMMAND_UI(ID_ADD_REVIEWS, OnUpdateAddReviews) ON_COMMAND(ID_ADD_REVIEWS, OnAddReviews) ON_MESSAGE(WM_P4USERS, OnP4UserList ) ON_MESSAGE(WM_P4EDITSPEC, OnP4UserSpec ) ON_MESSAGE(WM_P4ENDSPECEDIT, OnP4EndSpecEdit ) ON_MESSAGE(WM_P4DELETE, OnP4Delete ) ON_MESSAGE(WM_P4DESCRIBE, OnP4Describe ) ON_MESSAGE(WM_P4ENDDESCRIBE, OnP4EndDescribe ) END_MESSAGE_MAP() IMPLEMENT_DYNCREATE(CUserListCtrl, CP4ListCtrl) CUserListCtrl::CUserListCtrl() { m_SortAscending=TRUE; m_viewType = P4USER_SPEC; m_OldDefUser = m_OldCurUser = _T("@"); m_CF_DEPOT = static_cast(RegisterClipboardFormat(LoadStringResource(IDS_DRAGFROMDEPOT))); m_CF_USER = static_cast(RegisterClipboardFormat(LoadStringResource(IDS_DRAGFROMUSER))); m_caption = m_captionplain = LoadStringResource(IDS_PERFORCE_USERS); } CUserListCtrl::~CUserListCtrl() { } ///////////////////////////////////////////////////////////////////////////// // CUserListCtrl diagnostics #ifdef _DEBUG void CUserListCtrl::AssertValid() const { CP4ListCtrl::AssertValid(); } void CUserListCtrl::Dump(CDumpContext& dc) const { CP4ListCtrl::Dump(dc); } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CUserListCtrl message handlers void CUserListCtrl::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); } void CUserListCtrl::Clear() { SetRedraw(FALSE); DeleteAllItems(); SetRedraw(TRUE); CP4ListCtrl::Clear(); } void CUserListCtrl::OnDeleteitem(NMHDR* pNMHDR, LRESULT* pResult) { NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; delete (CP4User *) GetItemData(pNMListView->iItem); *pResult = 0; } /* _________________________________________________________________ everything you need for a delete, the cmd ui, the first part of the delete, that sends a window message to this window, that comes right back and calls the second function for a delete. _________________________________________________________________ */ void CUserListCtrl::OnUpdateUserDelete(CCmdUI* pCmdUI) { pCmdUI->Enable( OnUpdateShowMenuItem( pCmdUI, IDS_DELETE_s ) && GetSelectedItemText() == GET_P4REGPTR()->GetP4User() && !MainFrame()->IsModlessUp() ); } BOOL CUserListCtrl::OKToDelete( ) { if ( GetSelectedItemText() == GET_P4REGPTR()->GetP4User() ) return TRUE; else { AfxMessageBox(IDS_YOU_DO_NOT_HAVE_PERMISSION_TO_DELETE_OTHER_USERS, MB_ICONINFORMATION); return FALSE; } } void CUserListCtrl::OnUserDelete() { OnDelete( P4USER_DEL ); } void CUserListCtrl::EditTheSpec(CString *name) { if ( *name == GET_P4REGPTR( )->GetP4User( ) ) OnUserEditmy(); } void CUserListCtrl::OnUserEditmy() { m_Active = GET_P4REGPTR()->GetP4User(); int index = FindInList(GET_P4REGPTR()->GetP4User()); if(index > -1) { SetItemState(index, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED); EnsureVisible(index, FALSE); } m_olduser= m_Active; OnEditSpec( m_Active ); } void CUserListCtrl::OnUpdateUserDescribe(CCmdUI* pCmdUI) { pCmdUI->Enable( OnUpdateShowMenuItem( pCmdUI, IDS_DESCRIBEIT_s ) && !MainFrame()->IsModlessUp() ); } void CUserListCtrl::OnUserDescribe() { OnDescribe(); } void CUserListCtrl::OnUpdateViewUpdate(CCmdUI* pCmdUI) { pCmdUI->Enable(!SERVER_BUSY() && !MainFrame()->IsModlessUp()); } void CUserListCtrl::OnViewUpdate() { m_Active = GetSelectedItemText(); CCmd_Users *pCmd= new CCmd_Users; pCmd->Init( m_hWnd, RUN_ASYNC); if( pCmd->Run( ) ) { MainFrame()->UpdateStatus( LoadStringResource(IDS_REQUESTING_USER_LISTING) ); MainFrame()->SetUserUpdateTime(GetTickCount()); Clear(); CP4ListCtrl::OnViewUpdate(); } else delete pCmd; } void CUserListCtrl::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.LoadMenu(IDR_USER); int index; SetIndexAndPoint( index, point ); if( index != -1 ) { // Can only edit or delete my user if ( GetSelectedItemText( ) == GET_P4REGPTR( )->GetP4User( ) ) { // can't switch if already there popMenu.GetSubMenu(0)->DeleteMenu(ID_USER_SWITCHTOUSER,MF_BYCOMMAND); } else { // can't edit, delete, set password or set as default if not current popMenu.GetSubMenu(0)->DeleteMenu(ID_USER_EDITMY,MF_BYCOMMAND); popMenu.GetSubMenu(0)->DeleteMenu(ID_USER_DELETE,MF_BYCOMMAND); popMenu.GetSubMenu(0)->DeleteMenu(ID_USER_PASSWORD,MF_BYCOMMAND); popMenu.GetSubMenu(0)->DeleteMenu(ID_SETDEFUSER,MF_BYCOMMAND); } } else { // can't do much if no user selected popMenu.GetSubMenu(0)->DeleteMenu(ID_USER_EDITMY,MF_BYCOMMAND); popMenu.GetSubMenu(0)->DeleteMenu(ID_USER_DESCRIBE,MF_BYCOMMAND); popMenu.GetSubMenu(0)->DeleteMenu(ID_USER_DELETE,MF_BYCOMMAND); popMenu.GetSubMenu(0)->DeleteMenu(ID_USER_SWITCHTOUSER,MF_BYCOMMAND); popMenu.GetSubMenu(0)->DeleteMenu(ID_USER_PASSWORD,MF_BYCOMMAND); popMenu.GetSubMenu(0)->DeleteMenu(ID_SETDEFUSER,MF_BYCOMMAND); // clobber extra separator popMenu.GetSubMenu(0)->DeleteMenu(1,MF_BYPOSITION); } MainFrame()->AddToolsToContextMenu((CP4Menu *)(popMenu.GetSubMenu(0))); popMenu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, AfxGetMainWnd()); } ///////////////////////////////////////////////////////////////////////////// // CUserListCtrl message handlers void CUserListCtrl::InsertUser(CP4User *user, int index) { ASSERT(user != NULL); m_iImage = CP4ViewImageList::VI_USER; LV_ITEM lvItem; int iActualItem = -1; CString curuser = GET_P4REGPTR()->GetP4User(); CString defuser = GET_P4REGPTR()->GetP4User(TRUE); for(int subItem=USER_NAME; subItem < USER_MAXCOL; subItem++) { lvItem.mask=LVIF_TEXT | ((subItem==USER_NAME) ? LVIF_IMAGE : 0) | ((subItem==USER_NAME) ? LVIF_PARAM : 0); lvItem.iItem= (subItem==USER_NAME) ? index : iActualItem; ASSERT(lvItem.iItem != -1); lvItem.iSubItem= subItem; switch(subItem) { case USER_NAME: { lvItem.pszText= const_cast(user->GetUserName()); bool isCurrent = curuser.Compare(lvItem.pszText) == 0; bool isDefault = defuser.Compare(lvItem.pszText) == 0; lvItem.iImage = CP4ViewImageList::GetUserIndex(isCurrent, isDefault); if(isDefault) m_OldDefUser = lvItem.pszText; if(isCurrent) m_OldCurUser = lvItem.pszText; lvItem.lParam=(LPARAM) user; } break; case USER_EMAIL: lvItem.pszText= const_cast(user->GetEmail()); break; case USER_FULLNAME: lvItem.pszText= const_cast(user->GetFullName()); break; case USER_DATEACCESS: lvItem.pszText= const_cast(user->GetLastAccess()); break; } if(subItem==0) iActualItem = InsertItem(&lvItem); else SetItem(&lvItem); } } void CUserListCtrl::UpdateUser(CP4User *user, int index) { // After a spec edit, update the appropriate list item // First, switch the user data CP4User *oldUser= (CP4User *) GetItemData(index); delete oldUser; SetItemData(index, (LPARAM) user); // Then update the text SetItemText(index, USER_NAME, const_cast(user->GetUserName())); SetItemText(index, USER_EMAIL, const_cast(user->GetEmail())); SetItemText(index, USER_FULLNAME, const_cast(user->GetFullName())); SetItemText(index, USER_DATEACCESS, const_cast(user->GetLastAccess())); } // Receives ak for user spec update LRESULT CUserListCtrl::OnP4UserSpec(WPARAM wParam, LPARAM lParam) { CCmd_EditSpec *pCmd= (CCmd_EditSpec *) wParam; BOOL newUser; // Save whether an edit operation refer to a new user pCmd->SetIsRequestingNew(newUser = pCmd->GetIsNewUser()); pCmd->SetCaller(DYNAMIC_DOWNCAST(CView, GetParent())); int i, j; CString specIn(pCmd->GetSpecIn()); if (m_ReviewsList.GetCount() > 0) // We have files to add to the Reviews list { if ((i = specIn.Find(_T("\n\nReviews:\n"))) == -1) { i = specIn.GetLength(); specIn += _T("\n\nReviews:\n"); } else specIn += _T("\t#\n"); // A review that is a single # means // put a blank line in the list here. POSITION pos; for(pos = m_ReviewsList.GetHeadPosition(); pos != NULL; ) { CString filename = m_ReviewsList.GetNext(pos); if ((i = filename.Find(_T(""))) != -1) filename = filename.Left(i-1) + _T("/..."); if (filename.Find(_T(' ')) != -1) filename = _T('\"') + filename + _T('\"'); if (specIn.Find(filename) == -1) specIn += _T('\t') + filename + _T('\n'); } m_ReviewsList.RemoveAll(); // this info is no longer needed pCmd->SetSpecIn(specIn); } m_oldJobView = _T(""); if ((i = specIn.Find(_T("\n\nJobView:\t"))) != -1) { i += lstrlen(_T("\n\nJobView:\n")); if ((j = specIn.Find(_T('\n'),i)) != -1) m_oldJobView = specIn.Mid(i, j-i); } if(!pCmd->GetError() && !m_EditInProgress && pCmd->DoSpecDlg(this)) { m_EditInProgress = TRUE; m_EditInProgressWnd = pCmd->GetSpecSheet(); } else { delete m_pNewSpec; CString txt; txt.FormatMessage(IDS_A_USER_HAS_BEEN_CREATED_DELETE_IT_s, m_Active); if (newUser && (FindInList(m_Active) == -1) && (CString(pCmd->GetErrorText()).Find(_T(" - over license quota")) == -1) && (pCmd->GetError() || (IDYES == AfxMessageBox(txt, MB_YESNO | MB_DEFBUTTON1 | MB_ICONQUESTION)))) { CCmd_Delete *pCmd2 = new CCmd_Delete; pCmd2->Init( NULL, RUN_SYNC, TRUE, pCmd->GetServerKey() ); if (pCmd2->Run( P4USER_DEL, m_Active )) { // nothing to do } else { ::PostMessage(MainFrame()->m_hWnd, WM_COMMAND, ID_VIEW_UPDATE, 0); } delete pCmd2; } else ::PostMessage(MainFrame()->m_hWnd, WM_COMMAND, ID_VIEW_UPDATE, 0); if (GET_P4REGPTR()->GetExpandFlag() == 1) GET_P4REGPTR()->AddMRUPcuPath(MainFrame()->GetCurrentItemPath()); m_Active = m_olduser; GET_P4REGPTR()->SetP4User( m_olduser, TRUE, FALSE, FALSE ); MainFrame()->UpdateCaption( ) ; if (pCmd->HaveServerLock()) pCmd->ReleaseServerLock(); delete pCmd; } MainFrame()->ClearStatus(); return 0; } LRESULT CUserListCtrl::OnP4EndSpecEdit( WPARAM wParam, LPARAM lParam ) { CCmd_EditSpec *pCmd= (CCmd_EditSpec *) wParam; int i, j; if (lParam != IDCANCEL && lParam != IDABORT) { if (m_UpdateState == LIST_UPDATED) { // we have to set 'index' again in case user's name got changed int index = FindInList(m_pNewSpec->GetUserName()); if(index > -1 ) UpdateUser(m_pNewSpec, index); else { InsertUser(m_pNewSpec, GetItemCount()); ReSort(); if( m_Active != m_olduser ) { if (GET_P4REGPTR()->GetExpandFlag() == 1) GET_P4REGPTR()->AddMRUPcuPath(MainFrame()->GetCurrentItemPath()); m_Active = m_olduser; GET_P4REGPTR()->SetP4User( m_olduser, TRUE, FALSE, FALSE ); MainFrame()->UpdateCaption( ) ; } } } else if ( m_pNewSpec ) delete m_pNewSpec; CString specOut(pCmd->GetSpecOut()); if ((i = specOut.Find(_T("\n\nJobView:\t"))) != -1) { i += lstrlen(_T("\n\nJobView:\n")); if ((j = specOut.Find(_T('\n'),i)) != -1) { // if JobView has changed, we have to refresh the changelists (and depot) if (m_oldJobView != specOut.Mid(i, j-i)) MainFrame()->UpdateDepotandChangeViews(TRUE); } } } else if ( m_pNewSpec ) delete m_pNewSpec; if (lParam != IDABORT) { MainFrame()->ClearStatus(); if (pCmd->HaveServerLock()) pCmd->ReleaseServerLock(); CDialog *dlg = (CDialog *)pCmd->GetSpecSheet(); dlg->DestroyWindow(); } if ((lParam == IDCANCEL) && pCmd->GetIsNewUser()) // if canceled, cleanup newly created user { m_Active = pCmd->GetItemName(); CString msg; msg.FormatMessage ( IDS_DELETENEWUSER_s, m_Active ); // ask if they want to delete the newly created user if( AfxMessageBox( msg, MB_YESNO|MB_ICONQUESTION ) == IDYES) { // fire off the delete of the newly created user CCmd_Delete *pCmdDel = new CCmd_Delete; pCmdDel->Init( m_hWnd, RUN_ASYNC ); pCmdDel->SetSwitch2User( m_olduser ); if( pCmdDel->Run( P4USER_DEL, m_Active ) ) MainFrame()->UpdateStatus( LoadStringResource(IDS_DELETING) ); else delete pCmdDel; } else { OnViewUpdate(); } } delete pCmd; m_EditInProgress = FALSE; return 0; } LRESULT CUserListCtrl::OnP4UserList(WPARAM wParam, LPARAM lParam) { CCmd_Users *pCmd= (CCmd_Users *) wParam; if(!pCmd->GetError()) { CObList const *users = pCmd->GetList(); SetRedraw(FALSE); int index = 0; for(POSITION pos= users->GetHeadPosition(); pos != NULL; index++) { CP4User *user = (CP4User *) users->GetNext(pos); InsertUser(user, index); } SetRedraw(TRUE); CString msg; msg.FormatMessage( IDS_NUMBER_OF_USERS_n, index ); AddToStatus( msg, SV_COMPLETION ); ReSort(); // Make sure previous item is re-selected if(users->GetCount() > 0) { int i = FindInList(m_Active.IsEmpty() ? GET_P4REGPTR()->GetP4User() : m_Active); if (i < 0) i=0; SetItemState(i, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED); EnsureVisible(i, FALSE); // If m_Active is empty but we found the current user in the list, // then set m_Active to the correct value if (m_Active.IsEmpty() && i >= 0) m_Active = GET_P4REGPTR()->GetP4User(); } CP4ListCtrl::SetUpdateDone(); // Notify the mainframe that we have finished getting the users, // hence the entire set of async command have finished. MainFrame()->ExpandDepotIfNeedBe(); if (m_PostViewUpdateMsg) PostMessage(m_PostViewUpdateMsg, m_PostViewUpdateWParam, m_PostViewUpdateLParam); } else CP4ListCtrl::SetUpdateFailed(); delete pCmd; m_PostViewUpdateMsg = 0; MainFrame()->ClearStatus(); return 0; } ////////////////////////////////////////////////////////////////////////// // Sort callback int CUserListCtrl::OnCompareItems(LPARAM lParam1, LPARAM lParam2, int subItem) { ASSERT(lParam1 && lParam2); CP4User const *user1 = (CP4User const*)lParam1; CP4User const *user2 = (CP4User const*)lParam2; CString txt1, txt2; switch(subItem) { case USER_NAME: txt1= user1->GetUserName(); txt2= user2->GetUserName(); break; case USER_EMAIL: txt1= user1->GetEmail(); txt2= user2->GetEmail(); break; case USER_FULLNAME: txt1= user1->GetFullName(); txt2= user2->GetFullName(); break; case USER_DATEACCESS: txt1= user1->GetLastAccess(); txt2= user2->GetLastAccess(); ConvertDates( txt1, txt2 ); 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 CUserListCtrl::OnUserCreatenewuser() { if (m_EditInProgress) { CantEditRightNow(IDS_USER); return; } MainFrame()->ViewUsers(); m_olduser = GET_P4REGPTR()->GetP4User( ); // let user type in the new name. if it's blank the user bailed. // CNewClientDlg newdlg; newdlg.SetNew( NEWUSER ); if (FindInList(m_Active) != -1) newdlg.m_Active = m_Active; if( newdlg.DoModal( ) == IDCANCEL ) return; CString saveActive = m_Active; m_Active = newdlg.GetName( ) ; if ( m_Active.IsEmpty( ) ) { m_Active = saveActive; return; } if (FindInListNoCase(m_Active) != -1) { CString msg; UINT nType; if (FindInList(m_Active) != -1) { msg.FormatMessage ( IDS_USER_s_ALREADY_EXIST, m_Active ); nType = MB_OK; } else { msg.FormatMessage ( IDS_USER_s_DIFFCASE_EXIST, m_Active ); nType = MB_YESNO; } if (IDYES != AfxMessageBox( msg, nType )) { m_Active = saveActive; return; } } if ( SetP4User( ) ) OnEditSpec( m_Active, TRUE ); } BOOL CUserListCtrl::SetP4User( ) { // not that we'd ever get here... but if they are the same, there // is nothing to do, so bail. // if ( m_Active == GET_P4REGPTR()->GetP4User() ) return FALSE; if (GET_P4REGPTR()->GetExpandFlag() == 1) GET_P4REGPTR()->AddMRUPcuPath(MainFrame()->GetCurrentItemPath()); // okay, change the session's user. // (either we're setting the active user back to the registered one // after using another user, or we are officially resetting // the registered user to the new active one.) // if( !GET_P4REGPTR()->SetP4User( m_Active, TRUE, FALSE, FALSE ) ) { AfxMessageBox( IDS_UNABLE_TO_WRITE_P4USER_TO_THE_REGISTRY, MB_ICONEXCLAMATION); m_Active = GET_P4REGPTR()->GetP4User(); return FALSE; } MainFrame()->UpdateCaption( ) ; return TRUE; } void CUserListCtrl::OnUpdateUserSwitchtouser(CCmdUI* pCmdUI) { CString selUser = GetSelectedItemText(); CString prompt; prompt.FormatMessage(IDS_SWITCH_TO_s, TruncateString(selUser, 50)); pCmdUI->SetText ( prompt ); pCmdUI->Enable( !SERVER_BUSY() && !selUser.IsEmpty() && selUser != GET_P4REGPTR()->GetP4User( ) && !MainFrame()->IsModlessUp() ); } void CUserListCtrl::OnUserSwitchtouser() { m_Active = GetSelectedItemText(); if ( SetP4User( ) ) // We just added a user, so make sure the depot and changes // lists are updated MainFrame()->OnPerforceOptions( FALSE ) ; } void CUserListCtrl::OnUpdateSetDefUser(CCmdUI* pCmdUI) { CString selUser = GetSelectedItemText(); pCmdUI->SetText ( LoadStringResource(IDS_SET_DEFAULT_USER_TO) + TruncateString(selUser, 50) ); pCmdUI->Enable( !SERVER_BUSY() && !selUser.IsEmpty() && selUser == GET_P4REGPTR()->GetP4User( FALSE ) && selUser != GET_P4REGPTR()->GetP4User( TRUE ) && !MainFrame()->IsModlessUp() ); } void CUserListCtrl::OnSetDefUser() { if (m_Active != GetSelectedItemText()) { ASSERT(0); return; } if (GET_P4REGPTR()->GetExpandFlag() == 1) GET_P4REGPTR()->AddMRUPcuPath(MainFrame()->GetCurrentItemPath()); if( !GET_P4REGPTR()->SetP4User( m_Active, TRUE, TRUE, TRUE ) ) { AfxMessageBox( IDS_UNABLE_TO_WRITE_P4USER_TO_THE_REGISTRY, MB_ICONEXCLAMATION); m_Active = GetSelectedItemText(); } else { CString txt; txt.FormatMessage(IDS_DEFAULT_USER_SET_TO_s, m_Active); AddToStatus( txt ); } } void CUserListCtrl::OnEditSpec( LPCTSTR sItem, BOOL bNew/*=FALSE*/ ) { if (m_EditInProgress) { CantEditRightNow(IDS_USER); return; } m_pNewSpec = new CP4User; CCmd_EditSpec *pCmd = new CCmd_EditSpec; pCmd->Init( m_hWnd, RUN_ASYNC, HOLD_LOCK ); pCmd->SetIsNewUser(bNew); if( pCmd->Run( P4USER_SPEC, sItem, m_pNewSpec ) ) MainFrame()->UpdateStatus( LoadStringResource(IDS_EDITING_USER_SPEC) ) ; else { delete pCmd; delete m_pNewSpec; } } void CUserListCtrl::OnUpdateUserPassword(CCmdUI* pCmdUI) { OnUpdateUserPassword( pCmdUI, TruncateString(GET_P4REGPTR()->GetP4User(), 50) ); } void CUserListCtrl::OnUpdateUserPassword(CCmdUI* pCmdUI, LPCTSTR userName) { CString txt; txt.FormatMessage(IDS_SET_PASSWORD_FOR_s, TruncateString(userName, 50)); pCmdUI->SetText ( txt ); pCmdUI->Enable( !SERVER_BUSY() && GET_SERVERLEVEL() >= 6 && lstrlen(userName) && !MainFrame()->IsModlessUp()); } void CUserListCtrl::OnUserPassword() { if( GET_SERVERLEVEL() < 6 || !lstrlen(GET_P4REGPTR()->GetP4User()) ) { ASSERT(0); return; } OnUserPasswordDlg(FALSE, NULL); } int CUserListCtrl::OnUserPasswordDlg(BOOL bLogin, int key) { CSetPwdDlg dlg; dlg.m_bLogin = bLogin; dlg.m_Key = key; if (bLogin) dlg.m_Caption = LoadStringResource(IDS_MUST_SET_PASSWORD); return dlg.DoModal(); } ///////////////////////////////////////////////////////////////////// // OLE drag-drop support, to accept depot files or folders // which will define a view to be used to filter the submitted // changes that this window displays ///////////////////////////////////////////////////////////////////// DROPEFFECT CUserListCtrl::OnDragEnter(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point) { m_DropEffect=DROPEFFECT_NONE; m_DragDataFormat=0; // Dont allow a drop if the server is busy, since a drop immediately attempts to // invoke a server command // Also don't allow a drop if we are in local syntax because // the reviews should be specified in depot syntax if(SERVER_BUSY() || m_EditInProgress || GET_P4REGPTR( )->ShowEntireDepot( ) > SDF_DEPOT) return DROPEFFECT_NONE; if(pDataObject->IsDataAvailable( m_CF_DEPOT)) { m_DropEffect=DROPEFFECT_COPY; m_DragDataFormat=m_CF_DEPOT; } return m_DropEffect; } DROPEFFECT CUserListCtrl::OnDragOver(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point) { // Dont allow a drop if the server is busy, since a drop immediately attempts to // invoke a server command if(SERVER_BUSY() || m_EditInProgress) m_DropEffect= DROPEFFECT_NONE; return m_DropEffect; } BOOL CUserListCtrl::OnDrop(COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point) { if(SERVER_BUSY() || m_EditInProgress) { // OnDragEnter() and OnDragOver() should avoid a drop at // the wrong time! ASSERT(0); return FALSE; } if(m_DragDataFormat == m_CF_DEPOT) { ClientToScreen(&point); ::SendMessage(m_depotWnd, WM_DROPTARGET, USERVIEW, MAKELPARAM(point.x,point.y)); return TRUE; } // Return false, so depot window doesnt start a file-open operation return FALSE; } int CUserListCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CP4ListCtrl::OnCreate(lpCreateStruct) == -1) return -1; CStringArray colnames; colnames.Add ( LoadStringResource(IDS_NAME) ); colnames.Add ( LoadStringResource(IDS_E_MAIL) ); colnames.Add ( LoadStringResource(IDS_FULL_NAME) ); colnames.Add ( LoadStringResource(IDS_ACCESS) ); ASSERT( USER_MAXCOL == colnames.GetSize( ) ); int width[ USER_MAXCOL ]={90,150,150,90}; RestoreSavedWidths( width, colnames.GetSize( ), sRegValue_UserList ); InsertColumnHeaders( colnames, width ); return 0; } void CUserListCtrl::OnUpdateAddReviews(CCmdUI* pCmdUI) { CString txt; txt.FormatMessage(IDS_ADD_FILES_TO_USER_s_REVIEWS, GET_P4REGPTR()->GetP4User()); pCmdUI->SetText ( txt ); pCmdUI->Enable( !SERVER_BUSY() && !m_EditInProgress && GET_P4REGPTR()->ShowEntireDepot() <= SDF_DEPOT ); } void CUserListCtrl::OnAddReviews() { if( ! SERVER_BUSY() ) { ::SendMessage(m_depotWnd, WM_GETSELLIST, (WPARAM) &m_ReviewsList, 0); if(m_ReviewsList.GetCount() > 0) { OnUserEditmy(); } } } BOOL CUserListCtrl::TryDragDrop( ) { // Store the job this is from m_DragFromItemName = GetSelectedItemText(); m_OLESource.DelayRenderData( (unsigned short) m_CF_USER); return m_OLESource.DoDragDrop(DROPEFFECT_COPY, &m_DragSourceRect, NULL) == DROPEFFECT_NONE ? FALSE : TRUE; } void CUserListCtrl::OnNewUser(WPARAM wParam, LPARAM lParam) { if (!IsClear()) { CString olduser = wParam ? m_OldDefUser : m_OldCurUser; CString newuser = GET_P4REGPTR()->GetP4User((BOOL)wParam); CString defuser = GET_P4REGPTR()->GetP4User(TRUE); LV_ITEM lvItem; lvItem.mask = LVIF_IMAGE; lvItem.iSubItem = 0; lvItem.state = lvItem.stateMask = 0; lvItem.iItem = FindInList(olduser); if(lvItem.iItem > -1) { lvItem.iImage = CP4ViewImageList::GetUserIndex(false, olduser == defuser); SetItem(&lvItem); } lvItem.iItem = FindInList(newuser); if(lvItem.iItem > -1) { lvItem.iImage = CP4ViewImageList::GetUserIndex(true, newuser == defuser); SetItem(&lvItem); } if (wParam) m_OldDefUser = newuser; else m_OldCurUser = newuser; } ::PostMessage(m_clientWnd, WM_NEWUSER, 0, 0); ::PostMessage(m_branchWnd, WM_NEWUSER, 0, 0); ::PostMessage(m_labelWnd, WM_NEWUSER, 0, 0); }