//====================================================================
// Although great care has gone into developing this software,
// it is provided without any guarantee of reliability, accuracy
// of information, or correctness of operation. I am not responsible
// for any damages that may occur as a result of using this software.
// Use this software entirely at your own risk.
// Copyright 2003, Chris Richardson
//
// Description: View class.
//
//====================================================================
#include "stdafx.h"
#include "IncFinder.h"
#include "IncFinderDoc.h"
#include "IncFinderView.h"
#include "Settings.h"
#include "ParsedFile.h"
#include "FileIterator.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CIncFinderView
// Register the FINDMSGSTRING message
static WM_FINDREPLACE = ::RegisterWindowMessage(FINDMSGSTRING);
IMPLEMENT_DYNCREATE(CIncFinderView, CFormView)
BEGIN_MESSAGE_MAP(CIncFinderView, CFormView)
//{{AFX_MSG_MAP(CIncFinderView)
ON_WM_SIZE()
ON_BN_CLICKED(IDC_START_STOP, OnStartStop)
ON_WM_DESTROY()
ON_WM_CONTEXTMENU()
ON_COMMAND(ID_TREE_OPENFILE, OnTreeOpenfile)
ON_UPDATE_COMMAND_UI(ID_TREE_OPENFILE, OnUpdateTreeOpenfile)
ON_COMMAND(ID_VIEW_UNFOUND_FILES, OnViewUnfoundFiles)
ON_UPDATE_COMMAND_UI(ID_VIEW_UNFOUND_FILES, OnUpdateViewUnfoundFiles)
ON_COMMAND(ID_VIEW_RELATIVE_PATHS, OnViewRelativePaths)
ON_UPDATE_COMMAND_UI(ID_VIEW_RELATIVE_PATHS, OnUpdateViewRelativePaths)
ON_NOTIFY(NM_DBLCLK, IDC_FILE_TREE, OnDblclkFileTree)
ON_COMMAND(ID_EDIT_FIND, OnEditFind)
ON_COMMAND(ID_EDIT_FIND_NEXT, OnEditFindNext)
ON_UPDATE_COMMAND_UI(ID_EDIT_FIND_NEXT, OnUpdateEditFindNext)
//}}AFX_MSG_MAP
ON_MESSAGE( INC_FINDER_WM_FILE_START, OnFileStart )
ON_MESSAGE( INC_FINDER_WM_FILE_FINISHED, OnFileFinished )
ON_MESSAGE( INC_FINDER_WM_FINISHED, OnFinished )
ON_REGISTERED_MESSAGE(WM_FINDREPLACE, OnFindReplace)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CIncFinderView construction/destruction
CIncFinderView::CIncFinderView()
: CFormView(CIncFinderView::IDD),
c_bIsShowingOnlyUnfoundFiles( false ),
c_bIsShowingRelativePaths( false ),
c_bIsInitialized( false ),
c_poCurrentSearchPage( NULL ),
c_poFindDlg( NULL )
{
//{{AFX_DATA_INIT(CIncFinderView)
//}}AFX_DATA_INIT
// TODO: add construction code here
}
CIncFinderView::~CIncFinderView()
{
c_poCurrentSearchPage = NULL;
ClearParsedFiles();
if( c_poFindDlg )
{
delete c_poFindDlg;
c_poFindDlg = NULL;
}
}
void CIncFinderView::DoDataExchange(CDataExchange* pDX)
{
CFormView::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CIncFinderView)
DDX_Control(pDX, IDC_PREPROCESS, c_oPreprocess);
DDX_Control(pDX, IDC_PROCESSING_TIME, c_oProcessingTime);
DDX_Control(pDX, IDC_FILES_PROCESSED, c_oFilesProcessed);
DDX_Control(pDX, IDC_PROCESSING_ANIM, c_oProcessingAnim);
DDX_Control(pDX, IDC_FILE_TREE, c_oFileTree);
DDX_Control(pDX, IDC_START_STOP, c_oStartStop);
DDX_Control(pDX, IDC_MIDDLE_BORDER, c_oMiddleBorder);
DDX_Control(pDX, IDC_TOP_BORDER, c_oTopBorder);
//}}AFX_DATA_MAP
}
BOOL CIncFinderView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CFormView::PreCreateWindow(cs);
}
void CIncFinderView::OnInitialUpdate()
{
CFormView::OnInitialUpdate();
if( !c_bIsInitialized )
{
// Load the neat file search icon from shell32.dll.
// I do this up here instead of with the rest of the init below, so that the control will be repositioned
// properly in the WM_SIZE handler.
HINSTANCE a_hInstance = (HINSTANCE)LoadLibrary( _T("Shell32.dll") );
c_oProcessingAnim.SendMessage( ACM_OPEN, (WPARAM)a_hInstance, (LPARAM)MAKEINTRESOURCE( 151 ) );
FreeLibrary( a_hInstance );
}
GetParentFrame()->RecalcLayout();
if( !c_bIsInitialized )
{
CSettings & a_roSettings = CSettings::GetSettings();
c_bIsInitialized = true;
// Create our "Search Type" property sheet.
c_oPropSheet.Create(this, WS_CHILD | WS_VISIBLE | WS_TABSTOP, WS_EX_CONTROLPARENT);
c_oPropSheet.ModifyStyleEx(0, WS_EX_CONTROLPARENT|WS_EX_WINDOWEDGE);
c_oPropSheet.ModifyStyle( WS_DLGFRAME, WS_TABSTOP );
CRect a_oRect;
c_oPropSheet.GetWindowRect( &a_oRect );
c_iDefaultPropSheetHeight = a_oRect.Height();
// Restore some GUI settings.
a_roSettings.c_iActiveSearchTab = max( a_roSettings.c_iActiveSearchTab, 0 );
a_roSettings.c_iActiveSearchTab = min( a_roSettings.c_iActiveSearchTab, c_oPropSheet.GetPageCount() );
c_oPropSheet.SetActivePage( a_roSettings.c_iActiveSearchTab );
if( a_roSettings.c_oMainRect.left == -1 ||
a_roSettings.c_oMainRect.top == -1 ||
a_roSettings.c_oMainRect.right == -1 ||
a_roSettings.c_oMainRect.bottom == -1 )
ResizeParentToFit(FALSE);
// Remove the client edge. I like the flat look a little more.
ModifyStyleEx( WS_EX_CLIENTEDGE, 0, SWP_DRAWFRAME );
// Set the initial text of the Start/Stop button.
CString a_sTemp( (LPCTSTR)IDS_STR_START );
c_oStartStop.SetWindowText( a_sTemp );
c_oTreeImages.Create( IDB_TREE_ICONS, 16, 0, RGB( 255, 0, 255 ) );
c_oFileTree.SetImageList( &c_oTreeImages, TVSIL_NORMAL );
UpdateResultsControls( 0, COleDateTimeSpan( 0, 0, 0, 0 ) );
c_oPreprocess.SetCheck( a_roSettings.c_bPreprocess != 0 );
}
}
/////////////////////////////////////////////////////////////////////////////
// CIncFinderView diagnostics
#ifdef _DEBUG
void CIncFinderView::AssertValid() const
{
CFormView::AssertValid();
}
void CIncFinderView::Dump(CDumpContext& dc) const
{
CFormView::Dump(dc);
}
CIncFinderDoc* CIncFinderView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CIncFinderDoc)));
return (CIncFinderDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CIncFinderView non-message functions
/////////////////////////////////////////////////////////////////////////////
//
// ------------------------------------------------------------------
//
void CIncFinderView::OnFinished()
{
PostMessage( INC_FINDER_WM_FINISHED, 0, 0 );
}
//
// ------------------------------------------------------------------
//
void CIncFinderView::OnFileStart( CParsedFile * p_poFile )
{
PostMessage( INC_FINDER_WM_FILE_START, 0, (LPARAM)p_poFile );
}
//
// ------------------------------------------------------------------
//
void CIncFinderView::OnFileComplete( CParsedFile * p_poResults )
{
PostMessage( INC_FINDER_WM_FILE_FINISHED, 0, (LPARAM)p_poResults );
}
//
// ------------------------------------------------------------------
//
HTREEITEM CIncFinderView::InsertFile( HTREEITEM p_hParent, CParsedFile * p_poFile, BOOL & p_rbHasMultipleIncluded )
{
BOOL a_bRecurse = TRUE;
// Determine the image we will use for the file.
int a_iImage = TREE_IMAGE_FILE;
if( p_poFile->GetNotFoundFlag() )
a_iImage = TREE_IMAGE_NOT_FOUND;
else
if( p_poFile->GetAlreadyIncluded() )
{
a_iImage = TREE_IMAGE_MULTIPLE;
// The file was already included. We don't want to recurse because
// we might infinitely recurse (i.e, "rpc.h" includes "windows.h", which includes "rpc.h").
a_bRecurse = FALSE;
p_rbHasMultipleIncluded = TRUE;
}
if( !p_poFile->GetNotFoundFlag() && c_bIsShowingOnlyUnfoundFiles && p_hParent != TVI_ROOT )
// We don't want to insert this item.
return NULL;
CTCharString a_sFileName = GetDisplayFileName( p_poFile, p_hParent );
// Insert the file into the tree.
HTREEITEM a_hFileRootItem = c_oFileTree.InsertItem( a_sFileName.c_str(), a_iImage, a_iImage, p_hParent );
c_oFileTree.SetItemData( a_hFileRootItem, (DWORD)p_poFile );
p_poFile->SetAlreadyIncluded( true );
if( a_bRecurse )
{
// Now recursively insert all the file's included files.
CParsedFileArray & a_roIncludedFiles = p_poFile->GetIncludedFiles();
HTREEITEM a_hFileItem = a_hFileRootItem;
for( int i = 0; i<a_roIncludedFiles.size(); ++i )
{
if( a_roIncludedFiles[i] == p_poFile )
{
// The current file included itself. Insert it, with a special icon.
a_sFileName = GetDisplayFileName( a_roIncludedFiles[i], p_hParent );
HTREEITEM a_hRecursiveItem = c_oFileTree.InsertItem( a_sFileName.c_str(), TREE_IMAGE_RECURSE, TREE_IMAGE_RECURSE, a_hFileRootItem );
c_oFileTree.SetItemData( a_hRecursiveItem, (DWORD)a_roIncludedFiles[i] );
continue;
}
a_hFileItem = InsertFile( a_hFileRootItem, a_roIncludedFiles[i], p_rbHasMultipleIncluded );
}
}
// Check if p_poFile has any files which are included more than once so we can change it's icon.
if( p_hParent == TVI_ROOT && p_rbHasMultipleIncluded )
c_oFileTree.SetItem( a_hFileRootItem, TVIF_IMAGE|TVIF_SELECTEDIMAGE, NULL, TREE_IMAGE_MULTIPLE, TREE_IMAGE_MULTIPLE, 0, 0, 0 );
return a_hFileRootItem;
}
//
// ------------------------------------------------------------------
//
CTCharString CIncFinderView::GetDisplayFileName( CParsedFile * p_poFile, HTREEITEM p_hParentLevel )
{
if( !c_bIsShowingRelativePaths )
return p_poFile->GetFileName();
const CTCharString & a_rsTemp = p_poFile->GetFileName();
TCHAR a_szFileExt[MAX_PATH + 1] = {0};
TCHAR a_szFileName[MAX_PATH + 1] = {0};
TCHAR a_szFileDir[MAX_PATH + 1] = {0};
_tsplitpath( a_rsTemp.c_str(), NULL, a_szFileDir, a_szFileName, a_szFileExt );
CTCharString a_sFinal;
a_sFinal = a_szFileName;
a_sFinal += a_szFileExt;
return a_sFinal;
// Well, this was an attempt at showing the relative path names...but it's not completed yet.
/*
if( p_hParentLevel == TVI_ROOT )
{
a_sFinal = a_szFileName;
a_sFinal += a_szFileExt;
}
else
{
CParsedFile * a_poParentFile = (CParsedFile*)c_oFileTree.GetItemData( p_hParentLevel );
const CTCharString & a_rsParentPath = a_poParentFile->GetFileName();
const TCHAR * a_pszFileBase = _tcsstr( a_rsParentPath.c_str(), a_szFileDir );
if( !a_pszFileBase )
{
a_sFinal = a_rsTemp.c_str();
}
else
{
a_pszFileBase += _tcslen( a_szFileDir );
a_sFinal = a_pszFileBase;
a_sFinal += a_szFileName;
a_sFinal += a_szFileExt;
}
}
return a_sFinal;
*/
}
//
// ------------------------------------------------------------------
//
void CIncFinderView::ClearParsedFiles()
{
if( IsWindow( c_oFileTree ) )
{
c_oFileTree.SetRedraw( FALSE );
// Clear the data from the tree.
c_oFileTree.DeleteAllItems();
c_oFileTree.SetRedraw( TRUE );
}
// Have the doc clear it's data as well.
GetDocument()->ClearResults();
}
//
// ------------------------------------------------------------------
//
void CIncFinderView::UpdateResultsControls( unsigned long p_ulFiles, COleDateTimeSpan & p_roProcessTime )
{
TCHAR a_szTemp[64] = {0};
_stprintf( a_szTemp, _T("%d"), p_ulFiles );
c_oFilesProcessed.SetWindowText( a_szTemp );
c_oProcessingTime.SetWindowText( p_roProcessTime.Format( _T("%H:%M:%S") ) );
}
//
// ------------------------------------------------------------------
//
void CIncFinderView::RepopulateTree()
{
CWaitCursor a_oWait;
c_oFileTree.SetRedraw( FALSE );
// Clear the tree.
c_oFileTree.DeleteAllItems();
// Repopulate the tree now.
CParsedFileArray & a_roFiles = GetDocument()->GetTopLevelFiles();
CParsedFileArray::iterator a_oIter;
int i = 0;
for( a_oIter = a_roFiles.begin(); a_oIter != a_roFiles.end(); ++a_oIter )
{
CParsedFile * a_poFile = *a_oIter;
BOOL a_bHasMultipleIncluded = FALSE;
InsertFile( TVI_ROOT, a_poFile, a_bHasMultipleIncluded );
// Clear the "already included" flag so the file can be recursed next time.
a_poFile->SetAlreadyIncluded( false );
++i;
}
c_oFileTree.SetRedraw( TRUE );
}
//
// ------------------------------------------------------------------
//
void CIncFinderView::LaunchFile( CParsedFile * p_poFile )
{
CSettings & a_roSettings = CSettings::GetSettings();
CString a_sFilename;
a_sFilename.Format( _T("\"%s\""), p_poFile->GetFileName().c_str() );
if( a_roSettings.c_bViewWithAssociatedViewer )
{
// ShellExecute the selected file, with the associated program.
ShellExecute( NULL, _T("Open"), a_sFilename, NULL, NULL, SW_SHOWNORMAL );
}
else
{
// ShellExecute the selected file, with the custom command.
CString a_sCommand = a_roSettings.c_sCustomSourceViewerCommand.c_str();
ShellExecute( NULL, _T("Open"), a_sCommand, a_sFilename, NULL, SW_SHOWNORMAL );
}
}
//
// ------------------------------------------------------------------
//
HTREEITEM CIncFinderView::SearchTree( BOOL p_bStart, HTREEITEM p_hCur, const TCHAR * p_pszText )
{
HTREEITEM a_hCurrent = NULL;
if( p_hCur && !p_bStart )
{
// Test the current item.
CParsedFile * a_poFile = (CParsedFile*)c_oFileTree.GetItemData( p_hCur );
//if( WildcardCompare( a_poFile->GetFileName().c_str(), p_pszText ) )
if( _tcsstr( a_poFile->GetFileName().c_str(), p_pszText ) )
{
return p_hCur;
}
}
// Check the item's children first.
a_hCurrent = c_oFileTree.GetChildItem( p_hCur );
if( a_hCurrent )
{
a_hCurrent = SearchTree( FALSE, a_hCurrent, p_pszText );
if( a_hCurrent )
return a_hCurrent;
}
// Now check siblings.
a_hCurrent = p_hCur;
while( 1 )
{
a_hCurrent = c_oFileTree.GetNextSiblingItem( a_hCurrent );
if( !a_hCurrent )
break;
// We found one to search, so search it...
HTREEITEM a_hItem = SearchTree( FALSE, a_hCurrent, p_pszText );
if( a_hItem )
return a_hItem;
else
break;
}
if( p_bStart )
{
// Try to work our way back to another branch above us, that has more unchecked siblings.
a_hCurrent = p_hCur;
while( 1 )
{
a_hCurrent = c_oFileTree.GetParentItem( a_hCurrent );
if( !a_hCurrent )
break;
HTREEITEM a_hSibling = c_oFileTree.GetNextSiblingItem( a_hCurrent );
if( a_hSibling )
{
// We found a sibling of a parent to search.
HTREEITEM a_hTest = SearchTree( FALSE, a_hSibling, p_pszText );
if( a_hTest )
return a_hTest;
}
}
}
return NULL;
}
//
// ------------------------------------------------------------------
//
void CIncFinderView::DoSearch( const TCHAR * p_pszText )
{
HTREEITEM a_hSelection = c_oFileTree.GetSelectedItem();
if( !a_hSelection )
a_hSelection = c_oFileTree.GetRootItem();
if( a_hSelection )
{
// Search the tree for the next suitable item.
HTREEITEM a_hNewItem = SearchTree( TRUE, a_hSelection, p_pszText );
if( a_hNewItem )
{
c_oFileTree.SelectItem( a_hNewItem );
}
}
}
//
// ------------------------------------------------------------------
//
/////////////////////////////////////////////////////////////////////////////
// CIncFinderView message handlers
/////////////////////////////////////////////////////////////////////////////
void CIncFinderView::OnSize(UINT nType, int cx, int cy)
{
if( !IsWindow( c_oPropSheet ) )
// Our controls haven't been subclassed yet.
return;
// Resize our controls.
//
int a_iBigBorder = 0;
CRect a_oRect;
c_oFileTree.GetWindowRect( &a_oRect );
ScreenToClient( &a_oRect );
a_iBigBorder = a_oRect.left;
c_oTopBorder.GetWindowRect( &a_oRect );
c_oTopBorder.MoveWindow( 0,
0,
cx,
a_oRect.Height() );
CRect a_oButtonRect;
c_oStartStop.GetWindowRect( &a_oButtonRect );
ScreenToClient( &a_oButtonRect );
c_oPropSheet.GetWindowRect( &a_oRect );
c_oPropSheet.MoveWindow( a_iBigBorder / 2,
a_iBigBorder / 2,
cx - a_oButtonRect.Width() - a_iBigBorder * 2,
c_iDefaultPropSheetHeight );
c_oStartStop.MoveWindow( cx - a_oButtonRect.Width() - a_iBigBorder,
a_oButtonRect.top,
a_oButtonRect.Width(),
a_oButtonRect.Height() );
c_oProcessingAnim.GetWindowRect( &a_oRect );
ScreenToClient( &a_oRect );
c_oProcessingAnim.MoveWindow( cx - a_oButtonRect.Width() - a_iBigBorder + (abs(a_oButtonRect.Width()-a_oRect.Width()))/2,
a_oRect.top,
a_oRect.Width(),
a_oRect.Height() );
c_oMiddleBorder.GetWindowRect( &a_oRect );
ScreenToClient( &a_oRect );
c_oMiddleBorder.MoveWindow( a_oRect.left,
a_oRect.top,
cx - a_oRect.left * 2,
a_oRect.Height() );
c_oFileTree.GetWindowRect( &a_oRect );
ScreenToClient( &a_oRect );
c_oFileTree.MoveWindow( a_oRect.left,
a_oRect.top,
cx - a_iBigBorder * 2,
cy - a_oRect.top - a_iBigBorder );
}
//
// ------------------------------------------------------------------
//
void CIncFinderView::OnStartStop()
{
UINT a_uiTextID = 0;
CIncludeFinder & a_roFinder = GetDocument()->GetIncludeFinder();
CIncludeFinderInfo & a_roFindInfo = GetDocument()->GetFindInfo();
if( a_roFinder.IsRunning() )
{
CWaitCursor a_oWait;
// Stop the include finder thread.
a_roFinder.Stop();
a_uiTextID = IDS_STR_START;
}
else
{
CWaitCursor a_oWait;
c_poCurrentSearchPage = static_cast<CSearchPropertyPage*>(c_oPropSheet.GetPage( c_oPropSheet.GetActiveIndex() ));
CFileIterator * a_poIter = c_poCurrentSearchPage->PrepareToStart();
if( !a_poIter )
{
// The page doesn't want us to start.
return;
}
((CFrameWnd*)AfxGetMainWnd())->SetMessageText( IDS_STR_STARTING_UP );
c_oProcessingAnim.Play( 0, -1, -1 );
// Clear the current data.
ClearParsedFiles();
a_roFindInfo.SetOptions( a_poIter, (c_oPreprocess.GetCheck() == 1) );
UpdateResultsControls( 0, COleDateTimeSpan( 0, 0, 0, 0 ) );
// Start the parsing.
a_roFinder.Start();
a_uiTextID = IDS_STR_STOP;
}
// Change the text of the start/stop button.
CString a_sText( (LPCTSTR)a_uiTextID );
c_oStartStop.SetWindowText( a_sText );
}
//
// ------------------------------------------------------------------
//
LRESULT CIncFinderView::OnFileFinished( WPARAM wParam, LPARAM lParam )
{
// Add the file to the doc's top level file list.
CParsedFile * a_poFile = (CParsedFile*)lParam;
GetDocument()->AddTopLevelFile( a_poFile );
// Add the file into the tree, recursively.
BOOL a_bHasMultipleIncluded = FALSE;
InsertFile( TVI_ROOT, a_poFile, a_bHasMultipleIncluded );
// Set the 'already included' flag back to false, so the file's included files will show up recursively
// in the next file they may be included in.
a_poFile->SetAlreadyIncluded( false );
return 0;
}
//
// ------------------------------------------------------------------
//
LRESULT CIncFinderView::OnFileStart( WPARAM wParam, LPARAM lParam )
{
CParsedFile * a_poFile = (CParsedFile*)lParam;
// Set the text of the status bar to the path of the file we are parsing.
CString a_sTemp;
a_sTemp.Format( IDS_STR_PROCESSING, a_poFile->GetFileName().c_str() );
((CFrameWnd*)AfxGetMainWnd())->SetMessageText( a_sTemp );
// Update the two static controls which show the number of files processed and the amount of time it took so far.
CIncludeFinderInfo & a_roFindInfo = GetDocument()->GetFindInfo();
a_roFindInfo.c_ulFilesProcessed++;
UpdateResultsControls( a_roFindInfo.c_ulFilesProcessed, COleDateTime::GetCurrentTime() - a_roFindInfo.c_oStartTime );
return 0;
}
//
// ------------------------------------------------------------------
//
LRESULT CIncFinderView::OnFinished( WPARAM wParam, LPARAM lParam )
{
// Set the text of the start/stop button to "Start"
CString a_sText( (LPCTSTR)IDS_STR_START );
c_oStartStop.SetWindowText( a_sText );
// Set the status bar text to the idle msg.
((CFrameWnd*)AfxGetMainWnd())->SetMessageText( AFX_IDS_IDLEMESSAGE );
// Update the two static controls which show the number of files processed and the amount of time it took.
CIncludeFinderInfo & a_roFindInfo = GetDocument()->GetFindInfo();
UpdateResultsControls( a_roFindInfo.c_ulFilesProcessed, a_roFindInfo.c_oStopTime - a_roFindInfo.c_oStartTime );
c_oFileTree.SetRedraw( TRUE );
if( c_poCurrentSearchPage )
c_poCurrentSearchPage->SearchStopped();
// Stop the animation control.
c_oProcessingAnim.Stop();
return 0;
}
//
// ------------------------------------------------------------------
//
void CIncFinderView::OnDestroy()
{
CIncludeFinder & a_roFinder = GetDocument()->GetIncludeFinder();
// Stop the include finder thread if it's running.
if( a_roFinder.IsRunning() )
{
CWaitCursor a_oWait;
a_roFinder.Stop();
}
// Save settings.
CSettings & a_roSettings = CSettings::GetSettings();
a_roSettings.c_bPreprocess = c_oPreprocess.GetCheck() != 0;
a_roSettings.c_iActiveSearchTab = c_oPropSheet.GetActiveIndex();
CFormView::OnDestroy();
}
//
// ------------------------------------------------------------------
//
void CIncFinderView::OnContextMenu(CWnd* pWnd, CPoint point)
{
BOOL a_bKeyStroke = FALSE;
CWnd * a_poFocus = GetFocus();
if (point.x == -1 && point.y == -1)
{
// Keystroke invocation.
CRect rect;
a_poFocus->GetClientRect(rect);
a_poFocus->ClientToScreen(rect);
point = rect.TopLeft();
point.Offset(5, 5);
a_bKeyStroke = TRUE;
}
// Determine which menu to show.
CRect a_oRect;
c_oFileTree.GetWindowRect( &a_oRect );
UINT a_uiMenu = 0;
if( a_oRect.PtInRect( point ) || (a_bKeyStroke && a_poFocus == &c_oFileTree) )
a_uiMenu = IDR_TREE_CONTEXT;
else
return;
// Load and show the context menu.
CMenu menu;
VERIFY(menu.LoadMenu(a_uiMenu));
CMenu* pPopup = menu.GetSubMenu(0);
ASSERT(pPopup != NULL);
CWnd* pWndPopupOwner = this;
while (pWndPopupOwner->GetStyle() & WS_CHILD)
pWndPopupOwner = pWndPopupOwner->GetParent();
pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,
point.x,
point.y,
pWndPopupOwner);
}
//
// ------------------------------------------------------------------
//
void CIncFinderView::OnTreeOpenfile()
{
HTREEITEM a_hItem = c_oFileTree.GetSelectedItem();
CParsedFile * a_poFile = (CParsedFile*)c_oFileTree.GetItemData( a_hItem );
LaunchFile( a_poFile );
}
//
// ------------------------------------------------------------------
//
void CIncFinderView::OnUpdateTreeOpenfile(CCmdUI* pCmdUI)
{
HTREEITEM a_hItem = c_oFileTree.GetSelectedItem();
pCmdUI->Enable( a_hItem != NULL );
}
//
// ------------------------------------------------------------------
//
void CIncFinderView::OnViewUnfoundFiles()
{
// Toggle the flag.
c_bIsShowingOnlyUnfoundFiles = !c_bIsShowingOnlyUnfoundFiles;
// Repopulate the tree.
RepopulateTree();
}
//
// ------------------------------------------------------------------
//
void CIncFinderView::OnUpdateViewUnfoundFiles(CCmdUI* pCmdUI)
{
pCmdUI->Enable( !GetDocument()->GetIncludeFinder().IsRunning() );
pCmdUI->SetCheck( c_bIsShowingOnlyUnfoundFiles );
}
//
// ------------------------------------------------------------------
//
void CIncFinderView::OnViewRelativePaths()
{
// Toggle the flag.
c_bIsShowingRelativePaths = !c_bIsShowingRelativePaths;
// Repopulate the tree.
RepopulateTree();
}
//
// ------------------------------------------------------------------
//
void CIncFinderView::OnUpdateViewRelativePaths(CCmdUI* pCmdUI)
{
pCmdUI->Enable( !GetDocument()->GetIncludeFinder().IsRunning() );
pCmdUI->SetCheck( c_bIsShowingRelativePaths );
}
//
// ------------------------------------------------------------------
//
void CIncFinderView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
{
RepopulateTree();
}
//
// ------------------------------------------------------------------
//
void CIncFinderView::OnDblclkFileTree(NMHDR* pNMHDR, LRESULT* pResult)
{
CPoint a_oPoint( 0, 0 );
GetCursorPos( &a_oPoint );
c_oFileTree.ScreenToClient( &a_oPoint );
// If they double-clicked on a leaf item, we'll open the file.
HTREEITEM a_hItem = c_oFileTree.HitTest( a_oPoint );
if( a_hItem != NULL && c_oFileTree.GetChildItem( a_hItem ) == NULL )
{
CParsedFile * a_poFile = (CParsedFile*)c_oFileTree.GetItemData( a_hItem );
LaunchFile( a_poFile );
}
*pResult = 0;
}
//
// ------------------------------------------------------------------
//
void CIncFinderView::OnEditFind()
{
if( !c_poFindDlg )
{
CFindReplaceDialog * c_poFindDlg = new CFindReplaceDialog;
c_poFindDlg->m_fr.Flags |= FR_HIDEUPDOWN|FR_HIDEMATCHCASE|FR_HIDEWHOLEWORD;
c_poFindDlg->Create( TRUE, c_sLastSearchText.c_str(), NULL, FR_DOWN, this );
}
}
//
// ------------------------------------------------------------------
//
LRESULT CIncFinderView::OnFindReplace(WPARAM wParam, LPARAM lParam)
{
CFindReplaceDialog * a_poDlg = CFindReplaceDialog::GetNotifier( lParam );
if( NULL != a_poDlg )
{
if( a_poDlg->FindNext() )
{
c_sLastSearchText = a_poDlg->GetFindString();
DoSearch( c_sLastSearchText.c_str() );
}
}
return 0;
}
//
// ------------------------------------------------------------------
//
void CIncFinderView::OnEditFindNext()
{
DoSearch( c_sLastSearchText.c_str() );
}
//
// ------------------------------------------------------------------
//
void CIncFinderView::OnUpdateEditFindNext(CCmdUI* pCmdUI)
{
pCmdUI->Enable( c_sLastSearchText.length() != 0 );
}
//
// ------------------------------------------------------------------
//