/*-----------------------------------------------------------------------------
[名称]	GrepDlg.cpp
[概要]	Grep検索ダイアログクラスの実装
[備考]	なし
[履歴]	2004-01-30	b031228 (3367)Grep検索(dincom)
		2004-05-10	b031228 (3751)文書名がショートファイルネームで表示される(moralog)
-----------------------------------------------------------------------------*/

//-----------------------------------------------------------------------------
// インクルード
//-----------------------------------------------------------------------------
#include "stdafx.h"
#include "shitarabian.h"
#include "GrepDlg.h"
#include <process.h>
#include "Common.h"
#include "ShitarabianDoc.h"
#include "ShitarabianView.h"
#include "Selection.h"
#include "SettingPath.h"
#include "MainFrm.h"
#include "ExeCommon.h"
#include "Finder.h"


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

//-----------------------------------------------------------------------------
// ファイル内変数
//-----------------------------------------------------------------------------
static	int		s_iOnProposeModeID;		// 押された正規表現補完ボタン [リソースID] (-)

/////////////////////////////////////////////////////////////////////////////
// CGrepDlg ダイアログ


CGrepDlg::CGrepDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CGrepDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CGrepDlg)
	m_strSubstring = _T("");
	m_strFolder = _T("");
	m_bToken = FALSE;
	m_bRegexp = FALSE;
	m_strFileFilter = _T("");
	m_bCaseCare = FALSE;
	m_bSubFolder = FALSE;
	//}}AFX_DATA_INIT
}


void CGrepDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CGrepDlg)
	DDX_Control(pDX, IDC_GREP_FILEFILTER, m_comboFileFilter);
	DDX_Control(pDX, IDC_GREP_REGPROPOSE, m_btnRegPropose);
	DDX_Control(pDX, IDC_GREP, m_btnGrep);
	DDX_Control(pDX, IDC_GREP_FOLDER, m_comboFolder);
	DDX_Control(pDX, IDC_GREP_SUBSTRING, m_comboSubstring);
	DDX_CBString(pDX, IDC_GREP_SUBSTRING, m_strSubstring);
	DDX_CBString(pDX, IDC_GREP_FOLDER, m_strFolder);
	DDX_Check(pDX, IDC_GREP_TOKEN, m_bToken);
	DDX_Check(pDX, IDC_GREP_REGEXP, m_bRegexp);
	DDX_CBString(pDX, IDC_GREP_FILEFILTER, m_strFileFilter);
	DDX_Check(pDX, IDC_GREP_CASECARE, m_bCaseCare);
	DDX_Check(pDX, IDC_GREP_SBFOLDER, m_bSubFolder);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CGrepDlg, CDialog)
	//{{AFX_MSG_MAP(CGrepDlg)
	ON_BN_CLICKED(IDC_GREP, OnGrep)
	ON_BN_CLICKED(IDC_GREP_SETFOLDER, OnGrepSetFolder)
	ON_CBN_EDITCHANGE(IDC_GREP_FOLDER, OnEditchangeGrepFolder)
	ON_CBN_EDITCHANGE(IDC_GREP_SUBSTRING, OnEditchangeGrepSubstring)
	ON_WM_SHOWWINDOW()
	ON_BN_CLICKED(IDC_GREP_REGEXP, OnGrepRegexp)
	ON_BN_CLICKED(IDC_GREP_REGPROPOSE, OnGrepRegpropose)
	ON_COMMAND(IDM_REGEXP_0MATCH, OnRegexp0match)
	ON_COMMAND(IDM_REGEXP_1MATCH, OnRegexp1match)
	ON_COMMAND(IDM_REGEXP_CHAR, OnRegexpChar)
	ON_COMMAND(IDM_REGEXP_COUNT, OnRegexpCount)
	ON_COMMAND(IDM_REGEXP_GROUP, OnRegexpGroup)
	ON_COMMAND(IDM_REGEXP_HEAD, OnRegexpHead)
	ON_COMMAND(IDM_REGEXP_LAST, OnRegexpLast)
	ON_COMMAND(IDM_REGEXP_NOT, OnRegexpNot)
	ON_COMMAND(IDM_REGEXP_NOTSPACE, OnRegexpNotspace)
	ON_COMMAND(IDM_REGEXP_NOTTOKEN, OnRegexpNottoken)
	ON_COMMAND(IDM_REGEXP_OR, OnRegexpOr)
	ON_COMMAND(IDM_REGEXP_RENGE, OnRegexpRenge)
	ON_COMMAND(IDM_REGEXP_RENGEOVER, OnRegexpRengeover)
	ON_COMMAND(IDM_REGEXP_SPACE, OnRegexpSpace)
	ON_COMMAND(IDM_REGEXP_TAG, OnRegexpTag)
	ON_COMMAND(IDM_REGEXP_TOKEN, OnRegexpToken)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CGrepDlg メッセージ ハンドラ

/*-----------------------------------------------------------------------------
[名称]	ダイアログ初期化ハンドラ
[機能]	初期値を設定する
[戻値]	なし
[備考]	なし
-----------------------------------------------------------------------------*/
BOOL CGrepDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	//正規表現チェックボックスキャプション取得
	{
		CString	strRegexpCaption;
		CFinder*	pFinder = ::GetFinder( TRUE );
		strRegexpCaption.Format( "正規表現（%s）", pFinder->Name() );
		GetDlgItem( IDC_GREP_REGEXP )->SetWindowText( strRegexpCaption );
	}
	// フィルタ文字列の作成
	GetFilterFromSetting();

	VisibleControl();

	return TRUE;  // コントロールにフォーカスを設定しないとき、戻り値は TRUE となります
	              // 例外: OCX プロパティ ページの戻り値は FALSE となります
}

/*-----------------------------------------------------------------------------
[名称]	Grep実行ボタン押ハンドラ
[機能]	Grep検索を実行する
[戻値]	なし
[備考]	なし
-----------------------------------------------------------------------------*/
void CGrepDlg::OnGrep() 
{
	UpdateData( TRUE );

	//Grep条件を得る
	CString strOptionGrep;
	{
		strOptionGrep.Format(  _T("-%s=G"), ::GetString( IDS_OPTION_GREP ) );
		if( m_bRegexp )		strOptionGrep += _T("R");
		if( m_bCaseCare )	strOptionGrep += _T("C");
		if( m_bToken )		strOptionGrep += _T("T");
		if( m_bSubFolder )	strOptionGrep += _T("S");
	}

	//検索するフォルダを得る
	CString strOptionFolder;
	{
		m_comboFolder.AddString( m_strFolder );
		// 末尾が'\'の場合取り除く
		if( m_strFolder.ReverseFind( '\\' ) )
		{
			m_strFolder.TrimRight( '\\' );
		}
		strOptionFolder.Format( _T("-%s=%s"), ::GetString( IDS_OPTION_FOLDER ) , ::QuoteString( m_strFolder ) );
	}

	//検索文字列を得る
	CString strOptionSubstring;
	{
		strOptionSubstring.Format( _T("-%s=%s"), ::GetString( IDS_OPTION_SUBSTRING ) , ::QuoteString( m_strSubstring ));
		::GetMainFrame()->AddSubString( m_strSubstring , &m_comboSubstring );
	}
	
	//ファイルフィルターを得る
	CString strOptionFilter;
	{
		strOptionFilter.Format( _T("-%s=%s"), ::GetString( IDS_OPTION_FILTER ) , ::QuoteString( m_strFileFilter ));
	}

	// 実行ファイル名を得る
// ▼ (3751) BGN 2004.05.10 (moralog) 関数化
	CString	strExeShortPath = ::GetShortFilePath( ::GetExePathName() );
/*
// ▽ original BGN
	const	iMaxLength( 1028 );	// パス格納バッファ長さ
	char	strExeShortPath[ iMaxLength ];
	{
		char	strExeLongPath[ iMaxLength ];
		::GetModuleFileName(
			NULL,
			strExeLongPath,
			iMaxLength
		);

		// ショートファイルのパスを得る
		::GetShortPathName( strExeLongPath, strExeShortPath, iMaxLength );
	}
// △ original END
*/
// ▲ (3751) END
	ShowWindow( SW_HIDE );
	// 別窓で開く
		_spawnl(
			_P_NOWAIT,
			strExeShortPath,
			strExeShortPath,
			strOptionGrep,
			strOptionFolder,
			strOptionSubstring,
			strOptionFilter,
			NULL
		);
	
}

/*-----------------------------------------------------------------------------
[名称]	フォルダ取得ボタン押ハンドラ
[機能]	Grep対象フォルダを取得する
[戻値]	なし
[備考]	なし
-----------------------------------------------------------------------------*/
void CGrepDlg::OnGrepSetFolder() 
{
	UpdateData ( TRUE );

	TCHAR szFolderPath[_MAX_PATH];

	//フォルダ名取得
	if( ::SelectFolder ( this->m_hWnd, m_strFolder, szFolderPath ) )
	{
		m_strFolder.Empty();
		m_strFolder = szFolderPath;
	}
	
	UpdateData( FALSE );
	
}

/*-----------------------------------------------------------------------------
[名称]	コントロール制御
[機能]	ダイアログのコントロールEnable Disable制御
[戻値]	なし
[備考]	なし
-----------------------------------------------------------------------------*/
void CGrepDlg::VisibleControl()
{
	UpdateData( TRUE );

	//検索ボタン
	if ( m_strFolder.IsEmpty() || m_strSubstring.IsEmpty() )
	{
		m_btnGrep.EnableWindow( FALSE );
	}
	else
	{
		m_btnGrep.EnableWindow( TRUE );
	}

	//正規表現ボタン
	m_btnRegPropose.EnableWindow( m_bRegexp );
	GetDlgItem( IDC_GREP_TOKEN )->EnableWindow( !m_bRegexp );
}

/*-----------------------------------------------------------------------------
[名称]	ダイアログ表示時ハンドラ
[機能]	各コントロールへ値を反映させる
[戻値]	なし
[備考]	なし
-----------------------------------------------------------------------------*/
void CGrepDlg::OnShowWindow(BOOL bShow, UINT nStatus) 
{
	CDialog::OnShowWindow(bShow, nStatus);

	BOOL	bMultiLine;
	bMultiLine = (m_pDoc->GetSelection()->GetSelectedStartRow() != m_pDoc->GetSelection()->GetSelectedEndRow() );
	if ( !bMultiLine )
	{
		// １行のときには選択範囲を検索文字列とする
		CString	strSelected = m_pDoc->GetSelection()->GetSelectedText();
		if ( !strSelected.IsEmpty() )
		{
			GetDlgItem( IDC_GREP_SUBSTRING )->SetWindowText( strSelected );
		}
	}

	//デフォルトフォルダの位置取得
	if( m_strFolder.IsEmpty() )
	{
		GetDlgItem( IDC_GREP_FOLDER )->SetWindowText( CSettingPath::GetInstance()->GetFolderPath() );
	}

	// フィルタ文字列の作成
	GetFilterFromSetting();
	
	VisibleControl();

	// コンボボックスにフォーカスを移す
	m_comboSubstring.SetEditSel( 0, -1 );
	m_comboSubstring.SetFocus();

	SetWindowPos( &wndTop, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );

}

/*-----------------------------------------------------------------------------
[名称]	エディットボックス更新ハンドラ
[機能]	コントロールを制御する
[戻値]	なし
[備考]	なし
-----------------------------------------------------------------------------*/
void CGrepDlg::OnEditchangeGrepFolder() 
{
	VisibleControl();
}
void CGrepDlg::OnEditchangeGrepSubstring() 
{
	VisibleControl();
}
void CGrepDlg::OnGrepRegexp() 
{
	VisibleControl();
}

/*-----------------------------------------------------------------------------
[名称]	正規表現ボタン押ハンドラ
[機能]	正規表現メニューを表示する
[戻値]	なし
[備考]	なし
-----------------------------------------------------------------------------*/
void CGrepDlg::OnGrepRegpropose() 
{
	s_iOnProposeModeID = IDC_GREP_REGPROPOSE;

	CMenu menu;
	VERIFY(menu.LoadMenu( IDR_REGEXP ));
	CMenu* pPopup = menu.GetSubMenu(0);
	ASSERT(pPopup != NULL);

	CRect	rcButton;
	GetDlgItem( IDC_GREP_REGPROPOSE )->GetWindowRect( &rcButton );

	pPopup->TrackPopupMenu(
		TPM_LEFTALIGN | TPM_RIGHTBUTTON,
		rcButton.right, rcButton.top,
		this
	);	
}

/*-----------------------------------------------------------------------------
[名称]	正規表現補完ポップアップメニューハンドラ
[機能]	メニュー項目に対応した正規表現を、対象コンボボックスに挿入する。
[戻値]	なし
[備考]	なし
-----------------------------------------------------------------------------*/
void CGrepDlg::OnRegexpChar() 		{ CFinder::RegexpChar(	&m_comboSubstring); }
void CGrepDlg::OnRegexpRenge()		{ CFinder::RegexpRenge( &m_comboSubstring ); }
void CGrepDlg::OnRegexpRengeover()	{ CFinder::RegexpRengeover( &m_comboSubstring ); }
void CGrepDlg::OnRegexpHead() 		{ CFinder::RegexpHead( &m_comboSubstring ); }
void CGrepDlg::OnRegexpLast()		{ CFinder::RegexpLast( &m_comboSubstring ); }
void CGrepDlg::OnRegexpToken()		{ CFinder::RegexpToken( &m_comboSubstring ); }
void CGrepDlg::OnRegexpNottoken()	{ CFinder::RegexpNotToken( &m_comboSubstring ); }
void CGrepDlg::OnRegexpSpace()		{ CFinder::RegexpSpace( &m_comboSubstring ); }
void CGrepDlg::OnRegexpNotspace()	{ CFinder::RegexpNotSpace( &m_comboSubstring ); }
void CGrepDlg::OnRegexpTag()		{ CFinder::RegexpTag( &m_comboSubstring ); }
void CGrepDlg::OnRegexpNot()	 	{ CFinder::RegexpNot( &m_comboSubstring ); }
void CGrepDlg::OnRegexpOr() 		{ CFinder::RegexpOr( &m_comboSubstring ); }
void CGrepDlg::OnRegexp0match()		{ CFinder::Regexp0match( &m_comboSubstring ); }
void CGrepDlg::OnRegexp1match()		{ CFinder::Regexp1match( &m_comboSubstring ); }
void CGrepDlg::OnRegexpCount()		{ CFinder::RegexpCount( &m_comboSubstring ); }
void CGrepDlg::OnRegexpGroup()		{ CFinder::RegexpGroup( &m_comboSubstring ); }


/*-----------------------------------------------------------------------------
[名称]	ファイルフィルタリスト作成
[機能]	コンボボックスにファイルフィルタのリストを構築する
[戻値]	なし
[備考]	なし
-----------------------------------------------------------------------------*/
void CGrepDlg::GetFilterFromSetting()
{
	if( !m_strFileFilter.IsEmpty() )
	{
		return;
	}

	int	nLeft = 0;
	int nRight = 0;

	// フィルタ情報取得
	CString		strFilter;			// ファイルフィルタ
	CString		strDefaultExt;		// デフォルト拡張子

	CSettingPath::GetInstance()->GetFilter(
		&strFilter,
		&strDefaultExt
	);
	strFilter += _T("|");

	CString strTempFilter;
	m_comboFileFilter.ResetContent();

	//拡張子の情報のみ加える
	while( nRight != strFilter.GetLength() -1 )
	{
		strTempFilter.Empty();
		nLeft = strFilter.Find( _T("|") , nLeft ) + 1;
		nRight  = strFilter.Find( _T("|") , nLeft);
		strTempFilter = strFilter.Mid( nLeft , ( nRight - nLeft ) );
		m_comboFileFilter.AddString( strTempFilter );
		nLeft = nRight + 1;

		//最初のを表示させる
		if( m_strFileFilter.IsEmpty() )
		{
			m_strFileFilter = strTempFilter;
		}
	}

	m_comboFileFilter.SetWindowText( m_strFileFilter );
}
