Click here to Skip to main content
15,879,184 members
Articles / Desktop Programming / MFC

Include File Hierarchy Viewer

Rate me:
Please Sign up or sign in to vote.
4.84/5 (108 votes)
29 Jul 2003CPOL8 min read 379.5K   4.5K   151  
A tool to view the include file hierarchy of your source code.
//====================================================================
// 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: Workspace search options page.
//
//====================================================================

#include "stdafx.h"
#include "incfinder.h"
#include "WorkspaceSearchPage.h"

#include "Settings.h"
#include "FileIterator.h"

#include "VC6Objects.h"
#include "VC7Objects.h"

#include "Parser.h"

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

/////////////////////////////////////////////////////////////////////////////
// CWorkspaceFileIterator Implementation.
/////////////////////////////////////////////////////////////////////////////

class CWorkspaceFileIterator : public CFileIterator
{
public:
   CWorkspaceFileIterator();
   virtual ~CWorkspaceFileIterator();

   void                 ParseOptions( CDSWorkspace * p_poWorkspace,
                                      const TCHAR *  p_pszFileMasks,
                                      const TCHAR *  p_pszConfiguration );

   virtual void         Prepare( HANDLE p_hEvent,
                                 CParser * p_poParser );
   virtual bool         GetNextFile( CTCharString & p_rsFile );

protected:
   CDSWorkspace *       c_poWorkspace;
   CStdStringArray      c_oFileMasks;
   CTCharString         c_sDesiredConfiguration;
   CDSConfiguration *   c_poCurConfig;
   
   CDSProjectArray      c_oProjects;
   CDSFileArray         c_oParseFileList;

   int                  c_iCurrentProject;
   int                  c_iCurrentFile;
};


CWorkspaceFileIterator::CWorkspaceFileIterator() :
   c_poWorkspace( NULL ),
   c_poCurConfig( NULL ),
   c_iCurrentProject( 0 ),
   c_iCurrentFile( 0 )
{
}
//
// ------------------------------------------------------------------
//
CWorkspaceFileIterator::~CWorkspaceFileIterator()
{
   c_poWorkspace = NULL;
   c_poCurConfig = NULL;
}
//
// ------------------------------------------------------------------
//
void CWorkspaceFileIterator::ParseOptions( CDSWorkspace * p_poWorkspace,
                                           const TCHAR *  p_pszFileMasks,
                                           const TCHAR *  p_pszConfiguration )
{
   c_poWorkspace = p_poWorkspace;
   c_sDesiredConfiguration = p_pszConfiguration;
   
   c_oFileMasks.clear();

   // Parse file masks into a list..
   ParseSeparatedList( p_pszFileMasks, _T(";"), c_oFileMasks );
}
//
// ------------------------------------------------------------------
//
void CWorkspaceFileIterator::Prepare( HANDLE p_hEvent,
                                      CParser * p_poParser )
{
   CFileIterator::Prepare( p_hEvent, p_poParser );

   c_iCurrentProject = -1;
   c_iCurrentFile = 0;
   c_oParseFileList.clear();
   c_oProjects.clear();
   
   c_poCurConfig = NULL;

   // Load all the projects out of the workspace.
   c_poWorkspace->GetAllProjects( c_oProjects );
}
//
// ------------------------------------------------------------------
//
bool CWorkspaceFileIterator::GetNextFile( CTCharString & p_rsFile )
{
   while( 1 )
   {
      if( c_iCurrentFile >= c_oParseFileList.size() )
      {
         c_iCurrentProject++;
         if( c_iCurrentProject >= c_oProjects.size() )
            // We're done.
            return false;
   
         c_iCurrentFile = 0;
         
         // Get the next project.
         c_oParseFileList.clear();
         CDSProject * a_poProject = c_oProjects[c_iCurrentProject];

         // Try to get the desired configuration from the project.  If the project doesn't contain
         // a configuration by that name, it will give us back it's first configuration.
         c_poCurConfig = a_poProject->GetConfiguration( c_sDesiredConfiguration.c_str() );
         if( !c_poCurConfig )
            // The project doesn't have any configurations?
            continue;

         // Load the file list out of the next project.
         a_poProject->GetAllMatchingFiles( c_oParseFileList, c_oFileMasks );
      }
      else
         break;
   }
   
   CDSFile * a_poFile = c_oParseFileList[c_iCurrentFile];
   
   // Modify the parser's include directories and defines, based on the current file's configuration settings.
   
   CDSParsedSettings a_oSettings;
   a_poFile->GetFileSettings( c_poCurConfig, a_oSettings );
   
   c_poParser->SetSettings( a_oSettings );

   p_rsFile = a_poFile->GetPath();
   c_iCurrentFile++;

   return true;
}
//
// ------------------------------------------------------------------
//


/////////////////////////////////////////////////////////////////////////////
// CWorkspaceSearchPage Implementation.
/////////////////////////////////////////////////////////////////////////////

IMPLEMENT_DYNCREATE(CWorkspaceSearchPage, CSearchPropertyPage)

CWorkspaceSearchPage::CWorkspaceSearchPage() :
   CSearchPropertyPage(CWorkspaceSearchPage::IDD),
   c_poWorkspace( NULL )
{
	//{{AFX_DATA_INIT(CWorkspaceSearchPage)
	//}}AFX_DATA_INIT
   
   c_poIterator = new CWorkspaceFileIterator;
}
//
// ------------------------------------------------------------------
//
CWorkspaceSearchPage::~CWorkspaceSearchPage()
{
   if( c_poIterator )
   {
      delete c_poIterator;
      c_poIterator = NULL;
   }

   if( c_poWorkspace )
   {
      delete c_poWorkspace;
      c_poWorkspace = NULL;
   }
}
//
// ------------------------------------------------------------------
//
void CWorkspaceSearchPage::DoDataExchange(CDataExchange* pDX)
{
	CSearchPropertyPage::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CWorkspaceSearchPage)
	DDX_Control(pDX, IDC_WORKSPACE_LABEL, c_oWorkspaceLabel);
	DDX_Control(pDX, IDC_WORKSPACE_LOAD, c_oLoadWorkspace);
	DDX_Control(pDX, IDC_BROWSE_WORKSPACE, c_oBrowseWorkspace);
	DDX_Control(pDX, IDC_SEARCH_WORKSPACE, c_oSearchWorkspace);
	DDX_Control(pDX, IDC_FILE_MASK, c_oFileMask);
	DDX_Control(pDX, IDC_CONFIGURATION, c_oConfiguration);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CWorkspaceSearchPage, CSearchPropertyPage)
	//{{AFX_MSG_MAP(CWorkspaceSearchPage)
	ON_WM_SIZE()
	ON_BN_CLICKED(IDC_BROWSE_WORKSPACE, OnBrowseWorkspace)
	ON_BN_CLICKED(IDC_WORKSPACE_LOAD, OnWorkspaceLoad)
	ON_WM_DESTROY()
	ON_CBN_SELCHANGE(IDC_SEARCH_WORKSPACE, OnSelchangeSearchWorkspace)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CWorkspaceSearchPage non-message handlers
/////////////////////////////////////////////////////////////////////////////

CFileIterator * CWorkspaceSearchPage::PrepareToStart()
{
   if( !c_poWorkspace )
   {
      OnWorkspaceLoad();
      if( !c_poWorkspace )
      {
         AfxMessageBox( IDS_ERR_WORKSPACE_LOAD_FAILED );
         return NULL;
      }
   }
   
   if( GetFocus() && GetFocus()->GetParent() == &c_oSearchWorkspace )
      // Change the focus to the file mask control, since we are disabling the workspace control.
      c_oFileMask.SetFocus();
   
   // Disable the workspace controls, so the workspace won't be deleted out from underneath the search thread.
   EnableWorkspace( FALSE );
      
   CString a_sFileMask;
   HandleComboBox( &c_oFileMask, a_sFileMask );
   
   CString a_sConfiguration;
   c_oConfiguration.GetWindowText( a_sConfiguration );

   c_poIterator->ParseOptions( c_poWorkspace,
                               a_sFileMask,
                               a_sConfiguration );

   return c_poIterator;
}
//
// ------------------------------------------------------------------
//
void CWorkspaceSearchPage::EnableWorkspace( BOOL p_bEnable )
{
   c_oLoadWorkspace.EnableWindow( p_bEnable );
   c_oSearchWorkspace.EnableWindow( p_bEnable );
   c_oBrowseWorkspace.EnableWindow( p_bEnable );
   c_oWorkspaceLabel.EnableWindow( p_bEnable );
}
//
// ------------------------------------------------------------------
//
void CWorkspaceSearchPage::SearchStopped()
{
   EnableWorkspace( TRUE );
}
//
// ------------------------------------------------------------------
//

/////////////////////////////////////////////////////////////////////////////
// CWorkspaceSearchPage message handlers
/////////////////////////////////////////////////////////////////////////////

BOOL CWorkspaceSearchPage::OnInitDialog() 
{
	CSearchPropertyPage::OnInitDialog();
	
   CSettings & a_roSettings = CSettings::GetSettings();
   // Load the previous directories and masks from the settings.
   int i = 0;
   for( i = 0; i<a_roSettings.c_oWorkspaces.size(); ++i )
   {
      c_oSearchWorkspace.AddString( a_roSettings.c_oWorkspaces[i].c_str() );
   }
   c_oSearchWorkspace.SetCurSel( 0 );

   for( i = 0; i<a_roSettings.c_oWorkspaceFileMasks.size(); ++i )
   {
      c_oFileMask.AddString( a_roSettings.c_oWorkspaceFileMasks[i].c_str() );
   }
   c_oFileMask.SetCurSel( 0 );

	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}
//
// ------------------------------------------------------------------
//
void CWorkspaceSearchPage::OnSize(UINT nType, int cx, int cy) 
{
	CSearchPropertyPage::OnSize(nType, cx, cy);
	
	if( !IsWindow( c_oSearchWorkspace ) )
      // Our controls haven't been subclassed yet.
      return;

   // Resize our controls.
   //
   
   int a_iBigBorder = 0;
   CRect a_oRect;

   c_oSearchWorkspace.GetWindowRect( &a_oRect );
   ScreenToClient( &a_oRect );
   a_iBigBorder = a_oRect.top;
   
   c_oBrowseWorkspace.GetWindowRect( &a_oRect );
   ScreenToClient( &a_oRect );
   c_oBrowseWorkspace.MoveWindow( cx - a_oRect.Width() - a_iBigBorder*2,
                                  a_oRect.top,
                                  a_oRect.Width(),
                                  a_oRect.Height() );
   c_oBrowseWorkspace.GetWindowRect( &a_oRect );
   ScreenToClient( &a_oRect );
   
   int a_iComboRightEdge = a_oRect.left;

   c_oSearchWorkspace.GetWindowRect( &a_oRect );
   ScreenToClient( &a_oRect );
   c_oSearchWorkspace.MoveWindow( a_oRect.left,
                                  a_oRect.top,
                                  a_iComboRightEdge - a_oRect.left,
                                  a_oRect.Height() );
   
   c_oFileMask.GetWindowRect( &a_oRect );
   ScreenToClient( &a_oRect );
   c_oFileMask.MoveWindow( a_oRect.left,
                           a_oRect.top,
                           a_iComboRightEdge - a_oRect.left,
                           a_oRect.Height() );

   c_oConfiguration.GetWindowRect( &a_oRect );
   ScreenToClient( &a_oRect );
   c_oConfiguration.MoveWindow( a_oRect.left,
                                a_oRect.top,
                                a_iComboRightEdge - a_oRect.left,
                                a_oRect.Height() );
}
//
// ------------------------------------------------------------------
//
void CWorkspaceSearchPage::OnDestroy() 
{
   // Save the directories and masks to the settings.
   CSettings & a_roSettings = CSettings::GetSettings();

   a_roSettings.c_oWorkspaces.clear();
   int i = 0;
   for( i = 0; i<c_oSearchWorkspace.GetCount(); ++i )
   {
      CString a_sTemp;
      c_oSearchWorkspace.GetLBText( i, a_sTemp );
      a_roSettings.c_oWorkspaces.push_back( (LPCTSTR)a_sTemp );
   }

   a_roSettings.c_oWorkspaceFileMasks.clear();
   for( i = 0; i<c_oFileMask.GetCount(); ++i )
   {
      CString a_sTemp;
      c_oFileMask.GetLBText( i, a_sTemp );
      a_roSettings.c_oWorkspaceFileMasks.push_back( (LPCTSTR)a_sTemp );
   }

	CSearchPropertyPage::OnDestroy();
}
//
// ------------------------------------------------------------------
//
void CWorkspaceSearchPage::OnBrowseWorkspace() 
{
   // Let the user browse for a DSW/DSP/SLN/VCPROJ.
   CFileDialog a_oDlg( TRUE, NULL, NULL, OFN_HIDEREADONLY, _T("DevStudio Files (*.dsw;*.dsp;*.sln;*.vcproj)|*.dsw;*.dsp;*.sln;*.vcproj|All Files (*.*)|*.*||") );
   if( a_oDlg.DoModal() == IDOK )
   {
      c_oSearchWorkspace.SetWindowText( a_oDlg.GetPathName() );
   }
}
//
// ------------------------------------------------------------------
//
void CWorkspaceSearchPage::OnWorkspaceLoad() 
{
   CWaitCursor a_oWait;

   CString a_sFile;
   c_oSearchWorkspace.GetWindowText( a_sFile );
   
   int a_iExt = a_sFile.ReverseFind( _T('.') );
   //const TCHAR * a_pszExt = _tcsrchr( a_sFile, _T('.') );
   if( a_iExt == -1 )
   {
      // Can't tell what it is.
      return;
   }
   CString a_sExt = ((LPCTSTR)a_sFile + a_iExt);
   
   c_oConfiguration.ResetContent();

   if( c_poWorkspace )
   {
      delete c_poWorkspace;
      c_poWorkspace = NULL;
   }
   
   // Create the correct type of object.
   bool a_bReadProject = false;
   if( !a_sExt.CompareNoCase( _T(".dsw") ) )
      c_poWorkspace = new CVC6Workspace;
   else
   if( !a_sExt.CompareNoCase( _T(".dsp") ) )
   {
      c_poWorkspace = new CVC6Workspace;
      a_bReadProject = true;
   }
   else
   if( !a_sExt.CompareNoCase( _T(".sln") ) )
      c_poWorkspace = new CVC7Workspace;
   else
   if( !a_sExt.CompareNoCase( _T(".vcproj") ) )
   {
      c_poWorkspace = new CVC7Workspace;
      a_bReadProject = true;
   }
   else
   {
      AfxMessageBox( IDS_ERR_UNSUPPORTED_FILE_TYPE );
      return;
   }

   HandleComboBox( &c_oSearchWorkspace, a_sFile );
   
   // Read the file.
   ParseStatus a_eStatus = PARSE_STATUS_OK;
   if( a_bReadProject )
   {
      a_eStatus = c_poWorkspace->ReadOneProject( a_sFile );
   }
   else
   {
      a_eStatus = c_poWorkspace->ReadWorkspace( a_sFile );
   }
   
   if( a_eStatus != PARSE_STATUS_OK )
   {
      delete c_poWorkspace;
      c_poWorkspace = NULL;

      AfxMessageBox( IDS_ERR_READING_WORKSPACE, MB_ICONERROR );
      return;
   }

   // Load the configuration combo box.
   CDSConfigurationArray a_oConfigurations;
   c_poWorkspace->GetAllConfigurations( a_oConfigurations );
   for( int config = 0; config < a_oConfigurations.size(); ++config )
   {
      CDSConfiguration * a_poConfig = a_oConfigurations[config];
      
      if( c_oConfiguration.FindStringExact( 0, a_poConfig->GetDisplayName() ) == CB_ERR )
         c_oConfiguration.AddString( a_poConfig->GetDisplayName() );
   }
   c_oConfiguration.SetCurSel( 0 );
}
//
// ------------------------------------------------------------------
//
void CWorkspaceSearchPage::OnSelchangeSearchWorkspace() 
{
   if( c_poWorkspace )
   {
      // When they change selection, clear out the current workspace.

      delete c_poWorkspace;
      c_poWorkspace = NULL;
      
      c_oConfiguration.ResetContent();
   }
}
//
// ------------------------------------------------------------------
//

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United States United States
I like to program, I like to sail.

Comments and Discussions