/*
** 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> --- February 1998
 */

/*
 * CommitDlg.cpp : the cvs commit dialog
 */

#include "stdafx.h"

#ifdef WIN32
#	include "wincvs.h"
#	include <process.h>
#else /* !WIN32 */
#	include <ctype.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 "LPopupFiller.h"

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

#include "CommitDlg.h"
#include "CvsPrefs.h"
#include "MultiFiles.h"
#include "getline.h"
#include "TextBinary.h"
#include "MultiString.h"
#include "CvsCommands.h"
#include "EditorMonDlg.h"
#include "ItemListDlg.h"
#include "BrowseViewHandlers.h"

static CMString gCommitLogs(10, "P_CommitLogs");
static CPersistentBool gCheckValidEdits("P_CheckValidEdits", false);

void combozify(CStr & str)
{
	// extract the first xxx words
	const char *tmp = str;
	CStr result;
	int numWords = 0;
#	define HOWMUCH_WORDS 5
	while(*tmp != '\0' && numWords < HOWMUCH_WORDS)
	{
		while(*tmp != '\0' && isspace(*tmp))
			tmp++;

		while(*tmp != '\0' && !isspace(*tmp))
			result << *tmp ++;

		if(*tmp != '\0')
			result << ' ';

		numWords++;
	}

	if(*tmp != '\0')
	{
		result << "...";
	}
	str = result;
}

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

IMPLEMENT_DYNAMIC(CCommit_MAIN, CPropertyPage)

CCommit_MAIN::CCommit_MAIN(const MultiFiles *mf, const char *logMsg, const char *pathTmpl) 
	: m_mf(mf), m_fileToDiffCombo(USmartCombo::AutoDropWidth | USmartCombo::ReadOnly), 
	CPropertyPage(CCommit_MAIN::IDD)
{
	//{{AFX_DATA_INIT(CCommit_MAIN)
	m_logMsg = logMsg;
	m_wordWrap = FALSE;
	//}}AFX_DATA_INIT
	
	m_tmplPath = pathTmpl;
	if( !m_tmplPath.empty() )
	{
		if(!m_tmplPath.endsWith(kPathDelimiter))
			m_tmplPath << kPathDelimiter;
		m_tmplPath << "CVS";
		m_tmplPath << kPathDelimiter;
		m_tmplPath << "Template";
	}
	
	m_bSwitchingWrap = FALSE;
	m_wordWrap = gCvsPrefs.WordWrapLogMsg();

	m_prevLogsCombo.SetItems(&gCommitLogs);
}

CCommit_MAIN::~CCommit_MAIN()
{
}

void CCommit_MAIN::DoDataExchange(CDataExchange* pDX)
{
	CPropertyPage::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CCommit_MAIN)
	DDX_Control(pDX, IDC_PREVIEWINFO, m_previewInfo);
	DDX_Control(pDX, IDC_FILETODIFF, m_fileToDiffCombo);
	DDX_Control(pDX, IDC_WORDWRAP, m_wordWrapCtrl);
	DDX_Control(pDX, IDC_LOGMSG_WRAP, m_logMsgCtrlWrap);
	DDX_Control(pDX, IDC_LOGMSG, m_logMsgCtrl);
	DDX_Control(pDX, IDC_COMBO, m_prevLogsCombo);
	DDX_Check(pDX, IDC_WORDWRAP, m_wordWrap);
	//}}AFX_DATA_MAP

	if( !pDX->m_bSaveAndValidate )
	{
		DDX_Text(pDX, IDC_LOGMSG_WRAP, m_logMsg);
		DDX_Text(pDX, IDC_LOGMSG, m_logMsg);
	}
	else
	{
		DDX_Text(pDX, GetLogMsgID(), m_logMsg);
	}

	if( pDX->m_bSaveAndValidate )
	{
		if( !m_logMsg.IsEmpty() )
		{
			gCommitLogs.Insert(m_logMsg);
		}
	}
	else
	{
		DDX_ComboMString(pDX, IDC_COMBO, m_prevLogsCombo);
	}
}

void CCommit_MAIN::OnSelchangeCombo() 
{
	int sel = m_prevLogsCombo.GetCurSel();
	if( sel == CB_ERR )
		return;

	CEdit* pEdit = (CEdit*)GetLogMsgWnd();
	pEdit->SetSel(0, -1);

	const NAMESPACE(std) vector<CStr> & list = gCommitLogs.GetList();
	pEdit->ReplaceSel(list[sel]);
}

BEGIN_MESSAGE_MAP(CCommit_MAIN, CPropertyPage)
	//{{AFX_MSG_MAP(CCommit_MAIN)
	ON_CBN_SELCHANGE(IDC_COMBO, OnSelchangeCombo)
	ON_BN_CLICKED(IDC_LAUNCHEDITOR, OnLauncheditor)
	ON_WM_ERASEBKGND()
	ON_BN_CLICKED(IDC_WORDWRAP, OnWordwrap)
	ON_BN_CLICKED(IDC_DIFF, OnDiff)
	ON_CBN_SELCHANGE(IDC_FILETODIFF, OnSelchangeFiletodiff)
	ON_BN_CLICKED(IDC_TEMPLATE, OnTemplate)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

BOOL CCommit_MAIN::PreTranslateMessage(MSG* pMsg) 
{
	if( pMsg->message >= WM_KEYFIRST ||
		pMsg->message <= WM_KEYLAST ||
		pMsg->message == WM_COPY || pMsg->message == WM_CUT || pMsg->message == WM_PASTE )
	{
		UpdateInfo();
	}

	//dialog can be dismissed by Esc key
	if( pMsg->message == WM_KEYDOWN && 
		(int)pMsg->wParam == VK_ESCAPE )
	{
		EndDialog(IDCANCEL);
	}
	
	return CPropertyPage::PreTranslateMessage(pMsg);
}

void CCommit_MAIN::UpdateInfo()
{
	CEdit* pEdit = (CEdit*)GetLogMsgWnd();
	
	CString strOldInfo;
	CString strInfo;
	int nLineNumber = pEdit->LineFromChar();
	int nLineLenght = pEdit->LineLength( pEdit->LineIndex() );
	
	strInfo.Format( "Line %d (%d chars)", nLineNumber + 1, nLineLenght );
	
	GetDlgItemText( IDC_EDIT_POSITION, strOldInfo );
	if( strOldInfo != strInfo )
	{
		SetDlgItemText( IDC_EDIT_POSITION, strInfo );
	}
}

void CCommit_MAIN::UpdatePreviewInfo()
{
	CString strPreviewInfo;
	int nSelInfo = m_fileToDiffCombo.GetCurSel();
	if( nSelInfo < 0 || !m_fileToDiffCombo.GetCount() )
	{
		nSelInfo = 0;
	}
	else
	{
		nSelInfo++;
	}

	strPreviewInfo.Format("Preview file changes (%d/%d):", nSelInfo, m_fileToDiffCombo.GetCount());
	m_previewInfo.SetWindowText(strPreviewInfo);
}

void CCommit_MAIN::OnSelchangeFiletodiff() 
{
	UpdatePreviewInfo();
}

void CCommit_MAIN::OnLauncheditor() 
{
	UStr message;
	
	if( CompatGetEditorMsg(message) )
	{
		CString strMessage(message);
		strMessage.Replace("\n", "\r\n");

		if( !strMessage.IsEmpty() )
		{
			CEdit* pEdit = (CEdit*)GetLogMsgWnd();
			pEdit->SetSel(0, -1);
			pEdit->ReplaceSel(strMessage);		
		}
	}

	GotoDlgCtrl( GetLogMsgWnd() );
}

/// Switch the edit wrap and non-wrap edit boxes
void CCommit_MAIN::SwitchWrapEdit(BOOL bWordWrap)
{
	CString strMessage;

	if( bWordWrap )
	{
		m_logMsgCtrl.GetWindowText(strMessage);
		m_logMsgCtrlWrap.SetWindowText(strMessage);

		m_bSwitchingWrap = TRUE;
		m_logMsgCtrl.ShowWindow(SW_HIDE);
		m_logMsgCtrlWrap.ShowWindow(SW_SHOW);
		m_bSwitchingWrap = FALSE;
	}
	else
	{
		m_logMsgCtrlWrap.GetWindowText(strMessage);
		m_logMsgCtrl.SetWindowText(strMessage);

		m_bSwitchingWrap = TRUE;
		m_logMsgCtrlWrap.ShowWindow(SW_HIDE);
		m_logMsgCtrl.ShowWindow(SW_SHOW);
		m_bSwitchingWrap = FALSE;
	}
}

int CCommit_MAIN::GetLogMsgID()
{
	return m_wordWrapCtrl.GetCheck() ? IDC_LOGMSG_WRAP : IDC_LOGMSG;
}

CWnd* CCommit_MAIN::GetLogMsgWnd()
{
	return GetDlgItem( GetLogMsgID() );
}

BOOL CCommit_MAIN::OnEraseBkgnd(CDC* pDC) 
{
	if( m_bSwitchingWrap )
	{
		return TRUE;
	}
	
	return CPropertyPage::OnEraseBkgnd(pDC);
}

void CCommit_MAIN::OnWordwrap() 
{
	gCvsPrefs.SetWordWrapLogMsg(m_wordWrapCtrl.GetCheck());
	SwitchWrapEdit(gCvsPrefs.WordWrapLogMsg());
}

void CCommit_MAIN::OnDiff() 
{
	const int nComboIndex = m_fileToDiffCombo.GetCurSel();
	if( nComboIndex > CB_ERR )
	{
		int nIndex = (int)m_fileToDiffCombo.GetItemData(nComboIndex);
		CStr path;
		CStr fileName, currRev;
		if( m_mf->get(nIndex, path, fileName, currRev) )
		{
			MultiFiles mf;
			mf.newdir(path);
			mf.newfile(fileName);
			
			KoDiffHandler handler;
			handler.OnFiles(&mf);
		}
	}
}

BOOL CCommit_MAIN::OnInitDialog() 
{
	CPropertyPage::OnInitDialog();
	
	// Extra initialization here
	SwitchWrapEdit( gCvsPrefs.WordWrapLogMsg() );

	if( m_mf )
	{
		for( int nIndex = 0; nIndex < m_mf->NumFiles(); nIndex++ )
		{
			CStr path;
			CStr fileName, currRev;

			m_mf->get(nIndex, path, fileName, currRev);
			int nComboIndex = m_fileToDiffCombo.AddString(CString(path) + CString(fileName));
			m_fileToDiffCombo.SetItemData(nComboIndex, (DWORD)nIndex);
		}
	}

	if( m_fileToDiffCombo.GetCount() ) 
	{
		m_fileToDiffCombo.SetCurSel(0);
	}
	else
	{
		m_fileToDiffCombo.EnableWindow(FALSE);
		CWnd* pButton = GetDlgItem(IDC_DIFF);
		if( pButton )
		{
			pButton->EnableWindow(FALSE);
		}
	}
	
	//enable template button
	{
		CWnd* pTemplateButton = GetDlgItem(IDC_TEMPLATE);
		if( pTemplateButton )
		{
			FILE* templateFile = fopen(m_tmplPath, "r");
			pTemplateButton->EnableWindow(NULL != templateFile);
			if( templateFile )
			{
				fclose(templateFile);
			}
		}
	}

	UpdatePreviewInfo();

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

void CCommit_MAIN::OnTemplate() 
{
	CEdit* pEdit = (CEdit*)GetLogMsgWnd();
	pEdit->SetSel(0, -1);

	bool gotIt = false;
	FILE* output;
	
	if( !m_tmplPath.empty() && (output = fopen(m_tmplPath, "r")) != 0L )
	{
		char *line = 0L;
		size_t line_chars_allocated = 0;
		int line_length;
		while ((line_length = getline (&line, &line_chars_allocated, output)) > 0)
		{
			//correct the new line characters for edit box and insert the line
			CString strLine(line);
			strLine.Replace( "\n", "\r\n" );
			pEdit->ReplaceSel(strLine);
		}
		
		gotIt = true;
		if (line_length < 0 && !feof (output))
			gotIt = false;
		
		if(line != 0L)
			free (line);
		
		fclose(output);
	}
	
	if( !gotIt )
	{
		pEdit->ReplaceSel("*CVS/Template file not found*");
	}
}

/////////////////////////////////////////////////////////////////////////////
// CCommit_OPTIONS property page

IMPLEMENT_DYNAMIC(CCommit_OPTIONS, CPropertyPage)

CCommit_OPTIONS::CCommit_OPTIONS(const MultiFiles* mf) 
	: m_mf(mf), CPropertyPage(CCommit_OPTIONS::IDD)
{
	//{{AFX_DATA_INIT(CCommit_OPTIONS)
	m_forceCommit = FALSE;
	m_rev = _T("");
	m_forceRecurse = FALSE;
	m_forceRevision = FALSE;
	m_noModuleProgram = FALSE;
	m_noRecurse = FALSE;
	m_checkValidEdits = FALSE;
	//}}AFX_DATA_INIT

	m_checkValidEdits = (bool)gCheckValidEdits;
	m_revCombo.SetItems(&gRevNames);
}

CCommit_OPTIONS::~CCommit_OPTIONS()
{
}

void CCommit_OPTIONS::DoDataExchange(CDataExchange* pDX)
{
	CPropertyPage::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CCommit_OPTIONS)
	DDX_Control(pDX, IDC_COMBOREV, m_revCombo);
	DDX_Check(pDX, IDC_FORCECOMMIT, m_forceCommit);
	DDX_CBString(pDX, IDC_COMBOREV, m_rev);
	DDX_Check(pDX, IDC_FORCERECURSE, m_forceRecurse);
	DDX_Check(pDX, IDC_FORCEREVISION, m_forceRevision);
	DDX_Check(pDX, IDC_NOMODULEPROGRAM, m_noModuleProgram);
	DDX_Check(pDX, IDC_NORECURS, m_noRecurse);
	DDX_Check(pDX, IDC_CHECKVALIDEDITS, m_checkValidEdits);
	//}}AFX_DATA_MAP

	if( m_forceRevision )
	{
		DDV_MinChars(pDX, m_rev, 1);
	}
	
	if( !pDX->m_bSaveAndValidate )
	{
		OnForcerevision();
	}
	
	DDX_ComboMString(pDX, IDC_COMBOREV, m_revCombo);
}


BEGIN_MESSAGE_MAP(CCommit_OPTIONS, CPropertyPage)
//{{AFX_MSG_MAP(CCommit_OPTIONS)
	ON_BN_CLICKED(IDC_FORCEREVISION, OnForcerevision)
	ON_BN_CLICKED(IDC_BROWSE_TAG, OnBrowseTag)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CCommit_OPTIONS message handlers

void CCommit_OPTIONS::OnForcerevision() 
{
	CButton* but = (CButton *)GetDlgItem(IDC_FORCEREVISION);

	CWnd* wnd = GetDlgItem(IDC_COMBOREV);
	if( wnd )
	{
		wnd->EnableWindow(but->GetCheck());
	}

	wnd = GetDlgItem(IDC_BROWSE_TAG);
	if( wnd )
	{
		wnd->EnableWindow(but->GetCheck());
	}
}

void CCommit_OPTIONS::OnBrowseTag() 
{
	CPStr tagName;
	if( CompatGetTagListItem(m_mf, tagName) )
	{
		m_rev = (const char*)tagName;
		m_revCombo.SetWindowText(m_rev);
	}
}

#endif /* WIN32 */

#ifdef qMacCvsPP
class LLogFillerWrapper : public LFillerWrapper
{
public:
	LLogFillerWrapper(LMenuController *menu, CMString & mstr, const char *pathTmpl) :
		LFillerWrapper(menu), fMStr(mstr), fFirstTime(true)
	{
		fTmplPath = pathTmpl;
		if(!fTmplPath.empty())
		{
			if(!fTmplPath.endsWith(kPathDelimiter))
				fTmplPath << kPathDelimiter;
			fTmplPath << "CVS";
			fTmplPath << kPathDelimiter;
			fTmplPath << "Template";
		}

	}
	
	virtual void OnAddingItem(CStr & str)
	{
		if(fFirstTime)
		{
			fMenu->InsertMenuItem("\pInsert CVS/Template", max_Int16);
			fMenu->InsertMenuItem("\p(-", max_Int16, false);
			fFirstTime = false;
		}
		
		combozify(str);
		CPStr pstr(str);
		fMenu->InsertMenuItem(pstr, max_Int16);
	}
	
	virtual bool OnSelectingItem(SInt32 inItem, CStr & str)
	{
		str = "";
		if(inItem == 2)
		{
			bool gotIt = false;
			FILE *output;
			if(!fTmplPath.empty() && (output = fopen(fTmplPath, "r")) != 0L)
			{
				char *line = 0L;
				size_t line_chars_allocated = 0;
				int line_length;
				while ((line_length = getline (&line, &line_chars_allocated, output)) > 0)
				{
					str << line;
				}

				gotIt = true;
				if (line_length < 0 && !feof (output))
					gotIt = false;

				if(line != 0L)
					free (line);

				fclose(output);
			}
			if(!gotIt)
				str << "*found no CVS/Template file*";
			return true;
		}
		else if(inItem >= 4)
		{
			str = fMStr.GetList()[inItem - 4];
			return true;
		}
		
		return false;
	}
protected:
	CMString & fMStr;
	CStr fTmplPath;
	bool fFirstTime;
};

static void DoDataExchange_Commit(LWindow *theDialog, CStr & commit, bool & norecurs,
	const char *pathTmpl, bool putValue)
{
	LCheckBox *chkNoRecurs = dynamic_cast<LCheckBox*>
		(theDialog->FindPaneByID(item_NoRecurs));
	LTextEditView *editLog = dynamic_cast<LTextEditView*>
		(theDialog->FindPaneByID(item_LogMsg));
	LPopupFiller *fillLog = dynamic_cast<LPopupFiller*>
		(theDialog->FindPaneByID(item_FillerRev1));
	LLogFillerWrapper *wrapper = putValue ? NEW LLogFillerWrapper(fillLog, gCommitLogs, pathTmpl) : 0L;
	
	fillLog->DoDataExchange(gCommitLogs, putValue, wrapper);
	
	if(putValue)
	{
		chkNoRecurs->SetValue(norecurs ? Button_On : Button_Off);
		editLog->SetTextPtr((Ptr)(const char *)commit, commit.length());	
		theDialog->SetLatentSub(editLog);
	}
	else
	{
		norecurs = chkNoRecurs->GetValue() == Button_On;
		Handle hdl = editLog->GetTextHandle();
		Assert_(hdl != 0L);
		commit.set(*hdl, GetHandleSize(hdl));
		
	}
}

static void 
DoDataExchange_CommitOptions(

	LView *theDialog, 
	bool & forceCommit,
	bool & forceRecurse,
	bool & hasRev,
	CPStr & lastRev, 
	bool & noModuleProgram,
	bool putValue)
{
	LPopupFiller *fillTag = dynamic_cast<LPopupFiller*> (theDialog->FindPaneByID(item_FillerTag));
	fillTag->DoDataExchange(gRevNames, putValue);

	DoDataExchange (theDialog, item_ForceCommit, forceCommit, putValue);
	DoDataExchange (theDialog, item_ForceRecurse, forceRecurse, putValue);
	DoDataExchange (theDialog, item_NoModuleProgram, noModuleProgram, putValue);
	DoDataExchange (theDialog, item_CheckRevTag, hasRev, putValue);
	DoDataExchange (theDialog, item_EditRevTag, lastRev, putValue);
}
#endif /* qMacCvsPP */

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

	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(UCvsCommit, UWidget)

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

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

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

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

class UCvsCommit_MAIN : public UWidget
{
	UDECLARE_DYNAMIC(UCvsCommit_MAIN)
public:
	UCvsCommit_MAIN(const char *logmsg, const char *pathTmpl);
	virtual ~UCvsCommit_MAIN() {}

	enum
	{
		kEditLog = EV_COMMAND_START,	// 0
		kComboLog,				// 1
		kCheckRecurs			// 2
	};

	virtual void DoDataExchange(bool fill);

	UStr m_logmsg;
	bool m_norecurs;
	UStr m_tmplPath;
protected:

	ev_msg void OnComboSel(int pos, const char *txt);

	UDECLARE_MESSAGE_MAP()
};

UIMPLEMENT_DYNAMIC(UCvsCommit_MAIN, UWidget)

UBEGIN_MESSAGE_MAP(UCvsCommit_MAIN, UWidget)
	ON_COMBO_SEL(UCvsCommit_MAIN::kComboLog, UCvsCommit_MAIN::OnComboSel)
UEND_MESSAGE_MAP()

UCvsCommit_MAIN::UCvsCommit_MAIN(const char *logmsg, const char *pathTmpl) : UWidget(::UEventGetWidID())
{
	m_logmsg = logmsg;
	m_norecurs = false;
	m_tmplPath = pathTmpl;
	if(!m_tmplPath.empty())
	{
		if(!m_tmplPath.endsWith(kPathDelimiter))
			m_tmplPath << kPathDelimiter;
		m_tmplPath << "CVS";
		m_tmplPath << kPathDelimiter;
		m_tmplPath << "Template";
	}
}

void UCvsCommit_MAIN::OnComboSel(int pos, const char *txt)
{
	if(pos == 0)
	{
		bool gotIt = false;
		FILE *output;

		if(!m_tmplPath.empty() && (output = fopen(m_tmplPath, "r")) != 0L)
		{
			char *line = 0L;
			size_t line_chars_allocated = 0;
			int line_length;
			while ((line_length = getline (&line, &line_chars_allocated, output)) > 0)
			{
				UEventSendMessage(GetWidID(), EV_SETTEXT, kEditLog, line);
			}

			gotIt = true;
			if (line_length < 0 && !feof (output))
				gotIt = false;

			if(line != 0L)
				free (line);

			fclose(output);
		}
		if(!gotIt)
			UEventSendMessage(GetWidID(), EV_SETTEXT, kEditLog, (void *)"*found no CVS/Template file*");
	}
	else
	{
		const std::vector<CStr> & list = gCommitLogs.GetList();
		UEventSendMessage(GetWidID(), EV_SETTEXT, kEditLog, (void *)(const char *)list[pos - 1]);
	}
}

void UCvsCommit_MAIN::DoDataExchange(bool fill)
{
	if(fill)
	{
		UEventSendMessage(GetWidID(), EV_SETTEXT, kEditLog, (void *)(const char *)m_logmsg);

		UEventSendMessage(GetWidID(), EV_COMBO_RESETALL, kComboLog, 0L);
		UEventSendMessage(GetWidID(), EV_COMBO_APPEND, kComboLog,
						  (void *)"Insert CVS/Template");
		const std::vector<CStr> & list = gCommitLogs.GetList();
		std::vector<CStr>::const_iterator i;
		for(i = list.begin(); i != list.end(); ++i)
		{
			CStr str = *i;
			combozify(str);
			UEventSendMessage(GetWidID(), EV_COMBO_APPEND, kComboLog, (void *)(const char *)str);
		}
		
		UEventSendMessage(GetWidID(), EV_SETSTATE, UMAKEINT(kCheckRecurs, m_norecurs), 0L);
	}
	else
	{
		UEventSendMessage(GetWidID(), EV_GETTEXT, kEditLog, &m_logmsg);
		if(!m_logmsg.empty())
			gCommitLogs.Insert(m_logmsg);

		m_norecurs = UEventSendMessage(GetWidID(), EV_QUERYSTATE, kCheckRecurs, 0L) != 0;
	}
}

#endif // qUnix

/*!
	Get the commit options
	\note The path is used to read the /path/CVS/Template optionally
*/
bool CompatGetCommit(const MultiFiles* mf,
					 CStr& commit, bool& norecurs, 
					 bool& forceCommit, bool& forceRecurse, CPStr& rev, bool& noModuleProgram,
					 bool& checkValidEdits,
					 const char* pathTmpl /*= 0L*/)
{
	bool userHitOK = false;
	
	static CStr sLastMsg;
	static CPStr sLastRev;
	
	bool hasRev = false;
	
	norecurs = false;
	commit = "";
	forceCommit = false;
	forceRecurse = false;
	rev = "";
	noModuleProgram = false;
	checkValidEdits = (bool)gCheckValidEdits;

#ifdef WIN32
	CPropertySheet pages("Commit settings");
	pages.m_psh.dwFlags |= PSH_NOAPPLYNOW;
	CCommit_MAIN page1(mf, sLastMsg, pathTmpl);
	CCommit_OPTIONS page2(mf);
	CGetPrefs_GLOBALS page3;
	pages.AddPage(&page1);
	pages.AddPage(&page2);
	pages.AddPage(&page3);
	if(pages.DoModal() == IDOK)
	{
		commit = (const char *)page1.m_logMsg;
		sLastMsg = (const char *)page1.m_logMsg;
		norecurs = page2.m_noRecurse ? true : false;
		forceCommit = page2.m_forceCommit ? true : false;
		forceRecurse = page2.m_forceRecurse ? true : false;
		hasRev = page2.m_forceRevision ? true : false;
		sLastRev = page2.m_rev;
		noModuleProgram = page2.m_noModuleProgram ? true : false;
		gCheckValidEdits = page2.m_checkValidEdits ? true : false;
		page3.StoreValues();

		userHitOK = true;
	}
#endif /* WIN32 */
#ifdef qMacCvsPP
	StDialogHandler	theHandler(dlg_Commit, 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_CommitOptions(theDialog, forceCommit, forceRecurse, hasRev, sLastRev, noModuleProgram, true);
	multiView->SwitchToPanel(1);
	DoDataExchange_Commit(theDialog, sLastMsg, norecurs, pathTmpl, true);
	
	groupView->SetValue(sRuntimePanel);
	theDialog->Show();
	MessageT hitMessage;
	while (true)
	{		// Let DialogHandler process events
		hitMessage = theHandler.DoDialog();
		
		if (hitMessage == msg_OK || hitMessage == msg_Cancel)
			break;
	}
	theDialog->Hide();
	sRuntimePanel = groupView->GetValue();
	
	if(hitMessage == msg_OK)
	{
		multiView->SwitchToPanel(1);
		DoDataExchange_Commit(theDialog, sLastMsg, norecurs, pathTmpl, false);
		multiView->SwitchToPanel(2);
		DoDataExchange_CommitOptions(theDialog, forceCommit, forceRecurse, hasRev, sLastRev, noModuleProgram, false);
		multiView->SwitchToPanel(3);
		DoDataExchange_Globals(theDialog, false);
		commit = sLastMsg;
		commit.replace('\015', '\012');
		userHitOK = true;
	}
#endif /* qMacCvsPP */
#if qUnix
	void *wid = UCreate_CommitDlg();

	UCvsCommit *dlg = new UCvsCommit();
	UCvsCommit_MAIN *tab1 = new UCvsCommit_MAIN(sLastMsg, pathTmpl);
	UEventSendMessage(dlg->GetWidID(), EV_INIT_WIDGET, kUMainWidget, wid);	
	dlg->AddPage(tab1, UCvsCommit::kTabGeneral, 0);

	if(dlg->DoModal())
	{
		commit = tab1->m_logmsg;
		sLastMsg = tab1->m_logmsg;
		norecurs = tab1->m_norecurs;

		userHitOK = true;
	}

	delete dlg;
#endif // qUnix

	if(userHitOK)
	{
		if(commit.length() == 0)
			commit = "no message";
		
		if(hasRev && !sLastRev.empty())
			rev = sLastRev;

		checkValidEdits = (bool)gCheckValidEdits;

		gCvsPrefs.save();
	}

	return userHitOK;
}
