Click here to Skip to main content
15,882,163 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 380K   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: Document class.
//
//====================================================================

#include "stdafx.h"
#include "IncFinder.h"

#include "IncFinderDoc.h"
#include "IncFinderView.h"

#include "ConfigureSourceViewerDlg.h"

#include "pugxml.h"

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

/////////////////////////////////////////////////////////////////////////////
// CIncFinderDoc

IMPLEMENT_DYNCREATE(CIncFinderDoc, CDocument)

BEGIN_MESSAGE_MAP(CIncFinderDoc, CDocument)
	//{{AFX_MSG_MAP(CIncFinderDoc)
	ON_COMMAND(ID_EDIT_CONFIGURE_SHELLEX, OnEditConfigureShellex)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CIncFinderDoc construction/destruction

CIncFinderDoc::CIncFinderDoc() :
   c_bIgnoreSetPathName( false )
{
   c_oIncludeFinder.SetInfo( &c_oFindInfo );
}

CIncFinderDoc::~CIncFinderDoc()
{
}

BOOL CIncFinderDoc::OnNewDocument()
{
	if (!CDocument::OnNewDocument())
		return FALSE;

   c_oFindInfo.c_poStatusNotifier = (CIncFinderView*)m_viewList.GetHead();

	return TRUE;
}



/////////////////////////////////////////////////////////////////////////////
// CIncFinderDoc serialization

void CIncFinderDoc::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
		// TODO: add storing code here
	}
	else
	{
		// TODO: add loading code here
	}
}

/////////////////////////////////////////////////////////////////////////////
// CIncFinderDoc diagnostics

#ifdef _DEBUG
void CIncFinderDoc::AssertValid() const
{
	CDocument::AssertValid();
}

void CIncFinderDoc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CIncFinderDoc non-command functions.
/////////////////////////////////////////////////////////////////////////////

void CIncFinderDoc::ClearResults()
{
   // Clear our current find results.
   CParsedFile * a_poFile = NULL;
   CParsedFileList::iterator a_oIter = c_oFindInfo.c_oResults.begin();
   while( a_oIter != c_oFindInfo.c_oResults.end() )
   {
      a_poFile = *a_oIter;
      
      delete a_poFile;

      a_oIter++;
   }

   c_oFindInfo.c_oResults.clear();
   c_oTopLevelFiles.clear();
}
//
// ------------------------------------------------------------------
//

/////////////////////////////////////////////////////////////////////////////
// CIncFinderDoc commands
/////////////////////////////////////////////////////////////////////////////

BOOL CIncFinderDoc::OnSaveDocument(LPCTSTR lpszPathName) 
{
   FILE * a_pstFile = _tfopen( lpszPathName, _T("w+t") );
   if( !a_pstFile )
      return FALSE;
   
   _ftprintf( a_pstFile, _T("<?xml version=\"1.0\"?>\n") );
   
   // I was thinking about doing some XSL stylesheets, but don't quite have the time yet, so this will remain until
   // I do get the time...
   /*
   TCHAR a_szResLocation[MAX_PATH + 64] = {0};
   GetModuleFileName( NULL, a_szResLocation, MAX_PATH+1 );
   _ftprintf( a_pstFile, _T("<?xml-stylesheet type=\"text/xsl\" href=\"res://%s/#%d\"?>\n"), a_szResLocation, IDR_DEFAULT_STYLESHEET );
   */

   _ftprintf( a_pstFile, _T("<parseResults>\n") );
   
   // Save all the top level files to the output file.
   for( int i = 0; i<c_oTopLevelFiles.size(); ++i )
   {
      CParsedFile * a_poFile = c_oTopLevelFiles[i];
      a_poFile->SaveToFile( a_pstFile );
      a_poFile->SetAlreadyIncluded( false );
   }

   _ftprintf( a_pstFile, _T("</parseResults>\n") );

   fclose( a_pstFile );

   return TRUE;
}
//
// ------------------------------------------------------------------
//
BOOL CIncFinderDoc::OnOpenDocument(LPCTSTR lpszPathName) 
{
	if( c_oIncludeFinder.IsRunning() )
   {
      // We cannot let the user load a file while the thread is running.
      // There might be messages being passed between the thread and the view, and we can't
      // just invalidate that data.
      AfxMessageBox( IDS_ERR_CANNOT_LOAD_FILE );
      c_bIgnoreSetPathName = true;
      return TRUE;
   }
   
   c_bIgnoreSetPathName = false;

   if (!CDocument::OnOpenDocument(lpszPathName))
      return FALSE;

   CPugXmlParser a_oParser;
	if( !a_oParser.ParseFile( lpszPathName ) )
	{
   	AfxMessageBox( IDS_ERR_INVALID_XML );
      return FALSE;
	}
   
   CPugXmlBranch a_oParseResults = a_oParser.GetRoot().GetChildAt( 0 );
   if( a_oParseResults.IsNull() || !a_oParseResults.IsNamed( _T("parseResults") ) )
	{
   	AfxMessageBox( IDS_ERR_INVALID_XML );
      return FALSE;
	}

   for( int i = 0; i<a_oParseResults.GetChildrenCount(); ++i )
   {
      CPugXmlBranch a_oFile = a_oParseResults.GetChildAt( i );
      if( !a_oFile.IsNamed( _T("File") ) )
         continue;

      CParsedFile * a_poFile = new CParsedFile( a_oFile.GetAttribute( _T("Name") ) );
      a_poFile->ReadFromXml( &a_oFile, c_oFindInfo.c_oResults );

      c_oTopLevelFiles.push_back( a_poFile );
      c_oFindInfo.c_oResults.push_back( a_poFile );
   }

	return TRUE;
}
//
// ------------------------------------------------------------------
//
void CIncFinderDoc::DeleteContents() 
{
	if( c_oIncludeFinder.IsRunning() )
   {
      // We don't want the include finder thread to be running, because the view
      // could be passing data to itself via PostMessage, and we would be deleting that
      // data.  This shouldn't ever happen, but if it does, you know why.
      ASSERT( FALSE );
   }

   // Clear out the results.
	ClearResults();

   CDocument::DeleteContents();
}
//
// ------------------------------------------------------------------
//
void CIncFinderDoc::OnEditConfigureShellex() 
{
   CConfigureSourceViewerDlg a_oDlg;
   a_oDlg.DoModal();
}
//
// ------------------------------------------------------------------
//
void CIncFinderDoc::SetPathName(LPCTSTR lpszPathName, BOOL bAddToMRU) 
{
	if( c_bIgnoreSetPathName )
      return;
   
   CDocument::SetPathName(lpszPathName, bAddToMRU);
}
//
// ------------------------------------------------------------------
//

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