//====================================================================
// 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();
}
}
//
// ------------------------------------------------------------------
//