/********************************************************************\
created: 2001/04/07
created: 7:4:2001 20:37
filename: commands.cpp
file path: no matter
file base: commands
file ext: cpp
author: Alex Kucherenko
purpose:
\********************************************************************/
#include "stdafx.h"
#include "ToDoCached.h"
#include "Commands.h"
#include "comutil.h"
#include "ToDoOptions.h"
#include "CLog.h"
#include "CWinLog.h"
#include "CFileLog.h"
#include "CFuncLog.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define MAX_LOG_LEVEL 2
#define LOG_ERROR 0
#define LOG_WARNING 1
#define LOG_INFO 2
#define TRACE_EXCEPTION log.LogString( LOG_WARNING, log.FormatString( \
"File : %s : Line(%d) : Exception : %s : More Info : %s\n", \
__FILE__, \
__LINE__, \
ex.GetErrorMessage().c_str( ), \
ex.GetMoreInfo().c_str( ) ) \
)
// Disable warning on microsoft specific constractions (look into 'note' comments)
#pragma warning( disable : 4239 )
//////////////////////////////////////////////////////////////////////////
// Reorder all records in registry for fixing order in Options combobox and
// all created std::map's - std::map sort hic records by key value
void CCommands::ReorderRegistry( void )
{
CFuncLog log( m_pLog, "CCommands::ReorderRegistry" );
CString tmpName, tmpTitle;
typedef std::map< string, string > TStrMap;
TStrMap arrNames;
long lCount = 0;
DWORD lSize;
char retValue[ 8192 ];
string value1, value2;
value1.reserve( 8192 );
value2.reserve( 8192 );
// read all regisatry records into std::map
while( 1 )
{
lSize = sizeof( retValue );
tmpName.Format( "Search%d", ++lCount );
if( m_RegistryWork.QueryValue( retValue, tmpName, &lSize ) != ERROR_SUCCESS )
break;
else
value1 = retValue;
tmpTitle.Format( "Text%d", lCount );
lSize = sizeof( retValue );
if( m_RegistryWork.QueryValue( retValue, tmpTitle, &lSize ) != ERROR_SUCCESS )
break;
else
value2 = retValue;
arrNames.insert( TStrMap::value_type( value1, value2 ) );
}
TStrMap::iterator k;
lSize = sizeof( retValue );
// Correct 'FindWhat' value in registry
if( m_RegistryWork.QueryValue( retValue, "FindWhat", &lSize ) != ERROR_SUCCESS )
retValue[0] = '1', retValue[1] = 0;
tmpName.Format( "Search%s", retValue );
lSize = sizeof( retValue );
if( m_RegistryWork.QueryValue( retValue, tmpName, &lSize ) == ERROR_SUCCESS )
{
TStrMap::difference_type tmpDiff = 0;
k = arrNames.find( string( retValue ) );
if( k != arrNames.end() )
tmpDiff = std::distance( arrNames.begin(), k ) + 1;
tmpName.Format( "%d", tmpDiff );
m_RegistryWork.SetValue( tmpName, "FindWhat" );
}
// Store sorted array into Registry (while adding records to map
// all records in it sorted automaticaly)
lCount = 0;
for( k = arrNames.begin(); k != arrNames.end() ; k++ )
{
tmpName.Format( "Search%d", ++lCount );
tmpTitle.Format( "Text%d", lCount );
if( m_RegistryWork.SetValue( k->first.c_str(), tmpName ) == ERROR_SUCCESS )
m_RegistryWork.SetValue( k->second.c_str(), tmpTitle );
}
}
//////////////////////////////////////////////////////////////////////////
// Recover all registry keys to default value if no registry values found
void CCommands::RecoverRegistryDefault( void )
{
CFuncLog log( m_pLog, "RecoverRegistryDefault" );
// Create key
if( m_RegistryWork.Create( HKEY_LOCAL_MACHINE,
TEXT( "SOFTWARE\\AlexKucherenko\\TODOList Add-in\\Debug" ) ) != ERROR_SUCCESS )
{
::MessageBox( NULL,
TEXT( "Error cannot create registry key" ),
TEXT( "Fatal Error" ),
MB_OK | MB_ICONERROR );
return;
}
m_RegistryWork.SetValue( TEXT( "c:\\todolist.log" ), TEXT( "LogToFile" ) );
m_RegistryWork.SetValue( TEXT( "0" ), TEXT( "LogInWindow" ) );
m_RegistryWork.Create( HKEY_LOCAL_MACHINE,
TEXT( "SOFTWARE\\AlexKucherenko\\TODOList Add-in" ) );
m_RegistryWork.SetValue( TEXT( "0" ), TEXT( "FindWhat" ) );
m_RegistryWork.SetValue( TEXT( "0" ), TEXT( "ParseOnlyActiveProject" ) );
m_RegistryWork.SetValue( TEXT( ".cpp;.hpp;.hxx;.cxx;.c;.h;" ), TEXT( "FileExtensions" ) );
m_RegistryWork.SetValue( TEXT( "// DONE: " ), TEXT( "Search1" ) );
m_RegistryWork.SetValue( TEXT( "-= DONE =-" ), TEXT( "Text1" ) );
m_RegistryWork.SetValue( TEXT( "// NOTE: " ), TEXT( "Search2" ) );
m_RegistryWork.SetValue( TEXT( "-= NOTE =-" ), TEXT( "Text2" ) );
m_RegistryWork.SetValue( TEXT( "// TEST: " ), TEXT( "Search3" ) );
m_RegistryWork.SetValue( TEXT( "-= TEST =-" ), TEXT( "Text3" ) );
m_RegistryWork.SetValue( TEXT( "// TODO: " ), TEXT( "Search4" ) );
m_RegistryWork.SetValue( TEXT( "-= TODO =-" ), TEXT( "Text4" ) );
}
/////////////////////////////////////////////////////////////////////////////
// Constructor
CCommands::CCommands( ) :
m_bFirstRun( FALSE )
, m_pWorkSpace( NULL )
, m_hSyncHandle( NULL )
, m_hThread( NULL )
, m_hTimeOut( NULL )
, m_tid( 0 )
, m_dTid( 0 )
, m_pApplication( NULL )
, m_pApplicationEventsObj( NULL )
, m_pDebuggerEventsObj( NULL )
, m_pLog( NULL )
{
// try to open registry key with parser options
if( m_RegistryWork.Open( HKEY_LOCAL_MACHINE,
TEXT( "SOFTWARE\\AlexKucherenko\\TODOList Add-in" ) ) != ERROR_SUCCESS
)
{
RecoverRegistryDefault();
}
else
{
ReorderRegistry();
}
#ifdef _DEBUG
char tmpVal[8192];
DWORD tmpSize = sizeof( tmpVal );
LONG errCode = 0;
CRegKey RegDebug;
errCode = RegDebug.Create( HKEY_LOCAL_MACHINE,
TEXT( "SOFTWARE\\AlexKucherenko\\TODOList Add-in\\Debug" ) );
errCode = RegDebug.QueryValue( tmpVal, "LogInWindow", &tmpSize );
if( errCode == ERROR_SUCCESS )
if( atol( tmpVal ) > 0 )
{
m_pLog = new CLog( new CWinLog( ), MAX_LOG_LEVEL );
}
else
{
tmpSize = sizeof( tmpVal );
errCode = RegDebug.QueryValue( tmpVal, "LogToFile", &tmpSize );
if( errCode == ERROR_SUCCESS )
{
m_pLog = new CLog( new CFileLog( tmpVal ), MAX_LOG_LEVEL );
// uncomment next string if you don't want to see log data immediately
// ( greatly increase perfomance )
// m_pLog->SetAutoFlush( false );
}
}
#endif // _DEBUG
}
//////////////////////////////////////////////////////////////////////////
// Destructor
CCommands::~CCommands( )
{
ASSERT( m_pApplication != NULL );
m_pApplication->Release( );
if( m_pWorkSpace != NULL )
delete m_pWorkSpace, m_pWorkSpace = NULL;
if( m_hThread != NULL )
::TerminateThread( m_hThread, ( DWORD )-1 );
if( m_hTimeOut != NULL )
::TerminateThread( m_hTimeOut, ( DWORD )-1 );
if( m_pLog != NULL )
delete m_pLog, m_pLog = NULL;
}
//////////////////////////////////////////////////////////////////////////
//
void CCommands::SetApplicationObject( IApplication* pApplication )
{
CFuncLog log( m_pLog, "CCommands::SetApplicationObject" );
m_pApplication = pApplication;
// Create Application event handlers
XApplicationEventsObj::CreateInstance(&m_pApplicationEventsObj);
m_pApplicationEventsObj->AddRef( );
m_pApplicationEventsObj->Connect(m_pApplication);
m_pApplicationEventsObj->m_pCommands = this;
// Create Debugger event handler
CComPtr<IDispatch> pDebugger;
if (SUCCEEDED(m_pApplication->get_Debugger(&pDebugger) )
&& pDebugger != NULL)
{
XDebuggerEventsObj::CreateInstance(&m_pDebuggerEventsObj);
m_pDebuggerEventsObj->AddRef( );
m_pDebuggerEventsObj->Connect(pDebugger);
m_pDebuggerEventsObj->m_pCommands = this;
}
}
//////////////////////////////////////////////////////////////////////////
//
void CCommands::UnadviseFromEvents( )
{
CFuncLog log( m_pLog, "CCommands::UnadviseFromEvents" );
ASSERT (m_pApplicationEventsObj != NULL);
m_pApplicationEventsObj->Disconnect(m_pApplication);
m_pApplicationEventsObj->Release( );
m_pApplicationEventsObj = NULL;
if (m_pDebuggerEventsObj != NULL)
{
CComPtr<IDispatch> pDebugger;
VERIFY_OK(m_pApplication->get_Debugger(&pDebugger) );
ASSERT (pDebugger != NULL);
m_pDebuggerEventsObj->Disconnect(pDebugger);
m_pDebuggerEventsObj->Release( );
m_pDebuggerEventsObj = NULL;
}
}
/////////////////////////////////////////////////////////////////////////////
// Event handlers //
// Application events //
/////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//
HRESULT CCommands::XApplicationEvents::BeforeBuildStart( )
{
AFX_MANAGE_STATE( AfxGetStaticModuleState( ) );
CFuncLog log( m_pCommands->m_pLog, "CCommands::XApplicationEvents::BeforeBuildStart" );
return S_OK;
}
//////////////////////////////////////////////////////////////////////////
//
HRESULT CCommands::XApplicationEvents::BuildFinish(long /*nNumErrors*/, long /*nNumWarnings*/)
{
AFX_MANAGE_STATE( AfxGetStaticModuleState( ) );
CFuncLog log( m_pCommands->m_pLog, "CCommands::XApplicationEvents::BuildFinish" );
return S_OK;
}
//////////////////////////////////////////////////////////////////////////
//
HRESULT CCommands::XApplicationEvents::BeforeApplicationShutDown( )
{
AFX_MANAGE_STATE( AfxGetStaticModuleState( ) );
CFuncLog log( m_pCommands->m_pLog, "CCommands::XApplicationEvents::BeforeApplicationShutDown" );
return S_OK;
}
//////////////////////////////////////////////////////////////////////////
//
HRESULT CCommands::XApplicationEvents::DocumentOpen(IDispatch* /*theDocument*/)
{
AFX_MANAGE_STATE( AfxGetStaticModuleState( ) );
CFuncLog log( m_pCommands->m_pLog, "CCommands::XApplicationEvents::DocumentOpen" );
return S_OK;
}
//////////////////////////////////////////////////////////////////////////
//
HRESULT CCommands::XApplicationEvents::BeforeDocumentClose(IDispatch* /*theDocument*/)
{
AFX_MANAGE_STATE( AfxGetStaticModuleState( ) );
CFuncLog log( m_pCommands->m_pLog, "CCommands::XApplicationEvents::BeforeDocumentClose" );
return S_OK;
}
//////////////////////////////////////////////////////////////////////////
//
HRESULT CCommands::XApplicationEvents::DocumentSave( IDispatch* theDocument )
{
AFX_MANAGE_STATE( AfxGetStaticModuleState( ) );
CFuncLog log( m_pCommands->m_pLog, "CCommands::XApplicationEvents::DocumentSave" );
CComQIPtr< IGenericDocument, &IID_IGenericDocument> pDoc( theDocument );
CComBSTR strFullName;
pDoc->get_FullName( &strFullName );
bstr_t tmpName( ( BSTR )strFullName );
string strProjectFile = (char *)tmpName;
string strProject = m_pCommands->GetActiveProject();
try
{
if( m_pCommands->m_pWorkSpace != NULL )
m_pCommands->m_pWorkSpace->ReparseFile( strProject.c_str( ), strProjectFile.c_str( ) );
}
catch( CToDoNoElements ex )
{
TRACE_EXCEPTION;
}
return S_OK;
}
//////////////////////////////////////////////////////////////////////////
//
HRESULT CCommands::XApplicationEvents::NewDocument(IDispatch* /*theDocument*/)
{
AFX_MANAGE_STATE( AfxGetStaticModuleState( ) );
CFuncLog log( m_pCommands->m_pLog, "CCommands::XApplicationEvents::NewDocument" );
return S_OK;
}
//////////////////////////////////////////////////////////////////////////
//
HRESULT CCommands::XApplicationEvents::WindowActivate(IDispatch* /*theWindow*/)
{
AFX_MANAGE_STATE( AfxGetStaticModuleState( ) );
CFuncLog log( m_pCommands->m_pLog, "CCommands::XApplicationEvents::WindowActivate" );
return S_OK;
}
//////////////////////////////////////////////////////////////////////////
//
HRESULT CCommands::XApplicationEvents::WindowDeactivate(IDispatch* /*theWindow*/)
{
AFX_MANAGE_STATE( AfxGetStaticModuleState( ) );
CFuncLog log( m_pCommands->m_pLog, "CCommands::XApplicationEvents::WindowDeactivate" );
return S_OK;
}
//////////////////////////////////////////////////////////////////////////
//
HRESULT CCommands::XApplicationEvents::WorkspaceOpen( )
{
AFX_MANAGE_STATE( AfxGetStaticModuleState( ) );
CFuncLog log( m_pCommands->m_pLog, "CCommands::XApplicationEvents::WorkspaceOpen" );
m_pCommands->m_bFirstRun = FALSE;
if( m_pCommands->m_pWorkSpace != NULL )
delete m_pCommands->m_pWorkSpace, m_pCommands->m_pWorkSpace = NULL;
return S_OK;
}
//////////////////////////////////////////////////////////////////////////
//
HRESULT CCommands::XApplicationEvents::WorkspaceClose( )
{
AFX_MANAGE_STATE( AfxGetStaticModuleState( ) );
CFuncLog log( m_pCommands->m_pLog, "CCommands::XApplicationEvents::WorkspaceClose" );
return S_OK;
}
//////////////////////////////////////////////////////////////////////////
//
HRESULT CCommands::XApplicationEvents::NewWorkspace( )
{
AFX_MANAGE_STATE( AfxGetStaticModuleState( ) );
CFuncLog log( m_pCommands->m_pLog, "CCommands::XApplicationEvents::NewWorkspace" );
m_pCommands->m_bFirstRun = FALSE;
if( m_pCommands->m_pWorkSpace != NULL )
delete m_pCommands->m_pWorkSpace, m_pCommands->m_pWorkSpace = NULL;
return S_OK;
}
//////////////////////////////////////////////////////////////////////////
// Debugger event //
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//
HRESULT CCommands::XDebuggerEvents::BreakpointHit(IDispatch* /*pBreakpoint*/)
{
AFX_MANAGE_STATE( AfxGetStaticModuleState( ) );
CFuncLog log( m_pCommands->m_pLog, "CCommands::XDebuggerEvents::BreakpointHit" );
return S_OK;
}
/////////////////////////////////////////////////////////////////////////////
// Parser caller
STDMETHODIMP CCommands::ToDoCachedCommandMethod( )
{
AFX_MANAGE_STATE( AfxGetStaticModuleState( ) );
CFuncLog log( m_pLog, "CCommands::ToDoCachedCommandMethod" );
// VSBUG: Don't remove bFirstLogo part code. It's fix Visual Studio bug.
// I'm seriously! If Macro output window not created before our output
// then we have error NULL pointer exception. It's very strange behaviour
// of Visual Studio. I think this was fixed in lates VS SP.
static bool bFirstLogo = true;
if( bFirstLogo )
{
bFirstLogo = false;
m_pApplication->PrintToOutputWindow( L"ToDoList Add-on Logo" );
}
if( m_bFirstRun == FALSE )
{
m_bFirstRun = TRUE;
ParseProject( );
}
if( m_hSyncHandle != NULL )
{
m_hThread = ::CreateThread( NULL, 0,
(LPTHREAD_START_ROUTINE)ShowCategory, this, 0, &m_tid );
if( m_hThread == NULL )
return S_FALSE;
m_hTimeOut = ::CreateThread( NULL, 0,
( LPTHREAD_START_ROUTINE )TimeOutThread, this, 0, &m_dTid );
}
return S_OK;
}
//////////////////////////////////////////////////////////////////////////
// Function set internal var m_bFirstRun. On next call ToDoListCommandMethod
// project will be reparsed fully. This function needed only if all comments
// in project not found automaticaly.
STDMETHODIMP CCommands::ReparseWorkspace( )
{
AFX_MANAGE_STATE( AfxGetStaticModuleState( ) )
CFuncLog log( m_pLog, "CCommands::ReparseWorkspace" );
m_bFirstRun = FALSE;
if( m_pWorkSpace != NULL )
delete m_pWorkSpace, m_pWorkSpace = NULL;
return S_OK;
}
//////////////////////////////////////////////////////////////////////////
// Function call option dilog for setting registry keys for our parser
STDMETHODIMP CCommands::OptionsForParsing( )
{
AFX_MANAGE_STATE( AfxGetStaticModuleState( ) )
CFuncLog log( m_pLog, "CCommands::OptionsForParsing" );
// If project never parsed before
if( m_bFirstRun == FALSE || m_pWorkSpace == NULL )
{
m_bFirstRun = TRUE;
ParseProject( );
DWORD retValue = ::WaitForSingleObject( m_hSyncHandle, DEF_TIMEOUT_THREAD_PARSE );
if( retValue == WAIT_TIMEOUT ) return S_OK;
}
CToDoOptions dlg;
dlg.InitMap( m_pWorkSpace );
dlg.DoModal();
// Change order of records in registry if option dialog something change
ReorderRegistry();
// Project must be fully reparsed if options in dialog changed
m_bFirstRun = FALSE;
if( m_pWorkSpace != NULL )
delete m_pWorkSpace, m_pWorkSpace = NULL;
return S_OK;
}
//////////////////////////////////////////////////////////////////////////
// Function parse project
void CCommands::ParseProject( void )
{
CFuncLog log( m_pLog, "CCommands::ParseProject" );
LONG tmpRet = 0;
long lCounter = 0;
CComPtr<IDispatch> pProjectsDisp;
// Create list of all projects in workspace
m_pApplication->get_Projects( &pProjectsDisp );
CComQIPtr< IProjects, &IID_IProjects > pProjects( pProjectsDisp );
// Get quantity of projects in workspace
pProjects->get_Count( &lCounter );
m_arrAllProjects.clear();
for( long i=0 ; i<lCounter ; i++ )
{
string strProjectFile;
{
// Extract project file name from BSTR string
CComBSTR tmpFullName;
{
CComPtr<IGenericProject> pProject;
variant_t Index( ( long )( i+1 ) );
pProjects->Item( Index.Detach( ), &pProject );
pProject->get_FullName( &tmpFullName );
}
bstr_t tmpName( ( BSTR )tmpFullName );
strProjectFile = (char *)tmpName;
} /* Delete all automatic vars */
strlwr( ( char * ) strProjectFile.c_str( ) );
m_arrAllProjects.push_back( string( strProjectFile.c_str( ) ) );
}
// Create search list of words
{
string _tmpKey;
char _tmpName[8192];
DWORD _tmpSize = 8192;
m_arrSearchWords.clear( );
for( i=0 ; TRUE ; ++i )
{
sprintf( _tmpName, "Search%d", i+1 );
_tmpKey = _tmpName;
tmpRet = m_RegistryWork.QueryValue( _tmpName, _tmpKey.c_str( ), &_tmpSize );
if( tmpRet != ERROR_SUCCESS ) break;
m_arrSearchWords.push_back( string( _tmpName ) );
_tmpSize = sizeof(_tmpName);
}
}
// Recover registry if nothing found in list
if( m_arrSearchWords.empty( ) )
RecoverRegistryDefault( );
if( m_pWorkSpace == NULL )
m_pWorkSpace = new CToDoWorkSpace( m_arrAllProjects, m_arrSearchWords );
m_hSyncHandle = ( HANDLE )m_pWorkSpace->StartParsing( );
}
//////////////////////////////////////////////////////////////////////////
// Thread waiting for Parse and Output thread and if they doesn't finish it's
// work in time then terminate threads
DWORD CCommands::TimeOutThread( CCommands *pThis )
{
CFuncLog log( pThis->m_pLog, "CCommands::TimeOutThread" );
if( pThis->m_hThread == NULL )
return (DWORD)-1;
DWORD retSync = 0;
::GetExitCodeThread( pThis->m_hThread, &retSync );
// By default we Wait 20 seconds
DWORD retValue = ::WaitForSingleObject( pThis->m_hThread, DEF_TIMEOUT_THREAD_SHOW );
if( retValue == WAIT_TIMEOUT )
{
// Ignore any returned codes
::TerminateThread( pThis->m_hSyncHandle, ( DWORD )-1 );
::TerminateThread( pThis->m_hThread, ( DWORD )-1 );
}
// Set handle to NULL when thread is finished
pThis->m_hTimeOut = NULL;
return 0;
}
//////////////////////////////////////////////////////////////////////////
// Function show all finded useful comments into Macro Output window
// ( Function select active project or all projets )
DWORD CCommands::ShowCategory( CCommands *pThis)
{
CFuncLog log( pThis->m_pLog, "CCommands::ShowCategory" );
char _tmpValue[8192];
DWORD _tmpSize = sizeof(_tmpValue);
long lAllPtojects = 0;
pThis->m_RegistryWork.QueryValue( _tmpValue, TEXT("ParseOnlyActiveProject"), &_tmpSize );
lAllPtojects = atol( _tmpValue );
DWORD retSync = 0;
// Check that we have first thread handle
if( pThis->m_hSyncHandle == NULL )
return (DWORD)-1;
GetExitCodeThread( pThis->m_hSyncHandle, &retSync );
if( retSync == STILL_ACTIVE )
{
retSync = ::WaitForSingleObject( pThis->m_hSyncHandle, DEF_TIMEOUT_THREAD_PARSE );
if( retSync == WAIT_TIMEOUT )
return (DWORD)-1;
}
if( lAllPtojects == 0 )
{
// Parse all projects in workspace
try
{
TWorkSpaceIter k, tmpIter = *pThis->m_pWorkSpace->Last();
for( k = *pThis->m_pWorkSpace->First( ) ;
k != tmpIter ;
k = *pThis->m_pWorkSpace->Next( ) )
pThis->ShowProjectText( k->second );
}
catch( CToDoException ex )
{
TRACE_EXCEPTION;
}
}
else
{
// Parse only active project in workspace
string strProjectFile = pThis->GetActiveProject();
try
{
TWorkSpaceIter k = *pThis->m_pWorkSpace->Find( strProjectFile.c_str( ) );
pThis->ShowProjectText( k->second );
}
catch( CToDoNoElements ex )
{
TRACE_EXCEPTION;
}
}
// Set handle to NULL when thread is finished
pThis->m_hThread = NULL;
return 0;
}
//////////////////////////////////////////////////////////////////////////
// Function selct from project
// (select search word or all search words)
void CCommands::ShowProjectText( TProject &tmpProject )
{
CFuncLog log( m_pLog, "CCommands::ShowProjectText" );
// Show all files from project
TProjectIter k;
for( k = tmpProject.begin( ) ; k != tmpProject.end( ) ; k++ )
{
log.LogString( LOG_INFO, log.FormatString( "file : %s\n", k->first.c_str( ) ) );
ShowMultiParseText( k->second );
}
}
//////////////////////////////////////////////////////////////////////////
//
void CCommands::ShowMultiParseText( CToDoMultiParse &tmpMulParse )
{
CFuncLog log( m_pLog, "CCommands::ShowMultiParseText" );
string strFindWhat;
char _tmpValue[8192];
DWORD _tmpSize = sizeof( _tmpValue );
long _tmpFindWhat = 0;
m_RegistryWork.QueryValue( _tmpValue, "FindWhat", &_tmpSize );
_tmpFindWhat = atol( _tmpValue );
if( _tmpFindWhat == 0 )
{
// Show all search categories from file
try
{
TMultiIter k, tmpIter = *tmpMulParse.Last();
for( k = *tmpMulParse.First( ) ; k != tmpIter ; k = *tmpMulParse.Next( ) )
{
// NOTE: Here used Microsoft compiler specific construction. For more info
// look into 'warning C4239' help
if( strcmp( k->first.c_str(), "// " ) != 0 )
OutputSingleText( tmpMulParse.CreateMultiLine( k->first, "// " ) );
}
}
catch( CToDoException ex )
{
TRACE_EXCEPTION;
}
}
else
{
// Show only one search category from file
long i = _tmpFindWhat;
try
{
TMultiIter k = *tmpMulParse.First( );
for( i = _tmpFindWhat ; i >= 1 ; --i )
k = *tmpMulParse.Next( );
// NOTE: Here used Microsoft compiler specific construction. For more info
// look into 'warning C4239' help
if( strcmp( k->first.c_str(), "// " ) != 0 )
OutputSingleText( tmpMulParse.CreateMultiLine( k->first, "// " ) );
}
catch( CToDoException ex )
{
TRACE_EXCEPTION;
}
}
}
//////////////////////////////////////////////////////////////////////////
// Function realy print message into macro window output. All text for output
// are formated here.
void CCommands::OutputSingleText( CToDoSingleParse &tmpSinParse )
{
CFuncLog log( m_pLog, "CCommands::OutputSingleText" );
TLineMapperIter k;
try
{
k = *tmpSinParse.First();
for( int i = 0; i < tmpSinParse.GetElementsQuantity() ; i++ )
{
char tmpOutput[ TODO_STRING_RESERVE ];
CString MultiComment( k->second.c_str( ) );
MultiComment.Replace( "\t", " " );
MultiComment.Replace( "\r", " " );
MultiComment.Replace( "\n", " " );
MultiComment.Replace( " ", " " );
sprintf( tmpOutput, "%s(%d): %s : %s",
tmpSinParse.GetFileName().c_str(),
k->first,
tmpSinParse.GetSearchWord().c_str(),
MultiComment );
CComBSTR tmpOut( tmpOutput );
m_pApplication->PrintToOutputWindow( tmpOut.Detach() );
k = *tmpSinParse.Next();
}
}
catch( CToDoException ex )
{
TRACE_EXCEPTION;
};
}
//////////////////////////////////////////////////////////////////////////
// Function return full path to active project
string CCommands::GetActiveProject()
{
CFuncLog log( m_pLog, "CCommands::GetActiveProject" );
CComBSTR tmpFullName;
CComPtr< IDispatch > iDispProject;
m_pApplication->get_ActiveProject( &iDispProject );
CComQIPtr< IGenericProject, &IID_IGenericProject > pProject( iDispProject );
// If no project opened
if( pProject == NULL ) return "";
pProject->get_FullName( &tmpFullName );
bstr_t tmpName( ( BSTR )tmpFullName );
string strProjectFile = (char *)tmpName;
strlwr( ( char * )strProjectFile.c_str( ) );
return string( strProjectFile.c_str( ) );
}
//:> End of file