/*
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 1, or (at your option)
** any later version.

** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.

** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

/*
 * Author : Alexandre Parenteau <aubonbeurre@hotmail.com> --- March 1998
 */

/*
 * CheckoutDlg.h : the cvs checkout dialog
 */

#include "stdafx.h"

#ifdef WIN32
#	include "wincvs.h"
#	include <sys\stat.h>
#	include <direct.h>
#	include <errno.h>
#endif /* WIN32 */

#if qUnix
#	include "UCvsDialogs.h"
#endif

#ifdef qMacCvsPP
#	include <UModalDialogs.h>
#	include <LMultiPanelView.h>
#	include <LPopupGroupBox.h>
#	include <LCheckBox.h>
#	include <LTextEditView.h>
#	include <LEditText.h>
#	include <LPushButton.h>
#	include "LPopupFiller.h"

#	include "MacCvsConstant.h"
#endif /* qMacCvsPP */

#include "CheckoutDlg.h"
#include "CvsPrefs.h"
#include "MultiString.h"
#include "MultiFiles.h"
#include "UpdateDlg.h"
#include "PromptFiles.h"
#include "ItemListDlg.h"

CMString gOldModules(10, "P_OldModules");

#ifdef WIN32
#	include "GetPrefs.h"
#	ifdef _DEBUG
#	define new DEBUG_NEW
#	undef THIS_FILE
	static char THIS_FILE[] = __FILE__;
#	endif

IMPLEMENT_DYNAMIC(CCheckout_MAIN, CPropertyPage)

CCheckout_MAIN::CCheckout_MAIN(const MultiFiles* mf, const char* modname, const char* path) 
	: m_mf(mf), CPropertyPage(CCheckout_MAIN::IDD)
{
	//{{AFX_DATA_INIT(CCheckout_MAIN)    
	m_noRecurse = FALSE;
	m_stdout = FALSE;
	m_overrideCoDir = FALSE;
	m_checkoutDir = _T("");
	//}}AFX_DATA_INIT
	
	m_moduleName = modname;
	m_path = path;
	if( m_path.IsEmpty() )
	{
		CWincvsApp* app = (CWincvsApp*)AfxGetApp();
		if( 0L != app )
			m_path = app->GetRoot();
	}

	m_moduleCombo.SetItems(&gOldModules);
}

CCheckout_MAIN::~CCheckout_MAIN()
{
}

void CCheckout_MAIN::DoDataExchange(CDataExchange* pDX)
{
	CPropertyPage::DoDataExchange(pDX);

	//{{AFX_DATA_MAP(CCheckout_MAIN)
	DDX_Control(pDX, IDC_EDIT_CHECKOUTDIR, m_checkoutDirEdit);
	DDX_Control(pDX, IDC_CHECK_OVERRIDECHECKOUTDIR, m_overrideCoDirCheck);
    DDX_Control(pDX, IDC_PATH, m_pathEdit);
	DDX_Control(pDX, IDC_MODNAME, m_moduleCombo);	    
	DDX_Text(pDX, IDC_MODNAME, m_moduleName);
	DDX_Text(pDX, IDC_PATH, m_path);
	DDX_Check(pDX, IDC_NORECURS, m_noRecurse);
	DDX_Check(pDX, IDC_STDOUT, m_stdout);
	DDX_Check(pDX, IDC_CHECK_OVERRIDECHECKOUTDIR, m_overrideCoDir);
	DDX_Text(pDX, IDC_EDIT_CHECKOUTDIR, m_checkoutDir);
	//}}AFX_DATA_MAP

	DDV_MinChars(pDX, m_moduleName, 1);
	DDX_ComboMString(pDX, IDC_MODNAME, m_moduleCombo);
	DDV_CheckPathExists(pDX, IDC_PATH, m_path);

	if( !pDX->m_bSaveAndValidate )
	{
		//see if we are overriding the checkout directory
		OnCheckOverridecheckoutdir();
	}
}


BEGIN_MESSAGE_MAP(CCheckout_MAIN, CPropertyPage)
	//{{AFX_MSG_MAP(CCheckout_MAIN)
	ON_BN_CLICKED(IDC_BTNPATH, OnBtnPath)
	ON_BN_CLICKED(IDC_CHECK_OVERRIDECHECKOUTDIR, OnCheckOverridecheckoutdir)
	ON_BN_CLICKED(IDC_BROWSE_MODULES, OnBrowseModules)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CCheckout_MAIN message handlers

/// BN_CLICKED message handler, browse for checkout directory
void CCheckout_MAIN::OnBtnPath() 
{
	CString strPath;
    m_pathEdit.GetWindowText(strPath);
	
	CStr path(strPath);
	if( BrowserGetDirectory("Select a directory to checkout to", path, IsWindow(m_hWnd) ? this : NULL) )
	{
		m_pathEdit.SetWindowText(path);
	}
}

/// BN_CLICKED message handler, enable controls
void CCheckout_MAIN::OnCheckOverridecheckoutdir() 
{
	BOOL enableCheckoutDir = m_overrideCoDirCheck.GetCheck() != 0;

	m_checkoutDirEdit.EnableWindow(enableCheckoutDir);

	if( enableCheckoutDir )
	{
		CString strCheckoutDir;
		m_checkoutDirEdit.GetWindowText(strCheckoutDir);
		if( strCheckoutDir.IsEmpty() )
		{
			CString strModuleName;
			m_moduleCombo.GetWindowText(strModuleName);

			if( !strModuleName.IsEmpty() )
			{
				m_checkoutDirEdit.SetWindowText(strModuleName);
				GotoDlgCtrl(&m_checkoutDirEdit);
			}
		}
	}
}

/// BN_CLICKED message handler, browse for file/directory
void CCheckout_MAIN::OnBrowseModules() 
{	
	CStr moduleName;
	if( CompatGetModuleListItem(m_mf, moduleName) )
	{
		m_moduleName = (const char*)moduleName;
		m_moduleCombo.SetWindowText(m_moduleName);
	}
}

IMPLEMENT_DYNAMIC(CCheckout_OPTIONS, CPropertyPage)

CCheckout_OPTIONS::CCheckout_OPTIONS(const MultiFiles* mf, 
									 const char* rev, const char* date, const char* keyword) 
									 : m_mf(mf), CPropertyPage(CCheckout_OPTIONS::IDD)
{
	//{{AFX_DATA_INIT(CCheckout_OPTIONS)
	m_date = date;
	m_rev = rev;
	m_hasDate = FALSE;
	m_match = FALSE;
	m_hasRev = FALSE;
	m_export = FALSE;
	m_forceRoot = FALSE;
	m_keyword = keyword;
	//}}AFX_DATA_INIT

	m_revCombo.SetItems(&gRevNames);
	m_dateCombo.SetItems(&gDateNames);
}

CCheckout_OPTIONS::~CCheckout_OPTIONS()
{
}

void CCheckout_OPTIONS::DoDataExchange(CDataExchange* pDX)
{
	CPropertyPage::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CCheckout_OPTIONS)
	DDX_Control(pDX, IDC_BROWSE_TAG, m_browseTagButton);
	DDX_Control(pDX, IDC_REV, m_hasRevCheck);
	DDX_Control(pDX, IDC_DATE, m_hasDateCheck);
	DDX_Control(pDX, IDC_KEYWORDSUBSTITUTION, m_keywordCombo);
	DDX_Control(pDX, IDC_KEYWORDDESC, m_keywordDescStatic);
	DDX_Control(pDX, IDC_COMBOREV, m_revCombo);
	DDX_Control(pDX, IDC_COMBODATE, m_dateCombo);
	DDX_CBString(pDX, IDC_COMBODATE, m_date);
	DDX_CBString(pDX, IDC_COMBOREV, m_rev);
	DDX_Check(pDX, IDC_DATE, m_hasDate);
	DDX_Check(pDX, IDC_MATCH, m_match);
	DDX_Check(pDX, IDC_REV, m_hasRev);
	DDX_Check(pDX, IDC_EXPORT, m_export);
	DDX_Check(pDX, IDC_FORCEROOT, m_forceRoot);
	DDX_CBString(pDX, IDC_KEYWORDSUBSTITUTION, m_keyword);
	//}}AFX_DATA_MAP
	
	if( m_hasRev )
	{
		DDV_MinChars(pDX, m_rev, 1);
	}
	
	if( m_hasDate )
	{
		DDV_MinChars(pDX, m_date, 1);
	}
	
	if( !pDX->m_bSaveAndValidate )
	{
		OnDate();
		OnRev();
	}

	DDX_ComboMString(pDX, IDC_COMBOREV, m_revCombo);
	DDX_ComboMString(pDX, IDC_COMBODATE, m_dateCombo);
}


BEGIN_MESSAGE_MAP(CCheckout_OPTIONS, CPropertyPage)
	//{{AFX_MSG_MAP(CCheckout_OPTIONS)
	ON_BN_CLICKED(IDC_DATE, OnDate)
	ON_BN_CLICKED(IDC_REV, OnRev)
	ON_BN_CLICKED(IDC_BROWSE_TAG, OnBrowseTag)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CCheckout_OPTIONS message handlers

/// OnInitDialog virtual override, initialize the controls
BOOL CCheckout_OPTIONS::OnInitDialog() 
{
	CPropertyPage::OnInitDialog();
	
	// Extra initialization
	m_keywordCombo.SetDescriptionWnd(m_keywordDescStatic.m_hWnd);
	
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

/// BN_CLICKED message handler, enable controls
void CCheckout_OPTIONS::OnDate() 
{
	m_dateCombo.EnableWindow(m_hasDateCheck.GetCheck() != 0);
}

/// BN_CLICKED message handler, enable controls
void CCheckout_OPTIONS::OnRev() 
{
	m_revCombo.EnableWindow(m_hasRevCheck.GetCheck());
	m_browseTagButton.EnableWindow(m_hasRevCheck.GetCheck());
}

/// BN_CLICKED message handler, display browse tag/branch dialog
void CCheckout_OPTIONS::OnBrowseTag() 
{
	CStr tagName;
	if( CompatGetTagListItem(m_mf, tagName) )
	{
		m_rev = (const char*)tagName;
		m_revCombo.SetWindowText(m_rev);
	}
}

#endif /* WIN32 */

#ifdef qMacCvsPP
static void DoDataExchange_CheckoutMain(LWindow *theDialog, const MultiFiles* mf, CPStr & modname,
	bool & norecurs, bool & toStdout, bool & overrideCheckoutDir, CPStr & checkoutDir, bool putValue)
{
	LEditText *mname = dynamic_cast<LEditText*>
		(theDialog->FindPaneByID(item_ModuleName));
	LPopupFiller *filler = dynamic_cast<LPopupFiller*>
		(theDialog->FindPaneByID(item_PopModName));
	
	LModuleWrapper *wrapper = putValue ? NEW LModuleWrapper(filler, mf) : 0L;
	filler->DoDataExchange(gOldModules, putValue, wrapper);
	
	DoDataExchange (theDialog, item_NoRecurs, norecurs, putValue);
	DoDataExchange (theDialog, item_ToStout, toStdout, putValue);
	DoDataExchange (theDialog, item_CheckGroupPath, overrideCheckoutDir, putValue);
	DoDataExchange (theDialog, item_ShowPath, checkoutDir, putValue);
	
	if(putValue)
	{
		mname->SetText((Ptr)(const char *)modname, modname.length());	
		theDialog->SetLatentSub(mname);
		
		// this will take care about an empty module name
		mname->AddListener(GetDlgHandler());
		if(modname.length() == 0)
		{
			LPushButton *theOK = dynamic_cast<LPushButton*>
										(theDialog->FindPaneByID(item_OK));
			Assert_(theOK != 0L);
			theOK->Disable();
		}
	}
	else
	{
		char buf[512];
		Size len;
		mname->GetText(buf, 511, &len);
		modname.set(buf, len);
	}
}

static void 
DoDataExchange_CheckoutOptions(
	LView *theDialog, 
	const MultiFiles* mf,
	bool & hasDate, 
	bool & hasRev,
	CPStr & sLastDate, 
	CPStr & sLastRev, 
	bool & useMostRecent, 
	bool & doexport, 
	bool & forceCvsroot,
	bool putValue)

{
	LPopupFiller *fillTag = dynamic_cast<LPopupFiller*>
		(theDialog->FindPaneByID(item_FillerTag));
	LPopupFiller *fillDate = dynamic_cast<LPopupFiller*>
		(theDialog->FindPaneByID(item_FillerDate));
	
	LTagWrapper *wrapper = putValue ? NEW LTagWrapper(fillTag, mf) : 0L;
	fillTag->DoDataExchange(gRevNames, putValue, wrapper);
	fillDate->DoDataExchange(gDateNames, putValue);
	
	DoDataExchange (theDialog, item_CheckDate, hasDate, putValue);
	DoDataExchange (theDialog, item_CheckRevTag, hasRev, putValue);
	DoDataExchange (theDialog, item_EditDate, sLastDate, putValue);
	DoDataExchange (theDialog, item_EditRevTag, sLastRev, putValue);
	DoDataExchange (theDialog, item_MostRecentRev, useMostRecent, putValue);
	DoDataExchange (theDialog, item_CheckForceRoot, forceCvsroot, putValue);
	DoDataExchange (theDialog, item_CheckExport, doexport, putValue);

}
#endif /* qMacCvsPP */

#if qUnix
class UCvsCheckout : public UWidget
{
	UDECLARE_DYNAMIC(UCvsCheckout)
public:
	UCvsCheckout() : UWidget(::UEventGetWidID()) {}
	virtual ~UCvsCheckout() {}

	enum
	{
		kOK = EV_COMMAND_START,	// 0
		kCancel,				// 1
		kTabGeneral				// 2
	};

	virtual void DoDataExchange(bool fill);

protected:
	ev_msg int OnOK(void);
	ev_msg int OnCancel(void);

	UDECLARE_MESSAGE_MAP()
};

UIMPLEMENT_DYNAMIC(UCvsCheckout, UWidget)

UBEGIN_MESSAGE_MAP(UCvsCheckout, UWidget)
	ON_UCOMMAND(UCvsCheckout::kOK, UCvsCheckout::OnOK)
	ON_UCOMMAND(UCvsCheckout::kCancel, UCvsCheckout::OnCancel)
UEND_MESSAGE_MAP()

int UCvsCheckout::OnOK(void)
{
	EndModal(true);
	return 0;
}

int UCvsCheckout::OnCancel(void)
{
	EndModal(false);
	return 0;
}

void UCvsCheckout::DoDataExchange(bool fill)
{
	if(fill)
	{
	}
	else
	{
	}
}

class UCvsCheckout_MAIN : public UWidget
{
	UDECLARE_DYNAMIC(UCvsCheckout_MAIN)
public:
	UCvsCheckout_MAIN(const char * modname, const char * path);
	virtual ~UCvsCheckout_MAIN() {}

	enum
	{
		kComboPath = EV_COMMAND_START,	// 0
		kStaticPath,			// 1
		kBtnPath,				// 2
		kCheckStdout,			// 3
		kCheckRecurse			// 4
	};

	virtual void DoDataExchange(bool fill);

	UStr m_path;
	UStr m_modname;
	bool m_norecurs;
	bool m_stdout;

protected:
	ev_msg int OnPath(void);

	UDECLARE_MESSAGE_MAP()
};

UIMPLEMENT_DYNAMIC(UCvsCheckout_MAIN, UWidget)

UBEGIN_MESSAGE_MAP(UCvsCheckout_MAIN, UWidget)
	ON_UCOMMAND(UCvsCheckout_MAIN::kBtnPath, UCvsCheckout_MAIN::OnPath)
UEND_MESSAGE_MAP()

UCvsCheckout_MAIN::UCvsCheckout_MAIN(const char * modname, const char * path) : UWidget(::UEventGetWidID())
{
	m_path = path;
	m_modname = modname;
	m_norecurs = false;
	m_stdout = false;
}

int UCvsCheckout_MAIN::OnPath(void)
{
	CStr dir;
	if( BrowserGetDirectory("Select a directory to checkout to", dir) )
	{
		UEventSendMessage(GetWidID(), EV_SETTEXT, kStaticPath, (void*)dir.c_str());
	}
	
	return 0;
}

void UCvsCheckout_MAIN::DoDataExchange(bool fill)
{
	::DoDataExchange(fill, GetWidID(), kComboPath, gOldModules);

	if(fill)
	{
		UEventSendMessage(GetWidID(), EV_SETSTATE, UMAKEINT(kCheckStdout, m_stdout), 0L);
		UEventSendMessage(GetWidID(), EV_SETSTATE, UMAKEINT(kCheckRecurse, m_norecurs), 0L);

		UEventSendMessage(GetWidID(), EV_SETTEXT, kComboPath, (void *)(const char *)m_modname);
		UEventSendMessage(GetWidID(), EV_SETTEXT, kStaticPath, (void *)(const char *)m_path);
	}
	else
	{
		m_stdout = UEventSendMessage(GetWidID(), EV_QUERYSTATE, kCheckStdout, 0L) != 0;
		m_norecurs = UEventSendMessage(GetWidID(), EV_QUERYSTATE, kCheckRecurse, 0L) != 0;

		UEventSendMessage(GetWidID(), EV_GETTEXT, kComboPath, &m_modname);
		UEventSendMessage(GetWidID(), EV_GETTEXT, kStaticPath, &m_path);
	}
}

class UCvsCheckout_STICKY : public UWidget
{
	UDECLARE_DYNAMIC(UCvsCheckout_STICKY)
public:
	UCvsCheckout_STICKY(const char *rev, const char *date);
	virtual ~UCvsCheckout_STICKY() {}

	enum
	{
		kCheckDate = EV_COMMAND_START,	// 0
		kComboDate,			// 1
		kCheckRev,			// 2
		kComboRev,			// 3
		kCheckMatch			// 4
	};

	virtual void DoDataExchange(bool fill);

	UStr m_date;
	UStr m_rev;
	bool m_hasdate;
	bool m_hasrev;
	bool m_match;
protected:

	ev_msg int OnDate(void);
	ev_msg int OnRev(void);

	UDECLARE_MESSAGE_MAP()
};

UIMPLEMENT_DYNAMIC(UCvsCheckout_STICKY, UWidget)

UBEGIN_MESSAGE_MAP(UCvsCheckout_STICKY, UWidget)
	ON_UCOMMAND(UCvsCheckout_STICKY::kCheckDate, UCvsCheckout_STICKY::OnDate)
	ON_UCOMMAND(UCvsCheckout_STICKY::kCheckRev, UCvsCheckout_STICKY::OnRev)
UEND_MESSAGE_MAP()

UCvsCheckout_STICKY::UCvsCheckout_STICKY(const char *rev, const char *date) : UWidget(::UEventGetWidID())
{
	m_date = date;
	m_rev = rev;
	m_hasdate = false;
	m_hasrev = false;
	m_match = false;
}

int UCvsCheckout_STICKY::OnDate()
{
	int state = UEventSendMessage(GetWidID(), EV_QUERYSTATE, kCheckDate, 0L);
	UEventSendMessage(GetWidID(), EV_ENABLECMD, UMAKEINT(kComboDate, state), 0L);
	return 0;
}

int UCvsCheckout_STICKY::OnRev()
{
	int state = UEventSendMessage(GetWidID(), EV_QUERYSTATE, kCheckRev, 0L);
	UEventSendMessage(GetWidID(), EV_ENABLECMD, UMAKEINT(kComboRev, state), 0L);
	return 0;
}

void UCvsCheckout_STICKY::DoDataExchange(bool fill)
{
	::DoDataExchange(fill, GetWidID(), kComboRev, gRevNames);
	::DoDataExchange(fill, GetWidID(), kComboDate, gDateNames);

	if(fill)
	{
		UEventSendMessage(GetWidID(), EV_SETSTATE, UMAKEINT(kCheckDate, m_hasdate), 0L);
		UEventSendMessage(GetWidID(), EV_SETSTATE, UMAKEINT(kCheckRev, m_hasrev), 0L);
		UEventSendMessage(GetWidID(), EV_SETSTATE, UMAKEINT(kCheckMatch, m_match), 0L);

		OnDate();
		OnRev();
	}
	else
	{
		m_hasdate = UEventSendMessage(GetWidID(), EV_QUERYSTATE, kCheckDate, 0L);
		m_hasrev = UEventSendMessage(GetWidID(), EV_QUERYSTATE, kCheckRev, 0L);
		m_match = UEventSendMessage(GetWidID(), EV_QUERYSTATE, kCheckMatch, 0L);

		UEventSendMessage(GetWidID(), EV_GETTEXT, kComboDate, &m_date);
		UEventSendMessage(GetWidID(), EV_GETTEXT, kComboRev, &m_rev);
	}
}

class UCvsCheckout_OPTIONS : public UWidget
{
	UDECLARE_DYNAMIC(UCvsCheckout_OPTIONS)
public:
	UCvsCheckout_OPTIONS();
	virtual ~UCvsCheckout_OPTIONS() {}

	enum
	{
		kCheckForce = EV_COMMAND_START,	// 0
		kCheckExport		// 1
	};

	virtual void DoDataExchange(bool fill);

	bool m_export;
	bool m_forceroot;
protected:

	UDECLARE_MESSAGE_MAP()
};

UIMPLEMENT_DYNAMIC(UCvsCheckout_OPTIONS, UWidget)

UBEGIN_MESSAGE_MAP(UCvsCheckout_OPTIONS, UWidget)
UEND_MESSAGE_MAP()

UCvsCheckout_OPTIONS::UCvsCheckout_OPTIONS() : UWidget(::UEventGetWidID())
{
	m_export = false;
	m_forceroot = false;
}

void UCvsCheckout_OPTIONS::DoDataExchange(bool fill)
{
	if(fill)
	{
		UEventSendMessage(GetWidID(), EV_SETSTATE, UMAKEINT(kCheckForce, m_forceroot), 0L);
		UEventSendMessage(GetWidID(), EV_SETSTATE, UMAKEINT(kCheckExport, m_export), 0L);
	}
	else
	{
		m_forceroot = UEventSendMessage(GetWidID(), EV_QUERYSTATE, kCheckForce, 0L);
		m_export = UEventSendMessage(GetWidID(), EV_QUERYSTATE, kCheckExport, 0L);
	}
}
#endif // qUnix

/// Get the checkout options
bool CompatGetCheckout(const MultiFiles* mf,
					   CPStr& modname, CPStr& path, bool& norecurs,
					   bool& toStdout, CPStr& date, CPStr& rev,
					   bool& useMostRecent, 
					   CPStr& rev1, CPStr& rev2,
					   bool& doexport, bool& forceCvsroot,
					   bool& overrideCheckoutDir, CPStr& checkoutDir,
					   CPStr& keyword)
{
	bool userHitOK = false;

	date = "";
	rev = "";
	modname = "";
	norecurs = false;
	toStdout = false;
	useMostRecent = false;
	doexport = false;
	forceCvsroot = false;
	overrideCheckoutDir = false;
	
	static CPStr sLastModName;
	static CPStr sLastRev;
	static CPStr sLastDate;
	static CPStr sLastRev1;
	static CPStr sLastRev2;
	static CPStr sLastDate1;
	static CPStr sLastDate2;

	bool hasDate = false;
	bool hasRev = false;
	bool merge1 = false;
	bool merge2 = false;
	bool hasDate1 = false;
	bool hasDate2 = false;
	keyword = "";

#ifdef WIN32
	CPropertySheet pages("Checkout settings");
	pages.m_psh.dwFlags |= PSH_NOAPPLYNOW;
	CCheckout_MAIN page1(mf, sLastModName, path);
	CCheckout_OPTIONS page2(mf, sLastRev, sLastDate, keyword);
	CUpdateMerge page3(mf, true, sLastRev1, sLastRev2, sLastDate1, sLastDate2);
	CGetPrefs_CVSROOT page4;
	CGetPrefs_GLOBALS page5;
	pages.AddPage(&page1);
	pages.AddPage(&page2);
	pages.AddPage(&page3);
	pages.AddPage(&page4);
	pages.AddPage(&page5);
	if(pages.DoModal() == IDOK)
	{
		sLastModName = (const char *)page1.m_moduleName;
		path = (const char *)page1.m_path;
		norecurs = page1.m_noRecurse == TRUE;
		toStdout = page1.m_stdout == TRUE;
		overrideCheckoutDir = page1.m_overrideCoDir == TRUE;
		checkoutDir = (const char *)page1.m_checkoutDir;

		sLastDate = page2.m_date;
		sLastRev = page2.m_rev;
		hasDate = page2.m_hasDate == TRUE;
		hasRev = page2.m_hasRev == TRUE;
		useMostRecent = page2.m_match == TRUE;
		doexport = page2.m_export == TRUE;
		forceCvsroot = page2.m_forceRoot == TRUE;
		keyword = page2.m_keyword;

		merge1 = page3.m_merge >= 1;
		merge2 = page3.m_merge == 2;
		sLastRev1 = page3.m_rev1;
		sLastRev2 = page3.m_rev2;
		hasDate1 = page3.m_hasDate1 == TRUE;
		hasDate2 = page3.m_hasDate2 == TRUE;
		sLastDate1 = page3.m_date1;
		sLastDate2 = page3.m_date2;

		page4.StoreValues();
		page5.StoreValues();
		userHitOK = true;
	}
#endif /* WIN32 */
#ifdef qMacCvsPP
	StDialogHandler	theHandler(dlg_Checkout, LCommander::GetTopCommander());
	LWindow *theDialog = theHandler.GetDialog();
	ThrowIfNil_(theDialog);
	static UInt16 sRuntimePanel = 1;
	
	LMultiPanelView *multiView = dynamic_cast<LMultiPanelView*>
		(theDialog->FindPaneByID(item_MultiViewPrefs));
	LPane *groupView = theDialog->FindPaneByID(item_GroupViewPrefs);
	
	multiView->SwitchToPanel(3);
	DoDataExchange_Globals(theDialog, true);
	multiView->SwitchToPanel(2);
	DoDataExchange_CheckoutOptions(theDialog, mf, hasDate, hasRev,
		sLastDate, sLastRev, useMostRecent, doexport, forceCvsroot, true);
	multiView->SwitchToPanel(1);
	DoDataExchange_CheckoutMain(theDialog, mf, sLastModName, norecurs, toStdout, overrideCheckoutDir, checkoutDir, true);
	dynamic_cast<LBroadcaster*> (theDialog->FindPaneByID (item_EditPath))->AddListener (&theHandler);
	dynamic_cast<LBroadcaster*> (theDialog->FindPaneByID (item_CheckGroupPath))->AddListener (&theHandler);
	
	
	groupView->SetValue(sRuntimePanel);
	theDialog->Show();
	MessageT hitMessage;
	while (true)
	{		// Let DialogHandler process events
		hitMessage = theHandler.DoDialog();
		
		if (hitMessage == msg_OK || hitMessage == msg_Cancel)
			break;

		if(hitMessage == item_CheckGroupPath || hitMessage == item_EditPath)
		{
			if(theDialog->GetValueForPaneID(item_CheckGroupPath) == Button_Off)
			{
				continue;
			}
			
			CStr dir;
			if( BrowserGetDirectory("Select a directory to checkout to", dir) )
			{
				CPStr tmp(dir.c_str());
				theDialog->SetDescriptorForPaneID(item_ShowPath, tmp);
			}
			else if(hitMessage == item_CheckGroupPath)
			{
				theDialog->SetValueForPaneID(item_CheckGroupPath, Button_Off);
			}
		}
	}
	theDialog->Hide();
	sRuntimePanel = groupView->GetValue();
	
	if(hitMessage == msg_OK)
	{
		multiView->SwitchToPanel(1);
		DoDataExchange_CheckoutMain(theDialog, mf, sLastModName, norecurs, toStdout, overrideCheckoutDir, checkoutDir, false);
		multiView->SwitchToPanel(2);
		DoDataExchange_CheckoutOptions(theDialog, mf, hasDate, hasRev,
			sLastDate, sLastRev, useMostRecent, doexport, forceCvsroot, false);
		multiView->SwitchToPanel(3);
		DoDataExchange_Globals(theDialog, false);
		
		Assert_(sLastModName.length() != 0);
		
		userHitOK = true;
	}
#endif /* qMacCvsPP */
#if qUnix
	void *wid = UCreate_CheckoutDlg();

	UCvsCheckout *dlg = new UCvsCheckout();
	UCvsCheckout_MAIN *tab1 = new UCvsCheckout_MAIN(sLastModName, path);
	UCvsCheckout_STICKY *tab2 = new UCvsCheckout_STICKY(sLastRev, sLastDate);
	UCvsCheckout_OPTIONS *tab3 = new UCvsCheckout_OPTIONS();
	UEventSendMessage(dlg->GetWidID(), EV_INIT_WIDGET, kUMainWidget, wid);	
	dlg->AddPage(tab1, UCvsCheckout::kTabGeneral, 0);
	dlg->AddPage(tab2, UCvsCheckout::kTabGeneral, 1);
	dlg->AddPage(tab3, UCvsCheckout::kTabGeneral, 2);

	if(dlg->DoModal())
	{
		sLastModName = tab1->m_modname;
		path = tab1->m_path;
		norecurs = tab1->m_norecurs;
		toStdout = tab1->m_stdout;

		sLastDate = tab2->m_date;
		sLastRev = tab2->m_rev;
		hasDate = tab2->m_hasdate;
		hasRev = tab2->m_hasrev;
		useMostRecent = tab2->m_match;

		doexport = tab3->m_export;
		forceCvsroot = tab3->m_forceroot;

		userHitOK = true;
	}

	delete dlg;
#endif // qUnix

	if( userHitOK )
	{
		if( hasDate && !sLastDate.empty() )
			date = sLastDate;
		
		if( hasRev && !sLastRev.empty() )
			rev = sLastRev;

		modname = sLastModName;

		if( merge1 && merge2 && !sLastRev1.empty() && !sLastRev2.empty() )
		{
			rev1 = sLastRev1;
			rev2 = sLastRev2;

			if( hasDate1 )
				rev1 << ":" << sLastDate1;
			
			if( hasDate2 )
				rev2 << ":" << sLastDate2;

		}
		
		if( merge1 && !merge2 && !sLastRev1.empty() )
		{
			rev1 = sLastRev1;
			
			if( hasDate1 )
				rev1 << ":" << sLastDate1;
		}

		gCvsPrefs.save();
	}

	return userHitOK;
}
