FileSpecPage.cpp. #1

  • //
  • guest/
  • YourUncleBob/
  • p4win/
  • main/
  • gui/
  • IntegDlg/
  • FileSpecPage.cpp.
  • View
  • Commits
  • Open Download .zip Download (33 KB)
//
// 
// Copyright 1999 Perforce Software.  All rights reserved.
//
// This file is part of Perforce - the FAST SCM System.
//
//


// FileSpecPage.cpp : implementation file
//

#include "stdafx.h"
#include "..\p4win.h"
#include "FileSpecPage.h"
#include "IntegOptSheet.h"
#include "Cmd_Describe.h"
#include "MainFrm.h"
#include "..\hlp\p4win.hh"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define UPDATE_STATUS(x) ((CMainFrame *)AfxGetMainWnd())->UpdateStatus(x)

/////////////////////////////////////////////////////////////////////////////
// CIntegFileSpecPage property page

CIntegFileSpecPage::CIntegFileSpecPage(CWnd* pParent /*=NULL*/)
	: CDialog(CIntegFileSpecPage::IDD, pParent)
{
	//{{AFX_DATA_INIT(CIntegFileSpecPage)
	m_SourceSpecs = _T("");
	m_TargetSpecs = _T("");
	m_TargetSpecsAlt = _T("");
	m_IsNoCopy = GET_P4REGPTR()->GetIsNoCopy();
	m_IsPermitDelReadd = GET_P4REGPTR()->GetIsPermitDelReadd();
	m_DelReaddType = GET_SERVERLEVEL() > 16 ? GET_P4REGPTR()->GetDelReaddType() : 2;
	m_IsBaselessMerge = GET_P4REGPTR()->GetIsBaselessMerge();
	m_IsIndirectMerge = FALSE;
	m_IsPropagateTypes = GET_P4REGPTR()->GetIsPropagateTypes();
	m_IsBaseViaDelReadd = GET_P4REGPTR()->GetIsBaseViaDelReadd();
	m_IsForceInteg = GET_P4REGPTR()->GetIsForceInteg();;
	m_IsForceDirect = GET_P4REGPTR()->GetIsForceDirect();;
	m_IsDeleteSource = GET_P4REGPTR()->GetIsDeleteSource();
	m_IsAutoSync = GET_P4REGPTR()->GetSyncFirstDefault();
	m_IsMappingReverse = FALSE;
	m_IsChgListInteg = FALSE;
	m_ReverseInteg = FALSE;
	m_BranchSpecs = _T("");
	//}}AFX_DATA_INIT

	m_ChangeNbr = 0;
	m_RevRangeFromFlag = m_RevRangeToFlag = 0;
	m_RevRangeFromType = m_RevRangeToType = 0;
	m_SetBranch= FALSE;
	m_Initialized= FALSE;
	m_IsMinimized= FALSE;
	m_IsSourceSpecified= FALSE;
	m_HaveSwappedAlready= FALSE;
	m_BiDir = FALSE;
	m_ChangeNum= 0;
	m_NewChangeNbr= 0;
	m_CommonPath = _T("");
	m_InitRect.SetRect(0,0,100,100);
	m_WinPos.SetWindow( this, _T("IntegDlg") );
}

CIntegFileSpecPage::~CIntegFileSpecPage()
{
}

void CIntegFileSpecPage::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CIntegFileSpecPage)
	DDX_Text(pDX, IDC_SOURCESPECS, m_SourceSpecs);
	DDX_Text(pDX, IDC_TARGETSPECS, m_TargetSpecs);
	DDX_Text(pDX, IDC_TARGETSPECS_ALT, m_TargetSpecsAlt);
	DDX_Control(pDX, IDC_CHANGECOMBO, m_ChangeCombo);
	DDX_Check(pDX, IDC_REVERSEINTEG, m_ReverseInteg);
	DDX_Text(pDX, IDC_BRANCHSPECS, m_BranchSpecs);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CIntegFileSpecPage, CDialog)
	//{{AFX_MSG_MAP(CIntegFileSpecPage)
	ON_BN_CLICKED(IDC_SOURCERADIO, OnSourceradio)
	ON_BN_CLICKED(IDC_TARGETRADIO, OnTargetradio)
	ON_BN_CLICKED(IDC_REVERSEINTEG, OnReverseInteg)
	ON_BN_CLICKED(IDC_ADVOPTS, OnAdvancedOptions)
	ON_BN_CLICKED(IDC_PREVIEW, OnPreview)
	ON_COMMAND(IDC_BACK, OnWizardBack)
	ON_COMMAND(IDC_FINISH, OnOK)
	ON_COMMAND(IDCANCEL, OnWizardCancel)
	ON_COMMAND(IDHELP, OnHelp)
	ON_WM_HELPINFO()
	ON_WM_GETMINMAXINFO()
	ON_WM_SIZE()
	ON_WM_DESTROY()
	ON_WM_SYSCOMMAND()
	//}}AFX_MSG_MAP
	ON_MESSAGE( WM_GOTODLGCTRL, OnGotoDlgCtrl)
	ON_MESSAGE( WM_ENABLEDISABLE, OnEnableDisableButtons)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CIntegFileSpecPage message handlers

void CIntegFileSpecPage::SetBranchMode( BOOL isSourceSpecified )
{
	ASSERT( m_IsBranch );

	if( m_Initialized )
	{
		UpdateData();

		if( isSourceSpecified )
		{
			ShowAlternateEditControls( BRANCH_FROMSOURCE );
			GetDlgItem( IDC_SOURCESPECS )->EnableWindow( TRUE );
		}
		else
		{
			ShowAlternateEditControls( BRANCH_FROMTARGET );
			GetDlgItem( IDC_TARGETSPECS_ALT )->EnableWindow( TRUE );
		}

		if( m_HaveSwappedAlready || isSourceSpecified == TRUE )
		{
			if( isSourceSpecified )
			{
				// Target was previously specified
				m_SourceSpecs= m_TargetSpecsAlt;
				m_TargetSpecsAlt= "//...";
			}
			else
			{
				// Source was previously specified
				m_TargetSpecsAlt= m_SourceSpecs;
				m_SourceSpecs= "//...";
			}
			m_HaveSwappedAlready= TRUE;
			UpdateData(FALSE);
		}
	}

	m_IsSourceSpecified= isSourceSpecified;
}

void CIntegFileSpecPage::SetSourceSpecs( CStringList *list )
{
	ASSERT(!m_Initialized);
	ASSERT(m_SetBranch);

	PutListInText( m_SourceSpecs, list );
}

void CIntegFileSpecPage::SetTargetSpecs( CStringList *list )
{
	ASSERT(!m_Initialized);
	ASSERT(m_SetBranch);

	if( m_IsBranch )
		PutListInText( m_TargetSpecsAlt, list );
	else
		PutListInText( m_TargetSpecs, list );
}

CStringList *CIntegFileSpecPage::GetSourceList()
{
	ASSERT(m_Initialized);
	if( IsWindow( m_hWnd ) )
		UpdateData();

	PutTextInList( m_SourceSpecs, &m_SourceSpecList );

	return &m_SourceSpecList;
}

CStringList *CIntegFileSpecPage::GetTargetList()
{
	ASSERT(m_Initialized);
	if( IsWindow( m_hWnd ) )
		UpdateData();

	if( m_IsBranch )
		PutTextInList( m_TargetSpecsAlt, &m_TargetSpecList );
	else
		PutTextInList( m_TargetSpecs, &m_TargetSpecList );

	return &m_TargetSpecList;
}

void CIntegFileSpecPage::PutListInText( CString &text, CStringList *list )
{
	text.Empty();
	for( POSITION pos= list->GetHeadPosition(); pos != NULL; )
	{
		if( !text.IsEmpty() )
			text+= "\r\n";
		text+= list->GetNext( pos );
	}
}

void CIntegFileSpecPage::PutTextInList( CString &text, CStringList *list )
{
	list->RemoveAll();
	if( !text.IsEmpty() )
	{
		CString line;

		for( int i=0; i<text.GetLength(); i++ )
		{
			switch( text[i] )
			{
			case '\r':
				break;
			case '\n':
				list->AddHead( line );
				line.Empty();
				break;
			default:
				line+= text[i];
			}
		}
		if( !line.IsEmpty() )
		{
			if (line.Find(_T("//"), 2) != -1)
				m_2FilesOnLine = line;
			list->AddHead( line );
		}
	}
}

#define MAX_LINE_LEN 1024

void CIntegFileSpecPage::LoadBranchView(void)
{
	CCmd_Describe *pCmd = new CCmd_Describe;
	pCmd->Init( m_hWnd, RUN_SYNC );
	if( pCmd->Run( P4BRANCH_SPEC, m_BranchName ) 
	 && !pCmd->GetError())
	{
		LPTSTR	p;
		LPTSTR	q;
		CString m_Description = pCmd->GetDescription();
		for (p = q = m_Description.GetBuffer( m_Description.GetLength( ) ); *p == _T('#'); ++p)
		{
			while (*++p != _T('\n'))
				;
		}
		p = q + m_Description.Find(_T("\nView:\n"), p - q) + sizeof(_T("\nView:\n"))/sizeof(TCHAR) - 1;
		while (*p)
		{
			if ((TBYTE)(*p) <= _T(' '))
				p++;
			else
				break;
		}
		m_BranchSpecs.Empty();
		while (*p)
		{
			if (*p == _T('\t'))
			{
				++p;
				continue;
			}
			else if (*p == _T(' '))
				m_BranchSpecs += _T(' ');
			else if (*p == _T('\n'))
				m_BranchSpecs += _T('\r');
			m_BranchSpecs += *p++;
		}
    }
	else
	{
	 	m_BranchSpecs.FormatMessage(IDS_UNABLE_TO_OBTAIN_BRANCHSPEC_FOR_s, m_BranchName);
	}
	UpdateData(FALSE);
		
	delete pCmd;
	return;
}

BOOL CIntegFileSpecPage::OnInitDialog() 
{
	CDialog::OnInitDialog();

	MainFrame()->SetModelessWnd(this);

	// Record the initial window size, then see if there is a registry preference
	GetWindowRect(&m_InitRect);
	m_LastRect = m_InitRect;

	UpdateData(FALSE);

	// Record positions of primary controls
	CRect rect;
	GetClientRect( &rect );
	int h = rect.Height();
	GetWindowRect( &rect );
	h = rect.Height() - h;
	GetDlgItem( IDC_LABELSOURCE )->GetWindowRect( &m_RectLabelSource );
	GetDlgItem( IDC_SOURCESPECS )->GetWindowRect( &m_RectSource );
	GetDlgItem( IDC_LABELTARGET )->GetWindowRect( &m_RectLabelTarget );
	GetDlgItem( IDC_TARGETSPECS )->GetWindowRect( &m_RectTarget );
	m_RectLabelSource.OffsetRect( -rect.left, -rect.top-h );
	m_RectSource.OffsetRect( -rect.left, -rect.top-h );
	m_RectLabelTarget.OffsetRect( -rect.left, -rect.top-h );
	m_RectTarget.OffsetRect( -rect.left, -rect.top-h );

	// Computer positions of alternate controls
	if( m_IsBranch )
	{
		// In branch mode, bottom of Source = bottom of Target
		m_RectSource.bottom= m_RectTarget.bottom;
		// Branch View takes same space as Source's top, left, right
		m_RectBranch= m_RectSource;

		if (m_BranchFlag == INTEG_USING_BRANCH)
		{
			// if coming from branch pane, hide source and target controls
			GetDlgItem(  IDC_LABELTARGET  )->ModifyStyle( WS_VISIBLE, 0 );
			GetDlgItem(  IDC_TARGETSPECS  )->ModifyStyle( WS_VISIBLE, 0 );
			GetDlgItem(  IDC_LABELSOURCE  )->ModifyStyle( WS_VISIBLE, 0 );
			GetDlgItem(  IDC_SOURCESPECS  )->ModifyStyle( WS_VISIBLE, 0 );
			GetDlgItem(IDC_TARGETSPECS_ALT)->ModifyStyle( WS_VISIBLE, 0 );

			// And show the Reverse Integ checkbox
			GetDlgItem(IDC_REVERSEINTEG)->ModifyStyle( 0, WS_VISIBLE );
		}
		else
		{
			// Diasable or Show the radio buttons
			if (m_IsChgListInteg)
			{
				GetDlgItem( IDC_SOURCERADIO )->EnableWindow(FALSE);
				GetDlgItem( IDC_TARGETRADIO )->EnableWindow(FALSE);
			}
			else
			{
				GetDlgItem( IDC_SOURCERADIO )->ModifyStyle( 0, WS_VISIBLE );
				GetDlgItem( IDC_TARGETRADIO )->ModifyStyle( 0, WS_VISIBLE );
				GetDlgItem( IDC_SOURCERADIO )->GetWindowRect( &m_RectSourceRadio );
				GetDlgItem( IDC_TARGETRADIO )->GetWindowRect( &m_RectTargetRadio );
				m_RectSourceRadio.OffsetRect( -rect.left, -rect.top-h );
				m_RectTargetRadio.OffsetRect( -rect.left, -rect.top-h );
			}

			// shrink branchview to top half, show target/source controls in bottom half
			if (m_IsChgListInteg)
			{
				GetDlgItem( IDC_SOURCESPECS )->ModifyStyle( WS_VISIBLE, 0 );
				CWnd *pWnd = GetDlgItem(IDC_STATIC_1);
				pWnd->GetWindowRect(&rect);
			}
			else
				m_RectBranch.bottom = m_RectBranch.bottom / 2 + 6;
			m_RectSourceRadio.OffsetRect( 0, m_RectBranch.bottom - m_RectLabelSource.top + 10);
			m_RectTargetRadio.OffsetRect( 0, m_RectBranch.bottom - m_RectLabelSource.top + 10);
			m_RectLabelSource.OffsetRect( 0, m_RectBranch.bottom - m_RectLabelSource.top + 10);
			GetDlgItem( IDC_SOURCERADIO )->MoveWindow( m_RectSourceRadio, FALSE );
			GetDlgItem( IDC_TARGETRADIO )->MoveWindow( m_RectTargetRadio, FALSE );
			GetDlgItem( IDC_LABELSOURCE )->MoveWindow( m_RectLabelSource, FALSE );
			m_RectSource.top += m_RectBranch.Height() + m_RectLabelSource.Height() + 14;

			// In branch mode, both multiline edits take same space
			m_RectTarget= m_RectSource;
			m_RectLabelTarget= m_RectLabelSource;

			// Target is always the default
			((CButton *) GetDlgItem(IDC_TARGETRADIO))->SetCheck( 1 );

			// Relabel the multiline edits
			if (m_IsChgListInteg)
				GetDlgItem( IDC_LABELSOURCE )->ModifyStyle( WS_VISIBLE, 0 );
			else
				SetDlgItemText( IDC_LABELSOURCE, LoadStringResource(IDS_FILE_SPECIFICATIONS__INTEGRATE) );
			SetDlgItemText( IDC_LABELTARGET, LoadStringResource(IDS_FILE_SPECIFICATIONS__INTEGRATE) );
		}
		GetDlgItem( IDC_BRANCHSPECS )->MoveWindow( m_RectBranch, FALSE );
		GetDlgItem( IDC_BRANCHSPECS )->ModifyStyle( 0, WS_VISIBLE );
		GetDlgItem( IDC_LABELBRANCH )->ModifyStyle( 0, WS_VISIBLE );
	}
			
	m_Initialized= TRUE;

	if( m_IsBranch )
	{
		SetBranchMode( m_IsSourceSpecified );
		m_LastSelectedTarget= TRUE;

		if( GET_SERVERLEVEL() < LEVEL_NEWINTEG )
		{
			if (m_BranchFlag != INTEG_USING_BRANCH)
			{
				// Pre-99.1 server doesnt allow source-spec for branch
				GetDlgItem(IDC_SOURCERADIO)->EnableWindow(FALSE);
				GetDlgItem(IDC_TARGETRADIO)->EnableWindow(FALSE);
			}
		}
		else
		{
			::SendMessage(GetDlgItem(IDC_TARGETRADIO)->m_hWnd, BM_SETCHECK, BST_UNCHECKED, 0);
			::SendMessage(GetDlgItem(IDC_SOURCERADIO)->m_hWnd, BM_SETCHECK, BST_CHECKED, 0);
			OnSourceradio();
		}
	}
	else
	{
		// If not branch, set alternate windows visible
		ShowAlternateEditControls( FILESPEC );

		// And make sure both are enabled
		GetDlgItem( IDC_SOURCESPECS )->EnableWindow(TRUE);
		GetDlgItem( IDC_TARGETSPECS_ALT )->EnableWindow(TRUE);

		m_targetspecs.SubclassDlgItem(IDC_TARGETSPECS, this);
		m_targetspecs.SetParent(this);
		m_targetspecs.m_pDropTgt = new CEBDropTarget();
		m_targetspecs.m_pDropTgt->Register(&m_targetspecs);
		m_targetspecs.m_pDropTgt->m_Owner = &m_targetspecs;
		m_targetspecs.m_SpecType = 0;

		m_IsSourceSpecified= TRUE;
	}
	
	if (m_ChangeNbr)	// are we integrating from a changlist?
	{
		m_RevRangeFrom.Format(_T("%d"), m_ChangeNbr);
		m_RevRangeTo.Format(_T("%d"), m_ChangeNbr);
		m_RevRangeFromFlag = m_RevRangeToFlag = 2;
		m_ChangeNbr = 0;	// so we won't overwrite any of the user's changes
	}
	
	UpdateChangesControl();

	if (m_IsRename)
	{
		GetDlgItem(IDC_ADVOPTS)->ShowWindow(SW_HIDE);
		SetDlgItemText( IDC_LABELSOURCE, 
			LoadStringResource(IDS_FILE_SPECIFICATIONS__RENAME__ORIGINAL_NAMES) );
		SetDlgItemText( IDC_LABELTARGET, 
			LoadStringResource(IDS_FILE_SPECIFICATIONS__RENAME__NEW_NAMES) );
	}

	if( m_BranchFlag != INTEG_USING_BRANCH_SPEC )
	{
		GetDlgItem(IDC_BACK)->EnableWindow( FALSE );
		GetDlgItem(IDC_BACK)->ShowWindow( SW_HIDE );
		GetDlgItem(IDC_FINISH)->SetWindowText( LoadStringResource(IDS_OK) );
	}

	if (m_IsBranch)
	{
		// Load the BranchView with the BranchSpecs
		LoadBranchView();

		// Add branch name to dialog box title
        CString title;
        title.FormatMessage(IDS_FILE_INTEGRATE_USING_BRANCHSPEC_s, m_BranchName);
		SetWindowText(title);
	}
	else if (m_IsRename)
	{
		// Change the dialog box title to indicate we are renaming
		SetWindowText(LoadStringResource(IDS_FILE_RENAME_TITLE));
		PostMessage(WM_GOTODLGCTRL, IDC_TARGETSPECS, 0);
	}

	m_WinPos.RestoreWindowPosition();
	ShowWindow(SW_SHOW);

	if (m_IsBranch)
		GotoDlgCtrl( GetDlgItem(IDC_CHANGECOMBO) );
	else
		GotoDlgCtrl( GetDlgItem(IDC_TARGETSPECS) );

	return FALSE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

LRESULT CIntegFileSpecPage::OnGotoDlgCtrl(WPARAM wParam, LPARAM lParam)
{
	GotoDlgCtrl(GetDlgItem(wParam));
	return 0;
}


void CIntegFileSpecPage::ShowAlternateEditControls( ShowMode mode )
{
	// We might have changed the branch flag as a result of a Preview
	// so restore it so this routine will work correctly
	//
	m_BranchFlag = m_SaveBranchFlag;

	switch( mode )
	{
	case BRANCH_FROMSOURCE:
		// Show source edit control and hide target
		if (m_BranchFlag != INTEG_USING_BRANCH)
		{
			if (!m_IsChgListInteg)
			{
				GetDlgItem( IDC_SOURCESPECS )->MoveWindow( m_RectSource, FALSE );
				GetDlgItem( IDC_SOURCESPECS )->ModifyStyle( 0, WS_VISIBLE );
				GetDlgItem( IDC_LABELSOURCE )->ModifyStyle( 0, WS_VISIBLE );
			}
		}

		// Hide target edit controls and label
		GetDlgItem( IDC_LABELTARGET )->ModifyStyle( WS_VISIBLE, 0 );
		GetDlgItem( IDC_TARGETSPECS_ALT )->ModifyStyle( WS_VISIBLE, 0 );
		GetDlgItem( IDC_TARGETSPECS )->ModifyStyle( WS_VISIBLE, 0 );

		break;

	case BRANCH_FROMTARGET:
		// Show alternate target edit control (multiline)
		if (m_BranchFlag != INTEG_USING_BRANCH)
		{
			GetDlgItem( IDC_LABELTARGET )->MoveWindow( m_RectLabelTarget, FALSE );
			GetDlgItem( IDC_LABELTARGET )->ModifyStyle( 0, WS_VISIBLE );

			GetDlgItem( IDC_TARGETSPECS_ALT )->MoveWindow( m_RectTarget, FALSE );
			GetDlgItem( IDC_TARGETSPECS_ALT )->ModifyStyle( 0, WS_VISIBLE );
		
			// Hide source edit control and standard target edit control
			GetDlgItem( IDC_LABELSOURCE )->ModifyStyle( WS_VISIBLE, 0 );
			GetDlgItem( IDC_SOURCESPECS )->ModifyStyle( WS_VISIBLE, 0 );
			GetDlgItem( IDC_TARGETSPECS )->ModifyStyle( WS_VISIBLE, 0 );
		}

		break;

	case FILESPEC:
		// Leave the default edit controls in default positions
		GetDlgItem( IDC_LABELSOURCE )->MoveWindow( m_RectLabelSource, FALSE );
		GetDlgItem( IDC_SOURCESPECS )->MoveWindow( m_RectSource, FALSE );
		GetDlgItem( IDC_SOURCESPECS )->ModifyStyle( 0, WS_VISIBLE );
		
		GetDlgItem( IDC_LABELTARGET )->MoveWindow( m_RectLabelTarget, FALSE );
		GetDlgItem( IDC_TARGETSPECS )->ModifyStyle( 0, WS_VISIBLE );

		// Hide alternate target edit control
		GetDlgItem( IDC_TARGETSPECS_ALT )->ModifyStyle( WS_VISIBLE, 0 );

		break;

	default:
		ASSERT(0);
	}
	RedrawWindow();
}

void CIntegFileSpecPage::OnWizardBack() 
{
	m_WinPos.SaveWindowPosition();

	::PostMessage(m_DepotWnd, WM_DOINTEGRATE1, (WPARAM)ID_WIZBACK, 0);
}

void CIntegFileSpecPage::OnWizardCancel() 
{
	m_WinPos.SaveWindowPosition();

	::PostMessage(m_DepotWnd, WM_DOINTEGRATE1, 0, 0);
}

void CIntegFileSpecPage::OnPreview() 
{
	m_Previewing = TRUE;
	if( SERVER_BUSY() || !OnSetInactive() )
		return;

	m_IsPreview = TRUE;
	::PostMessage(m_DepotWnd, WM_DOINTEGRATE1, (WPARAM)ID_WIZFINISH, 0);
}

void CIntegFileSpecPage::OnOK() 
{
	m_WinPos.SaveWindowPosition();

	m_Previewing = FALSE;
	if( SERVER_BUSY() || !OnSetInactive() )
		return;

	m_IsPreview = FALSE;
	::PostMessage(m_DepotWnd, WM_DOINTEGRATE1, (WPARAM)ID_WIZFINISH, 0);
}

// This signals the closing of a modeless
// dialog to MainFrame which
// will delete the 'this' object
void CIntegFileSpecPage::OnDestroy()
{
	::PostMessage(MainFrame()->m_hWnd, WM_P4DLGDESTROY, 0, (LPARAM)this);
}

BOOL CIntegFileSpecPage::CheckForAllOK()
{
	if ((!m_IsSourceSpecified && (GetTargetList()->GetCount()==1) && (m_TargetSpecsAlt=="//..."))
	  || (m_IsSourceSpecified && (GetSourceList()->GetCount()==1) && (m_SourceSpecs=="//...")))
	{
		if (IDYES != AfxMessageBox(IDS_YOU_HAVE_ENTERED_THE_ALL_ENCOMPASSING_FILESPEC,
								MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON2))
			return FALSE;
	}
	return TRUE;
}


BOOL CIntegFileSpecPage::OnSetInactive()
{
	m_2FilesOnLine.Empty();
	UpdateData();

	// We might have changed the branch flag as a result of a Preview
	// so restore it so this will work correctly
	//
	m_BranchFlag = m_SaveBranchFlag;

	m_RevRange.Empty();
	if  (m_RevRangeFromFlag || m_RevRangeToFlag)
	{
		switch(m_RevRangeFromFlag)
		{
		case 0:
			break;
		case 1:
			m_RevRange = _T('#') + m_RevRangeFrom + _T(',');
			break;
		case 2:
			m_RevRange = _T('@') + m_RevRangeFrom + _T(',');
			break;
		default:
			ASSERT(0);
			break;
		}
		switch(m_RevRangeToFlag)
		{
		case 0:
			m_RevRange += _T("#head");
			break;
		case 1:
			m_RevRange += _T('#') + m_RevRangeTo;
			break;
		case 2:
			m_RevRange += _T('@') + m_RevRangeTo;
			break;
		default:
			ASSERT(0);
			break;
		}
	}

	switch( m_BranchFlag )
	{
	case INTEG_USING_FILE_SPEC:
	{
		CString findwhat = m_TargetSpecs.GetAt(0) == _T('/') ? _T("/...") : _T("\\...");
		if( GetSourceList()->GetCount() > 1 && 
			m_TargetSpecs.Find(findwhat) != m_TargetSpecs.GetLength()-4 )
		{
			AfxMessageBox( IDS_TARGET_FILESPEC_MUST_END_IN_WILDCARD, MB_ICONEXCLAMATION);
			return FALSE;
		}
		m_SourceSpecs.Trim();
		m_TargetSpecs.Trim();
		if (m_SourceSpecs == m_TargetSpecs)
		{
			AfxMessageBox( IDS_SOURCE_TARGET_FILESPECS_MAY_NOT_BE_IDENTICAL, MB_ICONEXCLAMATION);
			return FALSE;
		}
		if ((m_SourceSpecs.FindOneOf(_T("@#")) != -1) || (m_TargetSpecs.FindOneOf(_T("@#")) != -1))
		{
			AfxMessageBox(IDS_CANT_USE_REVRANGE_HERE_USE_OPTIONS, MB_ICONEXCLAMATION);
			return FALSE;
		}
		if (m_SourceSpecs.IsEmpty() || m_TargetSpecs.IsEmpty())
		{
			AfxMessageBox(IDS_NEITHER_SRC_OR_TARG_MAY_BE_EMPTY, MB_ICONEXCLAMATION);
			return FALSE;
		}
		if (m_IsRename && IS_NOCASE() && (GetSourceList()->GetCount()==1)
			&& !GetSourceList()->GetHead().CompareNoCase(GetTargetList()->GetHead()))
		{
			AfxMessageBox(IDS_CANT_RENAME_TO_CHANGE_CASE, MB_ICONEXCLAMATION);
			return FALSE;
		}
		if (m_TargetSpecs.GetAt(0) == _T('/') && m_TargetSpecs.Find(_T('\\')) != -1)
		{
			if (AfxMessageBox(IDS_BACKSLASHINDEPOTSYNTAX, MB_YESNO|MB_ICONQUESTION ) != IDYES)
				return FALSE;
		}
		break;
	}
	case INTEG_USING_BRANCH_SPEC:
		m_SaveBranchFlag = m_BranchFlag;	// we will need to restore if this is a Preview
		if( GetSourceList()->GetCount() && !GetTargetList()->GetCount() )
		{
			m_SourceSpecs.Empty();
			m_BranchFlag = INTEG_USING_BRANCH;
			m_IsMappingReverse = m_ReverseInteg = m_IsChgListInteg;
			break;
		}
		if( !GetSourceList()->GetCount() && GetTargetList()->GetCount() )
		{
			m_TargetSpecsAlt.Empty();
			m_BranchFlag = INTEG_USING_BRANCH;
			m_IsMappingReverse = m_ReverseInteg = !m_IsChgListInteg;
			m_BiDir = m_IsChgListInteg;
			break;
		}
		if (!CheckForAllOK())
			return FALSE;
		if( !GetSourceList()->GetCount() && !GetTargetList()->GetCount() )	// shouldn't happen (?)
		{
			AfxMessageBox( IDS_NO_FILES_SPECIFIED_NOTHING_TO_DO, MB_ICONEXCLAMATION);
			return FALSE;
		}
		break;
	case INTEG_USING_BRANCH:
		GetSourceList();		// called only to check m_2FilesOnLine
		m_SourceSpecs.Empty();
		break;
	}

	if (!m_2FilesOnLine.IsEmpty())
	{
		CString txt;
		txt.FormatMessage(IDS_CANTHAVE2FILESON1LINE, m_2FilesOnLine);
		AfxMessageBox(txt, MB_ICONSTOP);
		return FALSE;
	}

	// Looks good, so obtain the change number.
	// We wait until here so that we don't use up
	// a new change number for bad data
	// when the user wants a new changelist.
	m_ChangeNum= GetChangeNum();
	if (m_ChangeNum == -1)
		return FALSE;
	
	return TRUE;
}

void CIntegFileSpecPage::SetChangesList( CStringList *list )
{
	m_pChangeList= list;
}

void CIntegFileSpecPage::UpdateChangesControl()
{
	ASSERT( m_Initialized );
	ASSERT( m_pChangeList != NULL );
	
	// Make sure the combo is empty
	m_ChangeCombo.Clear();

	// Then fill it
	POSITION pos= m_pChangeList->GetHeadPosition();
	while( pos != NULL )
	{
		CString txt= m_pChangeList->GetNext(pos);
		m_ChangeCombo.AddString( txt );
	}

	// Select the first item (but 2nd item for rename or if Option is for New)
	if (m_IsRename)
		m_ChangeCombo.SetCurSel(GET_P4REGPTR()->GetUseNewChglist2() ? 1 : 0);
	else
		m_ChangeCombo.SetCurSel(GET_P4REGPTR()->GetUseNewChglist() ? 1 : 0);
}

int CIntegFileSpecPage::GetChangeNum()
{
	if( IsWindow( m_hWnd ) )
	{
		// Get the target change number
		CString tmp;
		int changeNum=0;
	
		if((m_ChangeCombo.GetCurSel() >= 0) && !m_Previewing)
		{
			m_ChangeCombo.GetLBText(m_ChangeCombo.GetCurSel(), tmp);
			if(tmp.Compare(LoadStringResource(IDS_NEWCHANGELISTNAME)) == 0)
			{
				CString description;
				CString *pDesc = NULL;
				BOOL autoOK=FALSE;

				if (!m_NewChangeNbr && m_IsRename)
				{
					description = LoadStringResource(IDS_RENAME_RENAME)
								+ m_SourceSpecs 
								+ LoadStringResource(IDS_RENAME_TO) 
								+ m_TargetSpecs;
					description.Replace(_T('\n'), _T(' '));
					pDesc = &description;
					autoOK= TRUE;
				}
				changeNum= (m_NewChangeNbr > 0) ? m_NewChangeNbr 
							: m_NewChangeNbr = MainFrame()->CreateNewChangeList(0, pDesc, autoOK);
			}
			else if(tmp.Compare(LoadStringResource(IDS_DEFAULTCHANGELISTNAME)) != 0)
				changeNum= _ttol(tmp);
		}
		return changeNum;
	}
	else
		return m_ChangeNum;
}

void CIntegFileSpecPage::OnSourceradio()
{
	if( m_LastSelectedTarget )
	{
		SetBranchMode( TRUE );
		m_LastSelectedTarget= FALSE;
	}
}

void CIntegFileSpecPage::OnTargetradio()
{
	if( !m_LastSelectedTarget )
	{
		SetBranchMode( FALSE );
		m_LastSelectedTarget= TRUE;
	}
}

void CIntegFileSpecPage::OnReverseInteg() 
{
	UpdateData();
	m_IsMappingReverse = m_ReverseInteg;
}

void CIntegFileSpecPage::OnAdvancedOptions() 
{
	// We might have changed the branch flag as a result of a Preview
	// so restore it so this will work correctly
	//
	m_BranchFlag = m_SaveBranchFlag;

	CIntegOptSheet dlg(LoadStringResource(IDS_FILE_INTEGRATE_ADVANCED_OPTIONS), this, 0);

	dlg.m_OptsPage.SetIsDefOpts( FALSE );
	dlg.m_OptsPage.SetIsBranch( m_IsBranch );
	dlg.m_OptsPage.SetBranchFlag( m_BranchFlag );
	dlg.m_OptsPage.SetIsNoCopy( m_IsNoCopy );
	dlg.m_OptsPage.SetIsSyncFirst( m_IsAutoSync );
	dlg.m_OptsPage.SetIsPermitDelReadd( m_IsPermitDelReadd );
	dlg.m_OptsPage.SetDelReaddType( m_DelReaddType );
	dlg.m_OptsPage.SetIsBaselessMerge( m_IsBaselessMerge );
	dlg.m_OptsPage.SetIsIndirectMerge( m_IsIndirectMerge );
	dlg.m_OptsPage.SetIsPropagateTypes( m_IsPropagateTypes );
	dlg.m_OptsPage.SetIsBaseViaDelReadd( m_IsBaseViaDelReadd );
	dlg.m_OptsPage.SetIsForceInteg( m_IsForceInteg );
	dlg.m_OptsPage.SetIsForceDirect( m_IsForceDirect );
	dlg.m_OptsPage.SetIsDeleteSource( m_IsDeleteSource );
	dlg.m_OptsPage.SetIsMappingReverse( m_IsMappingReverse );
	dlg.m_RevRngPage.SetRevRangeFrom( m_RevRangeFrom );
	dlg.m_RevRngPage.SetRevRangeTo( m_RevRangeTo );
	dlg.m_RevRngPage.SetRevRangeFromFlag( m_RevRangeFromFlag );
	dlg.m_RevRngPage.SetRevRangeToFlag( m_RevRangeToFlag );
	dlg.m_RevRngPage.SetRevRangeFromType( m_RevRangeFromType );
	dlg.m_RevRngPage.SetRevRangeToType( m_RevRangeToType );
	if (m_BranchFlag == INTEG_USING_BRANCH)
	{
		UpdateData();
		dlg.m_OptsPage.SetFileSpecs(m_LastSelectedTarget ? m_TargetSpecsAlt : m_SourceSpecs);
	}
	SET_APP_HALTED(TRUE);
	if( dlg.DoModal() == IDOK )
	{
		m_IsAutoSync       = dlg.m_OptsPage.IsSyncFirst();
		m_IsNoCopy         = dlg.m_OptsPage.IsNoCopy();
		m_IsPermitDelReadd = dlg.m_OptsPage.IsPermitDelReadd();
		m_DelReaddType     = dlg.m_OptsPage.DelReaddType();
		m_IsBaselessMerge  = dlg.m_OptsPage.IsBaselessMerge();
		m_IsIndirectMerge  = dlg.m_OptsPage.IsIndirectMerge();
		m_IsPropagateTypes = dlg.m_OptsPage.IsPropagateTypes();
		m_IsBaseViaDelReadd= dlg.m_OptsPage.IsBaseViaDelReadd();
		m_IsForceInteg     = dlg.m_OptsPage.IsForceInteg();
		m_IsForceDirect     = dlg.m_OptsPage.IsForceDirect();
		m_IsDeleteSource   = dlg.m_OptsPage.IsDeleteSource();
		m_IsMappingReverse = dlg.m_OptsPage.IsMappingReverse();
		m_RevRangeFrom     = dlg.m_RevRngPage.GetRevRangeFrom();
		m_RevRangeTo       = dlg.m_RevRngPage.GetRevRangeTo();
		m_RevRangeFromFlag = dlg.m_RevRngPage.GetRevRangeFromFlag();
		m_RevRangeToFlag   = dlg.m_RevRngPage.GetRevRangeToFlag();
		m_RevRangeFromType = dlg.m_RevRngPage.GetRevRangeFromType();
		m_RevRangeToType   = dlg.m_RevRngPage.GetRevRangeToType();
		if (m_BranchFlag == INTEG_USING_BRANCH)
		{
			if (m_LastSelectedTarget)
				m_TargetSpecsAlt = dlg.m_OptsPage.GetFileSpecs();
			else
				m_SourceSpecs = dlg.m_OptsPage.GetFileSpecs();
			UpdateData(FALSE);
		}
	}
	SET_APP_HALTED(FALSE);
}

void CIntegFileSpecPage::SetIsRename( BOOL isRename ) 
{
	if (isRename)
	{
		m_IsPropagateTypes = m_IsBaseViaDelReadd = m_IsPermitDelReadd = m_IsAutoSync
						   = m_IsForceInteg = m_IsDeleteSource = m_IsRename = TRUE;
		m_IsNoCopy = FALSE;
		m_DelReaddType = 2;
	}
	else
		m_IsRename = FALSE;
}

BOOL CIntegFileSpecPage::SetSpecList( CStringList *list )
{
	// We might have changed the branch flag as a result of a Preview
	// so restore it so this will work correctly
	//
	m_BranchFlag = m_SaveBranchFlag;

	if( m_IsBranch )
	{
		// We always assume that the supplied specs are targets, and only
		// set them to source at the user's request
		// We leave tagrets blank if request is from branch pane
		if (m_BranchFlag != INTEG_USING_BRANCH)
			SetTargetSpecs( list );

		CStringList sourceList;
		sourceList.AddHead( _T("//...") );

		SetSourceSpecs( &sourceList );
	}
	else
	{
		// The supplied list is source specs
		SetSourceSpecs( list );

		// Set the target spec
		CString commonPath = list->GetHead();
		TCHAR slashChar = commonPath.Find(_T('/')) != -1 ? _T('/') : _T('\\');

		// We want a directory (with no wildcard) for the common path
		// What we have is either a directory: //depot/dir1/dir2/...
		//                          or a file: //depot/dir1/dir2/filename.ext
		// In either case we want to remove the last / and everything after it
		int i;
		if( (i=commonPath.ReverseFind(slashChar)) != -1)
			commonPath = commonPath.Left(i);

		// Now walk the list and find the common path for all

		BOOL b = IS_NOCASE() || slashChar == _T('\\');
		for( POSITION pos = list->GetHeadPosition(); pos != NULL; )
		{
			CString item = list->GetNext( pos );
			do
			{
				int len = commonPath.GetLength();
				if (len <= item.GetLength())
				{
					if (b)
					{
						if (item.GetAt(len) == slashChar 
						 && commonPath.CompareNoCase(item.Left(len)) == 0)
							break;
					}
					else
					{
						if (item.GetAt(len) == slashChar 
						 && commonPath.Compare(item.Left(len)) == 0)
							break;
					}
				}
				if( (i=commonPath.ReverseFind(slashChar)) != -1)
					commonPath = commonPath.Left(i);
			} while (commonPath.GetLength() > 2);
		}
		if (commonPath.GetLength() <= 2)
		{
			AfxMessageBox(IDS_CANNTINTEGUNLESSCOMMONPATH, MB_ICONSTOP);
			return FALSE;
		}

		CStringList targetList;
		if (m_IsRename && list->GetCount() == 1)
			targetList.AddHead( list->GetHead() );
		else
			targetList.AddHead( commonPath + slashChar + _T("...") );

		SetTargetSpecs( &targetList );
		SetCommonPath(commonPath);
	}
	return TRUE;
}

LPCTSTR CIntegFileSpecPage::GetReference( )
{
	static CString ref;

	if( m_IsBranch )
		ref= GetBranchName();
	else
	{
		CStringList *list= GetTargetList();
		if( list->IsEmpty() )
			ASSERT(0);
		else
			ref= list->GetHead();		
	}

	return LPCTSTR( ref );
}

///////////////////////////////////////
// Handler for help button

void CIntegFileSpecPage::OnHelp() 
{
	AfxGetApp()->WinHelp(ALIAS_54_INTEG_OPTIONS);
}

BOOL CIntegFileSpecPage::OnHelpInfo(HELPINFO* pHelpInfo) 
{
	// Help for this property sheet is only specific down
	// to the property page level
	OnHelp();
	return TRUE;
}

///////////////////////////////////////
// Resize routines

void CIntegFileSpecPage::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI) 
{
	if (m_InitRect.Height())
	{
		lpMMI->ptMinTrackSize.x= m_InitRect.Width();
		lpMMI->ptMinTrackSize.y= m_InitRect.Height();
	}
}

void CIntegFileSpecPage::OnSize(UINT nType, int cx, int cy) 
{
	CDialog::OnSize(nType, cx, cy);

	if (nType == SIZE_MINIMIZED)
	{
		m_IsMinimized = TRUE;
		return;
	}
	else if (m_IsMinimized)
	{
		m_IsMinimized = FALSE;
		return;
	}

	// We might have changed the branch flag as a result of a Preview
	// so restore it so the resize will work correctly
	//
	m_BranchFlag = m_SaveBranchFlag;

	CWnd *pWnd=GetDlgItem(IDC_SOURCESPECS);
	if (!pWnd || !IsWindow(pWnd->m_hWnd))
		return;

	// Compute the change in width (dx)
	CRect rect;
	GetWindowRect(&rect);
	int dx = rect.Width() - m_LastRect.Width();
	int dy = rect.Height() - m_LastRect.Height();
	// Save the new size
	m_LastRect = rect;

	// Widen the source list by the change in width (dx) and
	// heighten the source list by the change in height (dy)
	pWnd->GetWindowRect(&rect);
	pWnd->SetWindowPos(NULL, 0, 0, rect.right - rect.left + dx, 
								   rect.bottom - rect.top + dy, SWP_NOMOVE | SWP_NOZORDER);
	m_RectSource.right += dx;
	m_RectSource.bottom += dy;

	// Widen the branchspec list by the change in width (dx) and
	// heighten the branchspec list by the change in height (dy) ONLY if
	// this is an Integ using a Branchspec from the Branches pane
	// or from the Submitted Changelist pane and using a Branchspec.
	pWnd = GetDlgItem(IDC_BRANCHSPECS);
	pWnd->GetWindowRect(&rect);
	ScreenToClient(rect);
	if (m_BranchFlag == INTEG_USING_BRANCH || m_IsChgListInteg)
		pWnd->SetWindowPos(NULL, 0, 0, rect.right - rect.left + dx, 
								   rect.bottom - rect.top + dy, SWP_NOMOVE | SWP_NOZORDER);
	else
		pWnd->SetWindowPos(NULL, 0, 0, rect.right - rect.left + dx, 
								   rect.bottom - rect.top, SWP_NOMOVE | SWP_NOZORDER);

	pWnd = GetDlgItem(IDC_TARGETSPECS_ALT);
	pWnd->GetWindowRect(&rect);
	ScreenToClient(rect);
	pWnd->SetWindowPos(NULL, 0, 0, rect.right - rect.left + dx, 
								   rect.bottom - rect.top + dy, SWP_NOMOVE | SWP_NOZORDER);
	m_RectTarget.right += dx;
	m_RectTarget.bottom += dy;

	// Widen the edit and combo boxes by the change in width (dx)
	// Slide these down by change in height (dy)
	pWnd = GetDlgItem(IDC_TARGETSPECS);
	pWnd->GetWindowRect(&rect);
	ScreenToClient(rect);
	pWnd->SetWindowPos(NULL, rect.left, rect.top + dy, rect.right - rect.left + dx, 
								   rect.bottom - rect.top, SWP_NOZORDER);

	pWnd = GetDlgItem(IDC_CHANGECOMBO);
	pWnd->GetWindowRect(&rect);
	ScreenToClient(rect);
	pWnd->SetWindowPos(NULL, rect.left, rect.top + dy, rect.right - rect.left + dx, 
								   rect.bottom - rect.top, SWP_NOZORDER);

	// Slide reverse checkbox by change in width
	pWnd = GetDlgItem(IDC_REVERSEINTEG);
	pWnd->GetWindowRect(&rect);
	ScreenToClient(rect);
	pWnd->SetWindowPos(NULL, rect.left + dx, rect.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER);

	// Slide other controls down by change in height
	if (m_BranchFlag != INTEG_USING_BRANCH_SPEC)
	{
		pWnd = GetDlgItem(IDC_LABELTARGET);
		pWnd->GetWindowRect(&rect);
		ScreenToClient(rect);
		pWnd->SetWindowPos(NULL, rect.left, rect.top + dy, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
	}

	pWnd = GetDlgItem(IDC_STATIC_1);
	pWnd->GetWindowRect(&rect);
	ScreenToClient(rect);
	pWnd->SetWindowPos(NULL, rect.left, rect.top + dy, 0, 0, SWP_NOSIZE | SWP_NOZORDER);

	// Slide the buttons to the right by the change in width
	// and down by the change in height
	pWnd = GetDlgItem(IDC_ADVOPTS);
	pWnd->GetWindowRect(&rect);
	ScreenToClient(rect);
	pWnd->SetWindowPos(NULL, rect.left + dx, rect.top + dy, 0, 0, SWP_NOSIZE | SWP_NOZORDER);

	pWnd = GetDlgItem(IDC_PREVIEW);
	pWnd->GetWindowRect(&rect);
	ScreenToClient(rect);
	pWnd->SetWindowPos(NULL, rect.left + dx, rect.top + dy, 0, 0, SWP_NOSIZE | SWP_NOZORDER);

	pWnd = GetDlgItem(IDC_BACK);
	pWnd->GetWindowRect(&rect);
	ScreenToClient(rect);
	pWnd->SetWindowPos(NULL, rect.left + dx, rect.top +dy, 0, 0, SWP_NOSIZE | SWP_NOZORDER);

	pWnd = GetDlgItem(IDC_FINISH);
	pWnd->GetWindowRect(&rect);
	ScreenToClient(rect);
	pWnd->SetWindowPos(NULL, rect.left + dx, rect.top +dy, 0, 0, SWP_NOSIZE | SWP_NOZORDER);

	pWnd = GetDlgItem(IDCANCEL);
	pWnd->GetWindowRect(&rect);
	ScreenToClient(rect);
	pWnd->SetWindowPos(NULL, rect.left + dx, rect.top +dy, 0, 0, SWP_NOSIZE | SWP_NOZORDER);

	pWnd = GetDlgItem(IDHELP);
	pWnd->GetWindowRect(&rect);
	ScreenToClient(rect);
	pWnd->SetWindowPos(NULL, rect.left + dx, rect.top + dy, 0, 0, SWP_NOSIZE | SWP_NOZORDER);

	InvalidateRect(NULL, TRUE);
}

void CIntegFileSpecPage::OnSysCommand(UINT nID, LPARAM lParam) 
{
	switch(nID)
	{
	case SC_MINIMIZE:
		GetDesktopWindow()->ArrangeIconicWindows();
		break;
	}

	CDialog::OnSysCommand(nID, lParam);
}

LRESULT CIntegFileSpecPage::OnEnableDisableButtons(WPARAM wParam, LPARAM lParam)
{
	if( m_BranchFlag == INTEG_USING_BRANCH_SPEC )
		GetDlgItem(IDC_BACK)->EnableWindow( lParam );
	GetDlgItem( IDC_ADVOPTS )->EnableWindow( lParam );
	GetDlgItem( IDC_PREVIEW )->EnableWindow( lParam );
	GetDlgItem( IDC_FINISH )->EnableWindow( lParam );
	GetDlgItem( IDHELP )->EnableWindow( lParam );
	GetDlgItem( IDCANCEL )->SetWindowText( LoadStringResource(lParam ? IDS_CANCEL : IDS_CLOSE) );
	return 0;
}
# Change User Description Committed
#1 19924 YourUncleBob Populate -o //guest/perforce_software/p4win/...
//guest/YourUncleBob/p4win/.....
//guest/perforce_software/p4win/main/gui/IntegDlg/FileSpecPage.cpp
#1 16169 perforce_software Move files to follow new path scheme for branches.
//guest/perforce_software/p4win/gui/IntegDlg/FileSpecPage.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.