// ClientListCtrl.cpp : implementation file
//
#include "stdafx.h"
#include "p4win.h"
#include "ClientListCtrl.h"
#include "ClientWizSheet.h"
#include "MainFrm.h"
#include "cmd_editspec.h"
#include "cmd_delete.h"
#include "cmd_describe.h"
#include "cmd_diff2.h"
#include "cmd_clients.h"
#include "cmd_get.h"
#include "cmd_changes.h"
#include "newclientdlg.h"
#include "TemplateNameDlg.h"
#include "Diff2ObjsDlg.h"
#include "ClientFilterDlg.h"
#include "MsgBox.h"
#include "ImageList.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define IMG_INDEX(x) (x-IDB_PERFORCE)
static LPCTSTR sRegValue_ClientList = _T("Client List");
enum ClientSubItems
{
CLIENT_NAME,
CLIENT_OWNER,
CLIENT_HOST,
CLIENT_ACCESSDATE,
CLIENT_ROOT,
CLIENT_DESC,
CLIENT_MAXCOL
};
/////////////////////////////////////////////////////////////////////////////
// CClientListCtrl
IMPLEMENT_DYNCREATE(CClientListCtrl, CP4ListCtrl)
BEGIN_MESSAGE_MAP(CClientListCtrl, CP4ListCtrl)
ON_COMMAND(ID_CLIENT_DELETE, OnClientDelete)
ON_UPDATE_COMMAND_UI(ID_CLIENT_DELETE, OnUpdateClientDelete)
ON_UPDATE_COMMAND_UI(ID_VIEW_UPDATE_RIGHT, OnUpdateViewUpdate)
ON_WM_CONTEXTMENU()
ON_COMMAND(ID_CLIENT_TEMPLATE, OnClientTemplate)
ON_UPDATE_COMMAND_UI(ID_CLIENT_TEMPLATE, OnUpdateClientTemplate)
ON_COMMAND(ID_CLIENT_USEASLOCALTEMPLATE, OnUseAsLocalTemplate)
ON_UPDATE_COMMAND_UI(ID_CLIENT_USEASLOCALTEMPLATE, OnUpdateUseAsLocalTemplate)
ON_COMMAND(ID_CLIENT_CLEARLOCALTEMPLATE, OnClearLocalTemplate)
ON_UPDATE_COMMAND_UI(ID_CLIENT_CLEARLOCALTEMPLATE, OnUpdateClearLocalTemplate)
ON_UPDATE_COMMAND_UI(ID_CLIENT_DESCRIBE, OnUpdateClientDescribe)
ON_COMMAND(ID_CLIENT_DESCRIBE, OnDescribe)
ON_WM_LBUTTONDBLCLK()
ON_COMMAND(ID_CLIENTSPEC_SWITCH, OnClientspecSwitch)
ON_UPDATE_COMMAND_UI(ID_CLIENTSPEC_SWITCH, OnUpdateClientspecSwitch)
ON_COMMAND(ID_SETDEFCLIENT, OnSetDefClient)
ON_UPDATE_COMMAND_UI(ID_SETDEFCLIENT, OnUpdateSetDefClient)
ON_COMMAND(ID_VIEW_UPDATE_RIGHT, OnViewUpdate)
ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, OnColumnclick)
ON_NOTIFY_REFLECT(LVN_DELETEITEM, OnDeleteitem)
ON_COMMAND(ID_CLIENTSPEC_NEW, OnClientspecNew)
ON_UPDATE_COMMAND_UI(ID_CLIENTSPEC_NEW, OnUpdateClientspecNew)
ON_WM_CREATE()
ON_UPDATE_COMMAND_UI(ID_ADD_TOVIEW, OnUpdateAddToClientView)
ON_COMMAND(ID_ADD_TOVIEW, OnAddToClientView)
ON_COMMAND(ID_PERFORCE_OPTIONS, OnPerforceOptions)
ON_UPDATE_COMMAND_UI(ID_FILE_DIFF2, OnUpdateDiff2Clients)
ON_COMMAND(ID_FILE_DIFF2, OnDiff2Clients)
ON_UPDATE_COMMAND_UI(ID_FILTERCLIENTS, OnUpdateFilterClients)
ON_COMMAND(ID_FILTERCLIENTS, OnFilterClients)
ON_UPDATE_COMMAND_UI(ID_CLEARCLIENTFILTER, OnUpdateClearClientFilter)
ON_COMMAND(ID_CLEARCLIENTFILTER, OnClearClientFilter)
ON_MESSAGE(WM_P4CLIENTS, OnP4ClientList )
ON_MESSAGE(WM_P4EDITSPEC, OnP4ClientSpec )
ON_MESSAGE(WM_P4ENDSPECEDIT, OnP4EndSpecEdit )
ON_MESSAGE(WM_P4DELETE, OnP4Delete )
ON_MESSAGE(WM_P4DESCRIBE, OnP4Describe )
ON_MESSAGE(WM_P4ENDDESCRIBE, OnP4EndDescribe )
ON_MESSAGE(WM_P4GET, OnP4Sync )
ON_MESSAGE(WM_NEWUSER, NewUser )
ON_MESSAGE(WM_P4DESCRIBEALT, OnP4UseAsLocalTemplate )
END_MESSAGE_MAP()
CClientListCtrl::CClientListCtrl()
{
m_SortAscending=TRUE;
m_LastSortCol=0;
m_OldClient = GET_P4REGPTR()->GetP4Client();
m_ClientNew.Empty();
m_NewClicked = m_NewClient = FALSE;
m_viewType = P4CLIENT_SPEC;
m_OldDefClient = m_OldCurClient = _T("@");
m_PrevNbrCli = -1;
m_CF_DEPOT = RegisterClipboardFormat(LoadStringResource(IDS_DRAGFROMDEPOT));
m_CF_CLIENT= RegisterClipboardFormat(LoadStringResource(IDS_DRAGFROMCLIENT));
m_caption = m_captionplain = LoadStringResource(IDS_PERFORCE_CLIENTS);
}
CClientListCtrl::~CClientListCtrl()
{
}
/////////////////////////////////////////////////////////////////////////////
// CClientListCtrl diagnostics
#ifdef _DEBUG
void CClientListCtrl::AssertValid() const
{
CP4ListCtrl::AssertValid();
}
void CClientListCtrl::Dump(CDumpContext& dc) const
{
CP4ListCtrl::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CClientListCtrl message handlers
/*
_________________________________________________________________
let user edit the client spec s/he clicked on.
_________________________________________________________________
*/
void CClientListCtrl::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 CClientListCtrl::OnDeleteitem(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
delete (CP4Client *) GetItemData(pNMListView->iItem);
*pResult = 0;
}
/*
_________________________________________________________________
define a new client, which means
set the current client to this new one (true? maybe i should ask the user)
sometimes change the registry
edit this new client's spec
this used to be done in the options dialogue's connection
parameters
_________________________________________________________________
*/
void CClientListCtrl::OnUpdateClientspecNew(CCmdUI* pCmdUI)
{
pCmdUI->SetText ( LoadStringResource( IDS_NEW ) );
pCmdUI->Enable( !SERVER_BUSY() && !m_EditInProgress && !MainFrame()->IsModlessUp() );
}
/*
_________________________________________________________________
*/
void CClientListCtrl::ClientspecNew()
{
OnClientspecNew( ) ;
}
/*
_________________________________________________________________
*/
void CClientListCtrl::OnClientspecNew()
{
DoClientspecNew(FALSE, NULL);
}
void CClientListCtrl::DoClientspecNew(BOOL bUseDefTemplate, LPCTSTR defName )
{
MainFrame()->ViewClients();
m_ClientNew.Empty();
m_OldClient= GET_P4REGPTR()->GetP4Client();
// let user type in the new name. if it's blank the user bailed.
//
CNewClientDlg newdlg;
newdlg.SetNew( NEWCLIENT );
if (FindInListAll(m_Active) != -1)
newdlg.m_Active = m_Active;
if (defName)
newdlg.m_Name = defName;
if( newdlg.DoModal( ) == IDCANCEL )
return;
if (newdlg.m_RunWizard)
{
CString txt;
CString port = GET_P4REGPTR()->GetP4Port();
CString clientname = newdlg.GetName();
txt.FormatMessage( IDS_NOCLIENT_s_s_s, clientname, port, GET_P4REGPTR()->GetP4User() );
int i;
if ((i = txt.Find(_T('\n'))) != -1)
{
txt = txt.Mid(i);
txt.TrimLeft();
}
CClientWizSheet dlg(LoadStringResource(IDS_CLIENTWORKSPACEWIZARD), this, 1);
dlg.SetMsg(txt);
dlg.SetName(clientname);
dlg.SetPort(port);
dlg.AllowBrowse(FALSE);
int rc;
while(1)
{
if( (rc = dlg.DoModal()) == IDCANCEL ) // user bailed
{
break;
}
if ( rc == IDIGNORE ) // user chose to browse existing clients
{
ViewUpdate();
break;
}
else // user clicked the Finish button on the create client page
{
CString newClient = dlg.GetName();
CString newRoot = dlg.GetRoot();
BOOL bEdit = dlg.IsEdit();
BOOL bTmpl = dlg.IsTmpl();
CString tmplate = dlg.GetTmpl();
while (m_UpdateState == LIST_UPDATING)
Sleep(100);
if (FindInListAll(newClient) != -1)
{
CString msg;
msg.FormatMessage(IDS_CANT_RECREATE_EXISTING_CLIENT_s, newClient);
AfxMessageBox( msg, MB_ICONSTOP );
}
else if (!newClient.IsEmpty() && !newRoot.IsEmpty())
{
if (AutoCreateClientSpec(newClient, newRoot, bEdit, bTmpl, tmplate))
break;;
}
}
}
return;
}
CString saveActive = m_Active;
m_Active = newdlg.GetName( ) ;
if ( m_Active.IsEmpty( ) )
return;
if ( SetP4Client( TRUE ) )
{
// rather than use the current directory as the default client root
// switch to the drive's root and use that; switch back at the end.
TCHAR buf[MAX_PATH+1];
TCHAR root[4];
if (GetCurrentDirectory(MAX_PATH, buf))
{
_tcsncpy(root, buf, 3);
root[3] = '\0';
SetCurrentDirectory(root);
}
else
{
buf[0] = _T('\0');
}
// Get the edit of the new spec underway
m_NewClient = (saveActive != m_Active);
m_NewClicked = TRUE;
OnEditSpec( m_Active, bUseDefTemplate );
m_ClientNew = m_Active;
// restore previous working directory
if (buf[0])
SetCurrentDirectory(buf);
}
}
/*
_________________________________________________________________
*/
void CClientListCtrl::OnUpdateClientDelete(CCmdUI* pCmdUI)
{
pCmdUI->Enable( OnUpdateShowMenuItem( pCmdUI, IDS_DELETE_s )
&& GetSelectedItemText() == GET_P4REGPTR()->GetP4Client()
&& !MainFrame()->IsModlessUp() );
}
BOOL CClientListCtrl::OKToDelete( )
{
if ( GetSelectedItemText() == GET_P4REGPTR()->GetP4Client() )
return TRUE;
else
{
AfxMessageBox(IDS_NO_PERMISSION_TO_DELETE_OTHER_CLIENTS, MB_ICONINFORMATION);
return FALSE;
}
}
/*
_________________________________________________________________
*/
void CClientListCtrl::OnClientDelete()
{
OnDelete( P4CLIENT_DEL );
}
/*
_________________________________________________________________
*/
void CClientListCtrl::EditTheSpec(CString *name)
{
if (*name == GET_P4REGPTR()->GetP4Client())
OnClientEditmy();
}
void CClientListCtrl::OnClientEditmy()
{
m_Active = GET_P4REGPTR()->GetP4Client();
m_OldClient= m_Active;
m_NewClicked = m_NewClient = FALSE;
int index = FindInList( m_Active ) ;
if ( index > -1 )
{
SetItemState(index, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED);
EnsureVisible(index, FALSE);
}
OnEditSpec( m_Active );
}
void CClientListCtrl::OnUpdateClientTemplate(CCmdUI* pCmdUI)
{
m_Active = GetSelectedItemText();
CString sCurrentClient = GET_P4REGPTR()->GetP4Client();
CString prompt;
prompt.FormatMessage(IDS_CREATE_UPDATE_CLIENT_USING_s_AS_TEMPLATE,
m_Active.IsEmpty( ) ? TruncateString(sCurrentClient, 50) : TruncateString(m_Active, 50));
pCmdUI->SetText ( prompt );
pCmdUI->Enable( !SERVER_BUSY() && !m_EditInProgress
&& !m_Active.IsEmpty()
&& !MainFrame()->IsModlessUp() );
}
/*
_________________________________________________________________
*/
void CClientListCtrl::OnClientTemplate()
{
m_Template = GetSelectedItemText();
m_OldClient= GET_P4REGPTR()->GetP4Client();
m_Active.Empty();
// rather than use the current directory as the default client root
// switch to the drive's root and use that; switch back at the end.
TCHAR buf[MAX_PATH+1];
TCHAR root[4];
if (GetCurrentDirectory(MAX_PATH, buf))
{
_tcsncpy(root, buf, 3);
root[3] = '\0';
SetCurrentDirectory(root);
}
else
{
buf[0] = _T('\0');
}
OnEditTemplate( m_Template );
// restore previous working directory
if (buf[0])
SetCurrentDirectory(buf);
}
void CClientListCtrl::OnUpdateClearLocalTemplate(CCmdUI* pCmdUI)
{
pCmdUI->Enable( !CString(GET_P4REGPTR()->GetLocalCliTemplate()).IsEmpty() );
}
void CClientListCtrl::OnClearLocalTemplate()
{
GET_P4REGPTR()->SetLocalCliTemplate(_T(""));
}
void CClientListCtrl::OnUpdateUseAsLocalTemplate(CCmdUI* pCmdUI)
{
m_Active = GetSelectedItemText();
CString sCurrentClient = GET_P4REGPTR()->GetP4Client();
CString prompt;
prompt.FormatMessage(IDS_CLIENT_USEASLOCALTEMPLATE,
m_Active.IsEmpty( ) ? TruncateString(sCurrentClient, 50) : TruncateString(m_Active, 50));
pCmdUI->SetText ( prompt );
pCmdUI->Enable( !SERVER_BUSY() && !m_EditInProgress
&& !m_Active.IsEmpty()
&& !MainFrame()->IsModlessUp()
&& GET_P4REGPTR()->LocalCliTemplateSw() );
}
void CClientListCtrl::OnUseAsLocalTemplate()
{
m_Active = GetSelectedItemText();
if ( m_Active.IsEmpty( ) )
return;
CCmd_Describe *pCmd = new CCmd_Describe;
pCmd->Init( m_hWnd, RUN_ASYNC );
pCmd->SetAlternateReplyMsg( WM_P4DESCRIBEALT );
if( pCmd->Run( m_viewType, m_Describing = m_Active ) )
{
MainFrame()->UpdateStatus( LoadStringResource(IDS_FETCHING_SPEC) );
return;
}
else
{
delete pCmd;
return;
}
}
LRESULT CClientListCtrl::OnP4UseAsLocalTemplate(WPARAM wParam, LPARAM lParam)
{
CCmd_Describe *pCmd = (CCmd_Describe *) wParam;
CString ref = pCmd->GetReference();
CString tmplate = pCmd->GetDescription();
int i;
if ((i = tmplate.Find(_T("\n\nClient:\t"))) != -1)
{
tmplate = tmplate.Mid(i);
tmplate.Replace(ref, LOCALDEFTEMPLATE);
if (GET_P4REGPTR()->SetLocalCliTemplate(tmplate))
{
CString msg;
msg.FormatMessage(IDS_LOCALDEFTEMPLATESET_s, ref);
AddToStatus(msg, SV_COMPLETION);
}
}
delete pCmd;
MainFrame()->ClearStatus();
return 0;
}
void CClientListCtrl::OnUpdateClientDescribe(CCmdUI* pCmdUI)
{
pCmdUI->Enable( OnUpdateShowMenuItem( pCmdUI, IDS_DESCRIBEIT_s )
&& !MainFrame()->IsModlessUp() );
}
/*
_________________________________________________________________
whether to show or grey out the F5 menu item on the context menu
_________________________________________________________________
*/
void CClientListCtrl::OnUpdateViewUpdate(CCmdUI* pCmdUI)
{
pCmdUI->Enable(!SERVER_BUSY() && !MainFrame()->IsModlessUp());
}
/*
_________________________________________________________________
user hit F5 or equiv
_________________________________________________________________
*/
void CClientListCtrl::OnViewUpdate()
{
m_Active = GetSelectedItemText();
SetCaption();
CCmd_Clients *pCmd= new CCmd_Clients;
pCmd->Init( m_hWnd, RUN_ASYNC);
if( pCmd->Run( ) )
{
MainFrame()->UpdateStatus(LoadStringResource(IDS_REQUESTING_CLIENT_LISTING));
MainFrame()->SetClientUpdateTime(GetTickCount());
Clear();
CP4ListCtrl::OnViewUpdate();
}
else
delete pCmd;
}
CString CClientListCtrl::SetCaption()
{
int i = GET_P4REGPTR()->GetClientFilteredFlags();
if (i)
{
CString filter;
CString txt;
if (i & 0x10)
txt = LoadStringResource(IDS_CURRENT_USER);
else if (i & 0x01)
txt = GET_P4REGPTR()->GetClientFilterOwner();
if (i & 0x22)
{
if (!txt.IsEmpty())
txt += _T(", ");
txt += i & 0x20 ? GET_P4REGPTR()->GetHostname() : GET_P4REGPTR()->GetClientFilterHost();
}
if (i & 0x04)
{
if (!txt.IsEmpty())
txt += _T(", ");
txt += CString(_T("\"")) + GET_P4REGPTR()->GetClientFilterDesc() + _T("\"");
}
filter.FormatMessage(IDS_FILTERED, txt);
m_caption = LoadStringResource(IDS_PERFORCE_CLIENTS) + filter;
}
else
m_caption = LoadStringResource(IDS_PERFORCE_CLIENTS);
CP4PaneContent::GetView()->SetCaption();
return m_caption;
}
/*
_________________________________________________________________
*/
LRESULT CClientListCtrl::NewUser(WPARAM wParam, LPARAM lParam)
{
if (GET_P4REGPTR()->GetClientFilteredFlags() & 0x10)
Clear();
return 0;
}
void CClientListCtrl::Clear()
{
SetRedraw(FALSE);
DeleteAllItems();
SetRedraw(TRUE);
CP4ListCtrl::Clear();
}
/*
_________________________________________________________________
called when user right clicks on a clientspec. create one of two
menus, depending on where the user clicked.
if user has highlighted a client, allow them to do the usual
things to a client view. (describe it, switch to it, use it as
a template to create a new client)
(edit and delete -- i need to know the owner. but delete is already there!)
if the user clicked on a random part of the pane, show
only the general choices, like refresh, create a new client
-- and maybe edit the current client?
_________________________________________________________________
*/
void CClientListCtrl::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 );
// Can always create a new client
popMenu.AppendMenu( stringsON, ID_CLIENTSPEC_NEW );
// Only offer edit if no other client is selected
if ( index == -1 || GetSelectedItemText() == GET_P4REGPTR()->GetP4Client() )
popMenu.AppendMenu( stringsON, ID_CLIENT_EDITMY );
if( index != -1 )
{
// Make sure item gets selected
SetItemState( index, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED );
popMenu.AppendMenu( stringsON, ID_CLIENT_DESCRIBE ); //or client edit if user is the owner
popMenu.AppendMenu( stringsON, ID_CLIENT_DELETE );
popMenu.AppendMenu( MF_SEPARATOR );
// Can only switch to a client if its not my current client
if ( GetSelectedItemText() != GET_P4REGPTR()->GetP4Client() )
popMenu.AppendMenu( stringsON, ID_CLIENTSPEC_SWITCH );
else // can only set as default if it is my current client
popMenu.AppendMenu( stringsON, ID_SETDEFCLIENT );
popMenu.AppendMenu( stringsON, ID_CLIENT_TEMPLATE );
if (GET_P4REGPTR()->LocalCliTemplateSw())
{
popMenu.AppendMenu( MF_SEPARATOR );
popMenu.AppendMenu( stringsON, ID_CLIENT_USEASLOCALTEMPLATE, LoadStringResource(IDS_CLIENT_USEASLOCALTEMPLATE) );
popMenu.AppendMenu( stringsON, ID_CLIENT_CLEARLOCALTEMPLATE, LoadStringResource(IDS_CLIENT_CLEARLOCALTEMPLATE) );
}
}
popMenu.AppendMenu( MF_SEPARATOR );
popMenu.AppendMenu( stringsON, ID_FILTERCLIENTS, LoadStringResource(IDS_FILTERCLIENTS) );
popMenu.AppendMenu( stringsON, ID_CLEARCLIENTFILTER, LoadStringResource(IDS_CLEARCLIENTFILTER) );
popMenu.AppendMenu( MF_SEPARATOR );
CString txt = GetSelectedItemText();
if (txt.IsEmpty())
txt = GET_P4REGPTR()->GetP4Client( );
txt = LoadStringResource(IDS_CHGS_BY_CLIENT) + txt;
txt = TruncateString(txt, 50);
popMenu.AppendMenu( stringsON, ID_CHGS_BY_CLIENT, txt );
popMenu.AppendMenu( stringsON, ID_VIEW_UPDATE, LoadStringResource(IDS_REFRESH) );
MainFrame()->AddToolsToContextMenu(&popMenu);
// put up the menu
//
popMenu.TrackPopupMenu( TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, AfxGetMainWnd( ) );
}
/////////////////////////////////////////////////////////////////////////////
// CClientListCtrl message handlers
/*
_________________________________________________________________
*/
void CClientListCtrl::OnUpdateClientspecSwitch(CCmdUI* pCmdUI)
{
CString selClient = GetSelectedItemText();
CString prompt;
prompt.FormatMessage(IDS_SWITCH_TO_s, TruncateString(selClient, 50));
pCmdUI->SetText ( prompt );
pCmdUI->Enable( !SERVER_BUSY()
&& !selClient.IsEmpty()
&& selClient != GET_P4REGPTR()->GetP4Client( )
&& !MainFrame()->IsModlessUp());
}
/*
_________________________________________________________________
*/
void CClientListCtrl::OnClientspecSwitch()
{
ClientSpecSwitch(GetSelectedItemText());
}
BOOL CClientListCtrl::ClientSpecSwitch(CString switchTo, BOOL bAlways /*=FALSE*/, BOOL portWasChanged /*= FALSE*/)
{
CCmd_Describe *pCmd = new CCmd_Describe;
pCmd->Init( NULL, RUN_SYNC );
BOOL cmdStarted= pCmd->Run( P4CLIENT_SPEC, switchTo );
if(cmdStarted && !pCmd->GetError())
{
CString options= TheApp()->GetClientSpecField( _T("Options"), pCmd->GetDescription() );
if (( options.Find(_T("unlocked")) == -1 ) && ( options.Find(_T("locked")) != -1 ))
{
CString lockedby= TheApp()->GetClientSpecField( _T("Owner"), pCmd->GetDescription() );
if ( lockedby.Compare( GET_P4REGPTR()->GetP4User() ) != 0 )
{
CString errmsg;
errmsg.FormatMessage(IDS_CLIENT_s_IS_LOCKED_BY_USER_s_AND_CANT_BE_USED_BY_s,
switchTo, lockedby, GET_P4REGPTR()->GetP4User());
AddToStatus( errmsg, SV_WARNING );
AfxMessageBox( errmsg, MB_ICONEXCLAMATION );
delete pCmd;
return FALSE;
}
}
}
delete pCmd;
m_Active = switchTo;
if ( SetP4Client( bAlways ) )
MainFrame()->OnPerforceOptions( FALSE, portWasChanged ) ;
return TRUE;
}
/*
_________________________________________________________________
*/
void CClientListCtrl::OnUpdateSetDefClient(CCmdUI* pCmdUI)
{
CString selClient = GetSelectedItemText();
CString prompt;
prompt.FormatMessage(IDS_SETDEFCLIENT_s, TruncateString(selClient, 50));
pCmdUI->SetText ( prompt );
pCmdUI->Enable( !SERVER_BUSY()
&& !selClient.IsEmpty()
&& selClient == GET_P4REGPTR()->GetP4Client( FALSE )
&& selClient != GET_P4REGPTR()->GetP4Client( TRUE )
&& !MainFrame()->IsModlessUp() );
}
/*
_________________________________________________________________
*/
void CClientListCtrl::OnSetDefClient()
{
if (m_Active != GetSelectedItemText())
{
ASSERT(0);
return;
}
if (GET_P4REGPTR()->GetExpandFlag() == 1)
GET_P4REGPTR()->AddMRUPcuPath(MainFrame()->GetCurrentItemPath());
if( !GET_P4REGPTR()->SetP4Client( m_Active, TRUE, TRUE, TRUE ) )
{
AfxMessageBox(IDS_UNABLE_TO_WRITE_P4CLIENT_TO_THE_REGISTRY, MB_ICONEXCLAMATION);
m_Active = GetSelectedItemText();
}
else
{
CString msg;
msg.FormatMessage(IDS_DEFAULT_CLIENT_SET_TO_s, m_Active);
AddToStatus( msg );
}
}
/*
_________________________________________________________________
*/
//fanny: damn! p4clients doesn't give you the owner! how can i put up an
//edit menu item without checking first?
void CClientListCtrl::InsertClient(CP4Client *client, int index,
CString *curclient, CString *defclient, CString *user)
{
ASSERT(client != NULL);
m_iImage = CP4ViewImageList::VI_CLIENT;
LV_ITEM lvItem;
int iActualItem = -1;
CString txt;
BOOL bFilteredOut = MainFrame()->IsClientFilteredOut(client, user, curclient, defclient);
for(int subItem=0; subItem < CLIENT_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;
switch(subItem)
{
case CLIENT_NAME:
{
lvItem.pszText = const_cast<LPTSTR>(client->GetClientName());
bool isCurrent = curclient->Compare(lvItem.pszText) == 0;
bool isDefault = defclient->Compare(lvItem.pszText) == 0;
lvItem.iImage = CP4ViewImageList::GetClientIndex(isCurrent, isDefault);
if(isDefault)
m_OldDefClient = lvItem.pszText;
if(isCurrent)
m_OldCurClient = lvItem.pszText;
lvItem.lParam=(LPARAM) client;
}
break;
case CLIENT_OWNER:
lvItem.pszText = const_cast<LPTSTR>( (LPCTSTR) client->GetOwner()); break;
case CLIENT_HOST:
lvItem.pszText = const_cast<LPTSTR>( (LPCTSTR) client->GetHost()); break;
case CLIENT_ACCESSDATE:
lvItem.pszText = const_cast<LPTSTR>( (LPCTSTR) client->GetDate()); break;
case CLIENT_ROOT:
lvItem.pszText = const_cast<LPTSTR>( (LPCTSTR) client->GetRoot()); break;
case CLIENT_DESC:
txt= PadCRs(client->GetDescription());
lvItem.pszText = const_cast<LPTSTR>( (LPCTSTR) txt); break;
default:
ASSERT( 0 ); lvItem.pszText = _T("@"); break;
}
m_ListAll.column[subItem].SetAtGrow(index, lvItem.pszText);
if (bFilteredOut)
continue;
if (subItem==0)
{
static BOOL bErrDispalyed=FALSE;
iActualItem=InsertItem(&lvItem);
if (iActualItem==-1 && !bErrDispalyed)
{
AfxMessageBox(_T("Client item insert failure"), MB_ICONSTOP);
bErrDispalyed = TRUE;
}
}
else
SetItem(&lvItem);
}
if (bFilteredOut)
delete client;
}
/*
_________________________________________________________________
*/
void CClientListCtrl::UpdateClient(CP4Client *client, int index)
{
// After a spec edit, update the appropriate list item
// First, switch the client data
CP4Client *oldClient= (CP4Client *) GetItemData(index);
delete oldClient;
SetItemData(index, (LPARAM) client);
// Then update the text
SetItemText(index, CLIENT_NAME, const_cast<LPTSTR>( (LPCTSTR) client->GetClientName()));
SetItemText(index, CLIENT_OWNER, const_cast<LPTSTR>( (LPCTSTR) client->GetOwner()));
SetItemText(index, CLIENT_HOST, const_cast<LPTSTR>( (LPCTSTR) client->GetHost()));
SetItemText(index, CLIENT_ACCESSDATE, const_cast<LPTSTR>( (LPCTSTR) client->GetDate()));
SetItemText(index, CLIENT_ROOT, const_cast<LPTSTR>( (LPCTSTR) client->GetRoot()));
CString txt= PadCRs(client->GetDescription());
SetItemText(index, CLIENT_DESC, const_cast<LPTSTR>((LPCTSTR)txt));
}
void CClientListCtrl::UpdateClientAll(CP4Client *client, int index)
{
m_ListAll.column[CLIENT_NAME].SetAt(index, const_cast<LPTSTR>((LPCTSTR)client->GetClientName()));
m_ListAll.column[CLIENT_OWNER].SetAt(index, const_cast<LPTSTR>((LPCTSTR)client->GetOwner()));
m_ListAll.column[CLIENT_HOST].SetAt(index, const_cast<LPTSTR>((LPCTSTR)client->GetHost()));
m_ListAll.column[CLIENT_ACCESSDATE].SetAt(index, const_cast<LPTSTR>((LPCTSTR)client->GetDate()));
m_ListAll.column[CLIENT_ROOT].SetAt(index, const_cast<LPTSTR>((LPCTSTR)client->GetRoot()));
CString txt= PadCRs(client->GetDescription());
m_ListAll.column[CLIENT_DESC].SetAt(index, const_cast<LPTSTR>((LPCTSTR)txt));
}
/*
_________________________________________________________________
Receives ak for client spec edit
_________________________________________________________________
*/
LRESULT CClientListCtrl::OnP4ClientSpec(WPARAM wParam, LPARAM lParam)
{
m_PrevNbrCli = m_UpdateState == LIST_CLEAR ? -1 : GetItemCount();
m_saveclientnew = m_ClientNew; // save name of freshly created client
CCmd_EditSpec *pCmd = (CCmd_EditSpec *) wParam;
if (pCmd->GetUseLocalDefTmplate())
{
CString specIn(pCmd->GetSpecIn());
int i;
if ((i = specIn.Find(_T("\n\nClient:\t"))) != -1)
{
CString tmplate = GET_P4REGPTR()->GetLocalCliTemplate();
tmplate.Replace(LOCALDEFTEMPLATE, pCmd->GetItemName());
pCmd->SetSpecIn(specIn.Left(i) + tmplate);
}
}
m_ClientNew.Empty();
// let the dialogbox know whether this is a new client or an edit of an existing one
int index= FindInListAll(m_Active.IsEmpty() ? pCmd->GetItemName() : m_Active);
if ((index == -1) || !GetItemCount()) // if name not in client list
index = m_NewClient ? -1 : -2; // it's new if and only if they clicked 'New'
pCmd->SetIsNewClient(m_isNew = (index == -1));
pCmd->SetIsRequestingNew(m_NewClicked);
pCmd->SetOldClient(m_OldClient);
pCmd->SetCaller(DYNAMIC_DOWNCAST(CView, GetParent()));
m_NewClicked = m_NewClient = FALSE; // clear these now, cuz no longer needed
if (m_AddToViewList.GetCount() > 0) // We have files to add to the Reviews list
{
CString specIn(pCmd->GetSpecIn());
int i;
if ((i = specIn.Find(_T("\n\nView:\n"))) == -1)
{
i = specIn.GetLength();
specIn += _T("\n\nView:\n");
}
else
specIn += _T("\t@\t@\n"); // A view that is @[TAB]@ means
// put a blank line in the list here.
POSITION pos;
CString filename;
CString localname;
BOOL b = GET_P4REGPTR()->UseDepotInClientView();
for (pos = m_AddToViewList.GetHeadPosition(); pos != NULL; )
{
filename = m_AddToViewList.GetNext(pos);
if ((i = filename.Find(_T("<contains no files or folders>"))) != -1)
filename = filename.Left(i-1) + _T("/...");
localname = CString ( _T("//") ) + GET_P4REGPTR()->GetP4Client();
if (!b && ((i = filename.Find(_T('/'), 2)) > 2))
localname += filename.Right(filename.GetLength() - i);
else
localname += filename.Right(filename.GetLength() - 1);
if (filename.Find(_T(' ')))
filename = _T('\"') + filename + _T('\"');
if (localname.Find(_T(' ')))
localname = _T('\"') + localname + _T('\"');
specIn += _T('\t') + filename + _T('\t') + localname + _T('\n');
}
m_AddToViewList.RemoveAll(); // this info is no longer needed
pCmd->SetSpecIn(specIn);
}
// show the dialog box
if(!pCmd->GetError() && !m_EditInProgress && pCmd->DoSpecDlg(this))
{
m_EditInProgress = TRUE;
m_EditInProgressWnd = pCmd->GetSpecSheet();
}
else
{
if (GET_P4REGPTR()->GetExpandFlag() == 1)
GET_P4REGPTR()->AddMRUPcuPath(MainFrame()->GetCurrentItemPath());
m_Active = m_OldClient;
GET_P4REGPTR()->SetP4Client( m_Active, TRUE, FALSE, FALSE);
MainFrame()->UpdateCaption( ) ;
delete m_pNewSpec;
if (pCmd->HaveServerLock())
pCmd->ReleaseServerLock();
delete pCmd;
}
MainFrame()->ClearStatus();
return 0;
}
LRESULT CClientListCtrl::OnP4EndSpecEdit( WPARAM wParam, LPARAM lParam )
{
CCmd_EditSpec *pCmd= (CCmd_EditSpec *) wParam;
BOOL chainedCommand = FALSE;
BOOL need2Refresh = FALSE;
if (lParam != IDCANCEL && lParam != IDABORT)
{
// Get the Sync flag
int syncAfter = SYNC_DONT;
BOOL bHasChgs = TRUE;
if (m_PrevNbrCli < 1)
{
int key= pCmd->HaveServerLock() ? pCmd->GetServerKey() : 0;
CCmd_Changes *pCmd2= new CCmd_Changes;
pCmd2->Init( m_hWnd, RUN_SYNC, key ? HOLD_LOCK : LOSE_LOCK, key);
if( pCmd2->Run(SUBMITTED_CHANGES, FALSE, NULL, 1) )
{
if (!pCmd2->GetChanges()->GetCount())
bHasChgs = FALSE;
}
delete pCmd2;
}
if (m_isNew && !GET_P4REGPTR()->DontShowYouHaveCr8NewClient() && bHasChgs)
{
BOOL b;
switch(MsgBox(IDS_YOU_HAVE_CREATED_NEW_CLIENT,
MB_ICONEXCLAMATION | MB_DEFBUTTON1, 0, this, &b))
{
case IDC_BUTTON1:
syncAfter = SYNC_HEAD;
break;
case IDC_BUTTON2:
syncAfter = SYNC_DONT;
break;
}
GET_P4REGPTR()->SetDontShowYouHaveCr8NewClient(b);
}
else if ((pCmd->IsSyncAfter() || pCmd->IsAutoUpdateSpec())
&& !GET_P4REGPTR()->DontShowYouHaveChgClientView() && bHasChgs)
{
BOOL b;
switch(MsgBox(pCmd->IsAutoUpdateSpec() ? IDS_DOYOUWANTOTSYNCYOURNEWCLIENT
: IDS_YOU_HAVE_CHANGED_CLIENTS_VIEW,
MB_ICONQUESTION | MB_DEFBUTTON1, 0, this,
pCmd->IsAutoUpdateSpec() ? NULL : &b))
{
case IDC_BUTTON1:
syncAfter = SYNC_HEAD;
break;
case IDC_BUTTON2:
syncAfter = pCmd->IsAutoUpdateSpec() ? SYNC_DONT : SYNC_HAVE;
break;
case IDC_BUTTON3:
syncAfter = SYNC_DONT;
break;
}
if (!pCmd->IsAutoUpdateSpec())
GET_P4REGPTR()->SetDontShowYouHaveChgClientView(b);
}
BOOL bDeld = FALSE;
if (m_UpdateState == LIST_UPDATED)
{
// we have to set 'index' again in case client's name got changed
int index= FindInList(m_pNewSpec->GetClientName());
int ixAll= FindInListAll(m_pNewSpec->GetClientName());
if (ixAll == -1) // not in either list
{
ASSERT(index == -1);
CString curclient = GET_P4REGPTR()->GetP4Client();
CString defclient = GET_P4REGPTR()->GetP4Client(TRUE);
InsertClient(m_pNewSpec, GetItemCount(), &curclient, &defclient);
}
else if (index > -1) // in both lists
{
ASSERT(ixAll > -1);
if (MainFrame()->IsClientFilteredOut(m_pNewSpec)) // should it no longer be shown?
{
need2Refresh = TRUE;
delete m_pNewSpec;
}
else
{
UpdateClient(m_pNewSpec, index);
UpdateClientAll(m_pNewSpec, ixAll);
}
}
else // not in visible list; is in list of all
{
if (MainFrame()->IsClientFilteredOut(m_pNewSpec)) // should it now be shown?
need2Refresh = TRUE;
else
UpdateClientAll(m_pNewSpec, ixAll);
if (pCmd->IsAutoUpdateSpec())
m_OldClient = m_pNewSpec->GetClientName();
delete m_pNewSpec;
bDeld = TRUE;
}
ReSort();
if (pCmd->IsAutoUpdateSpec() || pCmd->IsSpecForceSwitch())
{
if (bDeld)
need2Refresh = TRUE;
else
{
int i = FindInList(m_OldClient = m_pNewSpec->GetClientName());
if (i < 0)
i = 0;
SetItemState(i, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED);
EnsureVisible(i, FALSE);
}
m_Active = _T("@"); // force switch to new client
}
}
else
if ( m_pNewSpec ) delete m_pNewSpec;
int key= pCmd->HaveServerLock() ? pCmd->GetServerKey() : 0;
if( m_Active == m_saveclientnew ) // active-client == saved new client name
m_OldClient = m_saveclientnew; // means they decided to edit the current client
if( m_Active != m_OldClient ) // If current client is not now the client when this
{ // all started, switch to the new current client
if (GET_P4REGPTR()->GetExpandFlag() == 1)
GET_P4REGPTR()->AddMRUPcuPath(MainFrame()->GetCurrentItemPath());
m_Active = m_OldClient;
GET_P4REGPTR()->SetP4Client( m_Active, TRUE, FALSE, FALSE);
MainFrame()->UpdateCaption( );
if (syncAfter)
chainedCommand = SyncAfter(key, syncAfter);
}
else if( syncAfter || GET_P4REGPTR()->GetClearAndReload()
|| AfxMessageBox(IDS_YOU_HAVE_UPDATED_YOUR_CLIENT_WORKSPACE__CLEAR_AND_RELOAD,
MB_YESNO |MB_ICONQUESTION ) == IDYES )
{
if (syncAfter)
chainedCommand = SyncAfter(key, syncAfter);
else
{
int key= pCmd->HaveServerLock() ? pCmd->GetServerKey() : 0;
MainFrame()->UpdateDepotandChangeViews(REDRILL, key);
chainedCommand=TRUE;
}
}
if (GET_SERVERLEVEL() >= 22)
TheApp()->Set_m_ClientSubOpts(TheApp()->GetClientSpecField( _T("SubmitOptions"), pCmd->GetSpecOut()));
}
else
{
if ( m_pNewSpec )
delete m_pNewSpec;
if (lParam == IDCANCEL && pCmd->GetIsRequestingNew())
{
m_Active = pCmd->GetOldClient(); // switch back to the previous client
GET_P4REGPTR()->SetP4Client( m_Active, TRUE, FALSE, FALSE);
MainFrame()->UpdateCaption( );
}
}
if (lParam != IDABORT)
{
MainFrame()->ClearStatus();
if (!chainedCommand && pCmd->HaveServerLock())
pCmd->ReleaseServerLock();
CDialog *dlg = (CDialog *)pCmd->GetSpecSheet();
dlg->DestroyWindow();
}
delete pCmd;
m_EditInProgress = FALSE;
if (need2Refresh && !chainedCommand)
OnViewUpdate();
if (TheApp()->m_RunClientWizOnly && !chainedCommand)
::PostMessage(MainFrame()->m_hWnd, WM_COMMAND, ID_APP_EXIT, 0);
return 0;
}
// After a client spec has been update, this may get called to sync the client
BOOL CClientListCtrl::SyncAfter(int key, int syncAfter)
{
CCmd_Get *pCmd= new CCmd_Get;
pCmd->Init( m_hWnd, RUN_ASYNC, HOLD_LOCK, key);
m_AddToViewList.RemoveAll();
m_AddToViewList.AddHead(CString(syncAfter == SYNC_HEAD ? _T("#head") : _T("#have")));
if( pCmd->Run( &m_AddToViewList, FALSE, FALSE ) )
{
MainFrame()->UpdateStatus( LoadStringResource(IDS_FILE_SYNC) );
return TRUE;
}
else
{
delete pCmd;
return FALSE;
}
}
LRESULT CClientListCtrl::OnP4Sync(WPARAM wParam, LPARAM lParam)
{
CCmd_Get *pCmd= (CCmd_Get *) wParam;
if (TheApp()->m_RunClientWizOnly)
{
if (pCmd->GetWarningsCount() == 0)
{
pCmd->ReleaseServerLock();
::PostMessage(MainFrame()->m_hWnd, WM_COMMAND, ID_APP_EXIT, 0);
}
else
{
TheApp()->m_RunClientWizOnly = FALSE;
::ShowWindow(MainFrame()->m_hWnd, SW_RESTORE);
MainFrame()->UpdateDepotandChangeViews(REDRILL, pCmd->GetServerKey());
}
}
else
MainFrame()->UpdateDepotandChangeViews(REDRILL, pCmd->GetServerKey());
delete pCmd;
return 0;
}
/*
_________________________________________________________________
*/
LRESULT CClientListCtrl::OnP4ClientList(WPARAM wParam, LPARAM lParam)
{
CCmd_Clients *pCmd= (CCmd_Clients *) wParam;
if(!pCmd->GetError())
{
CString msg;
CObList const *clients= pCmd->GetList();
int count = clients->GetCount();
SetRedraw(FALSE);
int index = 0;
CString curclient = GET_P4REGPTR()->GetP4Client();
CString defclient = GET_P4REGPTR()->GetP4Client(TRUE);
CString user = GET_P4REGPTR()->GetP4User();
for(int subItem=0; subItem < CLIENT_MAXCOL; subItem++)
m_ListAll.column[subItem].SetSize(clients->GetCount(), 100);
for(POSITION pos= clients->GetHeadPosition(); pos != NULL; index++)
{
CP4Client *client=(CP4Client *) clients->GetNext(pos);
InsertClient(client, index, &curclient, &defclient, &user);
if ((index & 0x1FFF) == 0)
{
msg.FormatMessage(IDS_INSERTING_CLIENTS, count - index);
MainFrame()->UpdateStatus(msg);
}
}
SetRedraw(TRUE);
msg.FormatMessage( IDS_NUMBER_OF_CLIENTS_n, index );
AddToStatus( msg, SV_COMPLETION );
ReSort();
// Make sure previous item is re-selected
if(clients->GetCount() > 0)
{
int i = FindInList(m_Active.IsEmpty() ? GET_P4REGPTR()->GetP4Client() : m_Active);
if (i < 0) i=0;
SetItemState(i, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED);
EnsureVisible(i, FALSE);
}
CP4ListCtrl::SetUpdateDone();
// Notify the mainframe that we have finished getting the clients,
// 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, not in class
_________________________________________________________________
*/
int CClientListCtrl::OnCompareItems(LPARAM lParam1, LPARAM lParam2, int subItem)
{
ASSERT(lParam1 && lParam2);
CP4Client const *client1 = (CP4Client const *)lParam1;
CP4Client const *client2 = (CP4Client const *)lParam2;
CString txt1, txt2;
switch(subItem)
{
case CLIENT_NAME:
txt1 = client1->GetClientName();
txt2 = client2->GetClientName();
break;
case CLIENT_OWNER:
txt1 = client1->GetOwner();
txt2 = client2->GetOwner();
break;
case CLIENT_HOST:
txt1 = client1->GetHost();
txt2 = client2->GetHost();
break;
case CLIENT_ACCESSDATE:
txt1 = client1->GetDate();
txt2 = client2->GetDate();
ConvertDates( txt1, txt2 );
break;
case CLIENT_ROOT:
txt1 = client1->GetRoot();
txt2 = client2->GetRoot();
break;
case CLIENT_DESC:
txt1 = client1->GetDescription();
txt2 = client2->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;
}
/*
_________________________________________________________________
when creating a new client or switching to another one.
_________________________________________________________________
*/
BOOL CClientListCtrl::SetP4Client( BOOL bAlways )
{
// not that we'd ever get here... but if they are the same, there
// is nothing to do, so bail.
//
if ( !bAlways && ( m_Active == GET_P4REGPTR()->GetP4Client() ) )
return FALSE;
if (GET_P4REGPTR()->GetExpandFlag() == 1)
GET_P4REGPTR()->AddMRUPcuPath(MainFrame()->GetCurrentItemPath());
// okay, change the session's client.
// (either we're setting the active client back to the registered one
// after using another client, or we are officially resetting
// the registered client to the new active one.)
//
if( !GET_P4REGPTR()->SetP4Client( m_Active, TRUE, FALSE, FALSE ) )
{
AfxMessageBox(IDS_UNABLE_TO_WRITE_P4CLIENT_TO_THE_REGISTRY, MB_ICONEXCLAMATION);
m_Active = GET_P4REGPTR()->GetP4Client();
return FALSE;
}
MainFrame()->UpdateCaption( ) ;
return TRUE;
}
/*
_________________________________________________________________
*/
BOOL CClientListCtrl::AutoCreateClientSpec(LPCTSTR clientName, LPCTSTR clientRoot,
BOOL bEdit, BOOL bTmpl, LPCTSTR tmplate)
{
m_pNewSpec= new CP4Client;
CCmd_EditSpec *pCmd= new CCmd_EditSpec;
pCmd->Init(m_hWnd, RUN_ASYNC, HOLD_LOCK);
if (bTmpl && !(CString(GET_P4REGPTR()->GetLocalCliTemplate()).IsEmpty())
&& CString(tmplate) == CString(LOCALDEFTEMPLATE))
{
pCmd->SetUseLocalDefTmplate(TRUE);
bTmpl = FALSE;
bEdit = TRUE;
}
else
pCmd->SetNewClientRoot(clientRoot);
pCmd->SetAutoUpdateSpec(bEdit ? FALSE : TRUE);
BOOL b;
if (bTmpl)
b = pCmd->Run( P4CLIENT_SPEC, clientName, tmplate, m_pNewSpec );
else
b = pCmd->Run( P4CLIENT_SPEC, clientName, m_pNewSpec );
if( b )
{
MainFrame()->UpdateStatus( LoadStringResource(IDS_EDITING_CLIENT_SPEC) ) ;
return TRUE;
}
delete pCmd;
delete m_pNewSpec;
return FALSE;
}
void CClientListCtrl::OnEditSpec( LPCTSTR clientName, BOOL bUseDefTemplate /*=FALSE*/ )
{
if (m_EditInProgress)
{
CantEditRightNow(IDS_CLIENT);
return;
}
m_pNewSpec= new CP4Client;
CCmd_EditSpec *pCmd= new CCmd_EditSpec;
pCmd->Init( m_hWnd, RUN_ASYNC, HOLD_LOCK);
pCmd->SetUseLocalDefTmplate(bUseDefTemplate);
if( pCmd->Run( P4CLIENT_SPEC, clientName, m_pNewSpec ) )
MainFrame()->UpdateStatus( LoadStringResource(IDS_EDITING_CLIENT_SPEC) ) ;
else
{
delete pCmd;
delete m_pNewSpec;
}
}
void CClientListCtrl::OnEditTemplate( LPCTSTR templateName )
{
// Get a list of all clients, so the dialog can check
// for a bungle like trying to create a client that
// already exists
CStringList list;
int index=-1;
m_NewClicked=m_NewClient=FALSE;
if( GET_SERVERLEVEL() >= 6 )
list.AddHead( templateName );
else
{
while(1)
{
index=GetNextItem(index, LVNI_ALL);
if( index == -1)
break;
TCHAR str[ 1024 ];
GetItemText(index, 0, str, 1024 );
list.AddHead(str);
}
}
// Prompt for the new client name, using p4client as a
// default value
CTemplateNameDlg dlg;
dlg.SetTemplateName(templateName);
dlg.SetVerbotenSpecNames(&list);
dlg.SetNewSpecName(GET_P4REGPTR()->GetP4Client( ));
dlg.SetSpecType( P4CLIENT_SPEC );
if(dlg.DoModal() != IDCANCEL)
{
CString saveActive = m_Active;
m_Active = dlg.GetNewSpecName(); //set and switch to new client
if (SetP4Client( TRUE ))
{
m_pNewSpec= new CP4Client;
CCmd_EditSpec *pCmd= new CCmd_EditSpec;
pCmd->Init( m_hWnd, RUN_ASYNC, HOLD_LOCK);
if( pCmd->Run( P4CLIENT_SPEC, m_Active, templateName, m_pNewSpec ) )
{
MainFrame()->UpdateStatus( LoadStringResource(IDS_EDITING_CLIENT_SPEC) ) ;
m_NewClicked = m_NewClient = TRUE;
m_ClientNew = m_Active;
}
else
{
delete pCmd;
delete m_pNewSpec;
m_Active = saveActive;
SetP4Client( TRUE );
}
}
}
}
/////////////////////////////////////////////////////////////////////
// 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 CClientListCtrl::OnDragEnter(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point)
{
m_DropEffect=DROPEFFECT_NONE;
m_DragDataFormat=0;
CString fname;
// 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 left side of the view needs to be specified in depot syntax
if(SERVER_BUSY() || m_EditInProgress || GET_P4REGPTR( )->ShowEntireDepot( ) > SDF_DEPOT)
return DROPEFFECT_NONE;
if(pDataObject->IsDataAvailable( (unsigned short) m_CF_DEPOT))
{
m_DropEffect=DROPEFFECT_COPY;
m_DragDataFormat=m_CF_DEPOT;
}
return m_DropEffect;
}
DROPEFFECT CClientListCtrl::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 CClientListCtrl::OnDrop(COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point)
{
CString fname;
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, CLIENTVIEW, MAKELPARAM(point.x,point.y));
return TRUE;
}
// Return false, so depot window doesnt start a file-open operation
return FALSE;
}
int CClientListCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CP4ListCtrl::OnCreate(lpCreateStruct) == -1)
return -1;
CStringArray colnames;
colnames.Add ( LoadStringResource(IDS_CLIENT) );
colnames.Add ( LoadStringResource(IDS_OWNER) );
colnames.Add ( LoadStringResource(IDS_HOST) );
colnames.Add ( LoadStringResource(IDS_DATE) );
colnames.Add ( LoadStringResource(IDS_ROOT) );
colnames.Add ( LoadStringResource(IDS_DESCRIPTION) );
ASSERT( CLIENT_MAXCOL == colnames.GetSize( ) );
//FIXTHIS: default column widths should be in resource
int width[ CLIENT_MAXCOL ]={90,90,90,90,150,150};
RestoreSavedWidths(width, colnames.GetSize( ), sRegValue_ClientList );
InsertColumnHeaders( colnames, width );
return 0;
}
void CClientListCtrl::OnUpdateAddToClientView(CCmdUI* pCmdUI)
{
CString txt;
txt.FormatMessage(IDS_ADD_FILES_TO_CLIENT_s_VIEW, GET_P4REGPTR()->GetP4Client());
pCmdUI->SetText ( txt );
pCmdUI->Enable( !SERVER_BUSY() && !m_EditInProgress
&& GET_P4REGPTR()->ShowEntireDepot() <= SDF_DEPOT );
}
void CClientListCtrl::OnAddToClientView()
{
if( ! SERVER_BUSY() && IDYES == AfxMessageBox(IDS_CONFIRMADDTOVIEW, MB_YESNO|MB_ICONQUESTION))
{
::SendMessage(m_depotWnd, WM_GETSELLIST, (WPARAM) &m_AddToViewList, 0);
if(m_AddToViewList.GetCount() > 0)
{
OnClientEditmy();
}
}
}
BOOL CClientListCtrl::TryDragDrop( )
{
// Store the client this is from
m_DragFromItemName = GetSelectedItemText();
m_OLESource.DelayRenderData( (unsigned short) m_CF_CLIENT);
return m_OLESource.DoDragDrop(DROPEFFECT_COPY, &m_DragSourceRect, NULL)
== DROPEFFECT_NONE ? FALSE : TRUE;
}
void CClientListCtrl::OnNewClient(WPARAM wParam, LPARAM lParam)
{
if (!IsClear())
{
CString oldclient = wParam ? m_OldDefClient : m_OldCurClient;
CString newclient = GET_P4REGPTR()->GetP4Client((BOOL)wParam);
CString curclient = GET_P4REGPTR()->GetP4Client();
CString defclient = GET_P4REGPTR()->GetP4Client(TRUE);
LV_ITEM lvItem;
lvItem.mask = LVIF_IMAGE;
lvItem.iSubItem = 0;
lvItem.state = lvItem.stateMask = 0;
lvItem.iItem = FindInList(oldclient);
if(lvItem.iItem > -1)
{
lvItem.iImage = CP4ViewImageList::GetClientIndex(false,
oldclient == defclient);
SetItem(&lvItem );
}
lvItem.iItem = FindInList(newclient);
if(lvItem.iItem > -1)
{
lvItem.iImage = CP4ViewImageList::GetClientIndex(true,
newclient == defclient);
SetItem(&lvItem );
}
else if (GET_P4REGPTR()->GetClientFilteredFlags())
{
int index = FindInListAll(newclient);
if (index > -1)
{
CP4Client * client = new CP4Client;
client->Create(m_ListAll.column[CLIENT_NAME].GetAt(index),
m_ListAll.column[CLIENT_OWNER].GetAt(index),
m_ListAll.column[CLIENT_HOST].GetAt(index),
m_ListAll.column[CLIENT_ACCESSDATE].GetAt(index),
m_ListAll.column[CLIENT_ROOT].GetAt(index),
m_ListAll.column[CLIENT_DESC].GetAt(index));
m_ListAll.column[0].SetAt(index, _T("@@")); // Removes from list of all clients
InsertClient(client, GetItemCount(), &curclient, &defclient);
ReSort();
}
}
if (wParam)
m_OldDefClient = newclient;
else
m_OldCurClient = newclient;
}
}
void CClientListCtrl::OnPerforceOptions()
{
MainFrame()->OnPerforceOptions(TRUE, FALSE, IDS_PAGE_CLIENT);
}
void CClientListCtrl::OnUpdateDiff2Clients(CCmdUI* pCmdUI)
{
// For now this feature is permanently turned off
// Remove the 'FALSE' and the /* */ to turn on again
//
// However for now this feature just uses File > Diff 2
// If this is going out, the Client menu should have Diff 2
pCmdUI->Enable( FALSE /*!SERVER_BUSY()*/ );
}
void CClientListCtrl::OnDiff2Clients()
{
CDiff2ObjsDlg dlg;
dlg.m_Type = COMBO_CLIENT;
m_Active=GetSelectedItemText();
if (!m_Active.IsEmpty())
dlg.m_Edit1 = m_Active;
SET_APP_HALTED(TRUE);
int rc=dlg.DoModal();
SET_APP_HALTED(FALSE);
if (rc == IDOK)
{
CString x = "";
CCmd_Diff2 *pCmd= new CCmd_Diff2;
pCmd->Init( m_depotWnd, RUN_ASYNC);
pCmd->SetOutput2Dlg(GET_P4REGPTR()->Diff2InDialog());
if( pCmd->Run( _T("//...@") + dlg.m_Edit1, _T("//...@") + dlg.m_Edit2,
0, 0, x, x, FALSE, FALSE, TRUE) )
MainFrame()->UpdateStatus( LoadStringResource(IDS_DIFFING_FILES) );
else
delete pCmd;
}
}
void CClientListCtrl::OnUpdateFilterClients(CCmdUI* pCmdUI)
{
pCmdUI->Enable( MainFrame()->SetMenuIcon(pCmdUI, !SERVER_BUSY()) );
}
void CClientListCtrl::OnFilterClients()
{
CClientFilterDlg dlg;
if(dlg.DoModal() == IDCANCEL)
return;
OnViewUpdate();
}
void CClientListCtrl::OnUpdateClearClientFilter(CCmdUI* pCmdUI)
{
pCmdUI->Enable( MainFrame()->SetMenuIcon(pCmdUI, !SERVER_BUSY()
&& GET_P4REGPTR()->GetClientFilteredFlags()) );
}
void CClientListCtrl::OnClearClientFilter()
{
GET_P4REGPTR()->SetClientFilteredFlags(0);
OnViewUpdate();
}
| # | Change | User | Description | Committed | |
|---|---|---|---|---|---|
| #1 | 19924 | YourUncleBob |
Populate -o //guest/perforce_software/p4win/... //guest/YourUncleBob/p4win/..... |
||
| //guest/perforce_software/p4win/main/gui/ClientListCtrl.cpp | |||||
| #1 | 16169 | perforce_software | Move files to follow new path scheme for branches. | ||
| //guest/perforce_software/p4win/gui/ClientListCtrl.cpp | |||||
| #1 | 8562 | Matt Attaway |
These feet never stop running. Initial commit of the P4Win source code. To the best of our knowledge this compiles and runs using the 2013.3 P4 API and VS 2010. Expect a few changes as we refine the build process. Please post any build issues to the forums. |
||