Click here to Skip to main content
15,891,828 members
Articles / Programming Languages / C++

Project Line Counter Add-In v2.10 for VS.NET and VC6

Rate me:
Please Sign up or sign in to vote.
4.92/5 (38 votes)
29 Jun 2003 449.5K   5.3K   142  
Get statistics about your source code with a click of a button
/***************************************************************************/
/* NOTE:                                                                   */
/* This document is copyright (c) by Oz Solomonovich, and is bound by the  */
/* MIT open source license (www.opensource.org/licenses/mit-license.html). */
/* See License.txt for more information.                                   */
/***************************************************************************/

// ResultsDlg.cpp : implementation file
//

#include "stdafx.h"
#include "LineCount.h"
#include "ResultsDlg.h"
#include "Config.h"
#include "Export.h"
#include "FileSummaryDlg.h"
#include "Options.h"
#include "AboutDialog.h"
#include "PrjStats.h"
#include "Help\HelpIDs.h"

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

#define TOTAL_STR   _T("*** TOTAL ***")

const char *STR_WORKSPACE  = "<Workspace>";
const char *STR_ACTIVE_PRJ = "<Active Project>";

struct ColumnInfo
{
    LPCTSTR     name;
    SORT_TYPE   sortType;
    SORT_STATE  sortState;
    int         lengthExtension;
    int         fmt;
};

static ColumnInfo columns[] =
{
    { _T("File Name"),  TYPE_TEXT,    DESCENDING, 40 },
    { _T("Extension"),  TYPE_TEXT,    DESCENDING, 10 },
    { _T("Path"),       TYPE_TEXT,    DESCENDING, 20 },
    { _T("Lines"),      TYPE_NUMERIC, DESCENDING, 15 },
    { _T("Code"),       TYPE_NUMERIC, DESCENDING, 5  },
    { _T("Comments"),   TYPE_NUMERIC, DESCENDING, 5  },
    { _T("Mixed"),      TYPE_NUMERIC, DESCENDING, 15 },
    { _T("Blank"),      TYPE_NUMERIC, DESCENDING, 15 }
};


/////////////////////////////////////////////////////////////////////////////
// CResultsDlg dialog


CResultsDlg::CResultsDlg(WWhizInterface *pWWI,
    CWnd* pParent /*=NULL*/) : CResizableDialog(CResultsDlg::IDD, pParent), 
    /*m_pStats(pStats), m_pfi(pStats->pfi),*/ m_pWWI(pWWI)
{
    m_iHelpID = IDH_DLG_MAIN;
	//{{AFX_DATA_INIT(CResultsDlg)
	//}}AFX_DATA_INIT
}



void CResultsDlg::DoDataExchange(CDataExchange* pDX)
{
	CResizableDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CResultsDlg)
	DDX_Control(pDX, IDC_FILTER, m_Filter);
	DDX_Control(pDX, IDC_RESULTLIST, m_ListCtrl);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CResultsDlg, CResizableDialog)
	//{{AFX_MSG_MAP(CResultsDlg)
	ON_COMMAND(IDC_EXPORT, OnExport)
	ON_COMMAND(IDC_OPTIONS, OnOptions)
	ON_COMMAND(IDC_ABOUT, OnAbout)
	ON_UPDATE_COMMAND_UI(ID_STATISTICS_FILTER_ACTIVEPROJECT, OnUpdateStatisticsFilterActiveproject)
	ON_UPDATE_COMMAND_UI(ID_STATISTICS_FILTER_WORKSPACE, OnUpdateStatisticsFilterWorkspace)
	ON_UPDATE_COMMAND_UI(IDC_FILESUMMARY, OnUpdateStatsCommand)
	ON_UPDATE_COMMAND_UI(IDC_EXPORT, OnUpdateStatsCommand)
	ON_COMMAND(ID_STATISTICS_FILTER_ACTIVEPROJECT, OnStatisticsFilterActiveproject)
	ON_COMMAND(ID_STATISTICS_FILTER_WORKSPACE, OnStatisticsFilterWorkspace)
	ON_CBN_SELCHANGE(IDC_FILTER, OnSelchangeFilter)
	ON_COMMAND(IDC_DOWNLOADS, OnDownloads)
	ON_COMMAND(IDC_HOMEPAGE, OnHomepage)
	ON_COMMAND(IDC_FILESUMMARY, OnFileSummary)
	//}}AFX_MSG_MAP
	ON_COMMAND_RANGE(ID_STATISTICS_FILTER_PROJECT1, ID_STATISTICS_FILTER_PROJECT99, OnStatisticsFilterProjects)
	ON_UPDATE_COMMAND_UI_RANGE(ID_STATISTICS_FILTER_PROJECT1, ID_STATISTICS_FILTER_PROJECT99, OnUpdateStatisticsFilterProjects)
	ON_WM_INITMENUPOPUP()
END_MESSAGE_MAP()

BEGIN_HELP_IDS(CResultsDlg)
    IDC_MENU_SEP,     0,

    IDC_NOPROJ_TEXT,  0,
    IDC_NOPROJ_NOTE,  0,
    IDC_NOPROJ_FRAME, 0,

    IDC_TXT_TOTAL,    0,
    IDC_TXT_C,        0,
    IDC_TXT_P,        0,

    IDC_TXT_FILTER,   IDC_FILTER,
                    
    IDC_TIP_ICON,     0,
    IDC_TIP_TEXT,     0,

    IDC_LINESC,       IDC_LINEST,
    IDC_LINESP,       IDC_LINEST,

    IDC_CODEC,        IDC_CODET,
    IDC_CODEP,        IDC_CODET,

    IDC_COMMENTSC,    IDC_COMMENTST,
    IDC_COMMENTSP,    IDC_COMMENTST,

    IDC_MIXEDC,       IDC_MIXEDT,
    IDC_MIXEDP,       IDC_MIXEDT,

    IDC_BLANKC,       IDC_BLANKT,
    IDC_BLANKP,       IDC_BLANKT,

    IDC_NETLINESC,    IDC_NETLINEST,
    IDC_NETLINESP,    IDC_NETLINEST
END_HELP_IDS()

/////////////////////////////////////////////////////////////////////////////
// CResultsDlg message handlers

BOOL CResultsDlg::OnInitDialog() 
{
	CResizableDialog::OnInitDialog();

    SetIcon(AfxGetApp()->LoadIcon(IDI_TITLE), FALSE);
    
    int         i;
    LVCOLUMN    lvc;

    m_ListCtrl.SendMessage(LVM_SETEXTENDEDLISTVIEWSTYLE, 0, (LPARAM) 
        LVS_EX_GRIDLINES | LVS_EX_HEADERDRAGDROP | LVS_EX_FULLROWSELECT |
        m_ListCtrl.SendMessage(LVM_GETEXTENDEDLISTVIEWSTYLE));

    lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;

    for(i = 0; i < countof(columns); i++)
    {
        lvc.iSubItem = i;
        lvc.pszText = (char *)columns[i].name;
        lvc.cx = m_ListCtrl.GetStringWidth(lvc.pszText) + 
            columns[i].lengthExtension + 15;
        if (lvc.cx < 40) lvc.cx = 40;
        lvc.fmt = columns[i].fmt;
        m_ListCtrl.InsertColumn(i, columns[i].sortType, columns[i].sortState, 
            &lvc);
    }

	m_ListCtrl.SortColumn( 2, false );
	m_ListCtrl.SortColumn( 1, true );
	m_ListCtrl.SortColumn( 0, true );

	m_ListCtrl.SetUniqueName( "ResultsListCtrl" );
	m_ListCtrl.LoadColumnWidths();
    m_ListCtrl.LoadColumnOrder();
    m_ListCtrl.LoadColumnSort();

	//resizable dlg
    AddAnchor(IDC_MENU_SEP, TOP_LEFT, TOP_RIGHT);

    AddAnchor(IDC_RESULTLIST, TOP_LEFT, BOTTOM_RIGHT);

    AddAnchor(IDC_NOPROJ_FRAME, TOP_LEFT,    BOTTOM_RIGHT);
    AddAnchor(IDC_NOPROJ_TEXT,  TOP_LEFT,    BOTTOM_RIGHT);
    AddAnchor(IDC_NOPROJ_NOTE,  BOTTOM_LEFT, BOTTOM_RIGHT);

    AddAnchor(IDC_TXT_TOTAL, BOTTOM_LEFT);
	AddAnchor(IDC_TXT_P, BOTTOM_LEFT);
	AddAnchor(IDC_TXT_C, BOTTOM_LEFT);
	
	AddAnchor(IDC_LINEST, BOTTOM_LEFT);
	AddAnchor(IDC_LINESC, BOTTOM_LEFT);
	AddAnchor(IDC_LINESP, BOTTOM_LEFT);
	
	AddAnchor(IDC_CODET, BOTTOM_LEFT);
	AddAnchor(IDC_CODEC, BOTTOM_LEFT);
	AddAnchor(IDC_CODEP, BOTTOM_LEFT);
	
	AddAnchor(IDC_COMMENTST, BOTTOM_LEFT);
	AddAnchor(IDC_COMMENTSC, BOTTOM_LEFT);
	AddAnchor(IDC_COMMENTSP, BOTTOM_LEFT);
	
	AddAnchor(IDC_MIXEDT, BOTTOM_LEFT);
	AddAnchor(IDC_MIXEDC, BOTTOM_LEFT);
	AddAnchor(IDC_MIXEDP, BOTTOM_LEFT);

	AddAnchor(IDC_BLANKT, BOTTOM_LEFT);
	AddAnchor(IDC_BLANKC, BOTTOM_LEFT);
	AddAnchor(IDC_BLANKP, BOTTOM_LEFT);
	
	AddAnchor(IDC_NETLINEST, BOTTOM_LEFT);
	AddAnchor(IDC_NETLINESC, BOTTOM_LEFT);
	AddAnchor(IDC_NETLINESP, BOTTOM_LEFT);
	
	AddAnchor(IDC_NETLINEST, BOTTOM_LEFT);
	AddAnchor(IDC_NETLINESC, BOTTOM_LEFT);
	AddAnchor(IDC_NETLINESP, BOTTOM_LEFT);
	
	AddAnchor(IDC_TXT_FILTER, BOTTOM_LEFT);
	AddAnchor(IDC_FILTER, BOTTOM_LEFT);
    AddAnchor(IDC_TIP_ICON, BOTTOM_LEFT);
    AddAnchor(IDC_TIP_TEXT, BOTTOM_LEFT);
    AddAnchor(IDOK, BOTTOM_RIGHT);

    EnableSaveRestore("DlgSize", "ResultsDlg");

    InitStats();

    return TRUE;  
}

bool FindMenuItem(CMenu *pMenu, UINT nIDToFind, CMenu *& pOutMenu, int& iOutIndex)
{
    for (UINT i = 0; i < pMenu->GetMenuItemCount(); ++i)
    {
        UINT nID = pMenu->GetMenuItemID(i);
        if (nID == nIDToFind)
        {
            pOutMenu = pMenu;
            iOutIndex = i;
            return true;
        }
        if (nID == (unsigned)-1)
        {
            // submenu
            if (FindMenuItem(pMenu->GetSubMenu(i), nIDToFind, pOutMenu, iOutIndex))
            {
                return true;
            }
        }
    }
    pOutMenu = NULL;
    iOutIndex = -1;
    return false;
}

void CResultsDlg::InitStats()
{
    ::ResetStats();

    m_iContext = 0;

    int i;
    AddFilter(STR_WORKSPACE,  ID_STATISTICS_FILTER_WORKSPACE);
    AddFilter(STR_ACTIVE_PRJ, ID_STATISTICS_FILTER_ACTIVEPROJECT);

    CMenu *pMenuStatsFilter;
    VERIFY(FindMenuItem(GetMenu(), ID_STATISTICS_FILTER_ACTIVEPROJECT,
        pMenuStatsFilter, i));
    while (pMenuStatsFilter->GetMenuItemCount() > 2)
    {
        pMenuStatsFilter->DeleteMenu(
            pMenuStatsFilter->GetMenuItemCount() - 1, MF_BYPOSITION);
    }
    
    m_pWWI->RefreshFileList();

    WWhizProjectList& prjList = m_pWWI->GetProjectList();
    if (prjList.GetProjectCount() == 0)
    {
        m_Filter.EnableWindow(FALSE);
        m_ListCtrl.ShowWindow(SW_HIDE);
        m_bHasProject = false;
    }
    else
    {
        GetDlgItem(IDC_NOPROJ_TEXT)->ShowWindow(SW_HIDE);
        GetDlgItem(IDC_NOPROJ_NOTE)->ShowWindow(SW_HIDE);
        pMenuStatsFilter->AppendMenu(MF_SEPARATOR, 0, (LPCTSTR)0);
        for (i = 0; i < prjList.GetProjectCount(); ++i)
        {
            CString prjName = prjList.GetProjectByIndex(i)->GetName();
            int p = prjName.ReverseFind('\\');
            if (p > 0) prjName = prjName.Mid(p + 1);
            CString strTemp = prjName;
            strTemp.MakeLower();
            if (strTemp.Find(".dsw") < 0)  // don't add .dsw files
            {
                AddFilter(prjName, ID_STATISTICS_FILTER_PROJECT1 + i);
                pMenuStatsFilter->AppendMenu(MF_STRING, 
                    ID_STATISTICS_FILTER_PROJECT1 + i, prjName);
            }
        }
        m_bHasProject = true;
    }
    UpdateDialogControls(this, TRUE);
    RedrawWindow();

    // select last filter, or default
    int iFilter = cfg_iDefaultFilter;
    CString s;
    for (i = 0; i < m_Filter.GetCount(); ++i)
    {
        m_Filter.GetLBText(i, s);
        if (s.CompareNoCase(cfg_sLastFilter) == 0)
        {
            iFilter = i;
            break;
        }
    }
    if (iFilter > m_Filter.GetCount())
    {
        iFilter = 0;
    }
    SetFilter(iFilter);
}

void CResultsDlg::RefreshStats()
{
    if (!m_bHasProject) return;

    int files, total, code, mixed, com, blank;
    files = total = code = mixed = com = blank = 0;

    m_ListCtrl.SetRedraw(FALSE);
    m_ListCtrl.DeleteAllItems();
    ++m_iContext;

    // read the N/A string
    if (m_sNA.IsEmpty())
    {
        GetDlgItem(IDC_BLANKC)->GetWindowText(m_sNA);
    }
                        
    ProjectList projects;
    ProjectListFromFilter(m_iFilterIndex, projects);
    POSITION p = projects.GetHeadPosition();
    while (p)
    {
        WWhizProject& prj = *projects.GetNext(p);
        WWhizFileList& fileList = prj.GetFileList();
        int cFiles = fileList.GetCount();
        for (int f = 0; f < cFiles; ++f)
        {
            WWhizFile& file = *fileList.Get(f);
            CFileInfo *pFI = ::GetStats(file.GetFullName());
            if (pFI  &&  pFI->m_iContext < m_iContext)
            {
                // this will prevent us from counting the same file twice
                pFI->m_iContext = m_iContext;

                const CFileInfo& fi = *pFI;
                total += fi.m_iTotalLines ;
                com   += fi.m_iLinesWithComments;
                code  += fi.m_iLinesWithCode;
                blank += fi.m_iBlankLines;
                mixed += CalculateMixedLines(fi.m_iTotalLines,
                    fi.m_iLinesWithCode, fi.m_iLinesWithComments, 
                    fi.m_iBlankLines);
                ++files;
                AddRow(fi);
            }
        }
    }

    CFileInfo fiTotal;
    fiTotal.m_sFileName          = TOTAL_STR;    
    fiTotal.m_iBlankLines        = blank;
    fiTotal.m_iLinesWithCode     = code;
    fiTotal.m_iLinesWithComments = com;
    fiTotal.m_iTotalLines        = total;
    fiTotal.m_bFull              = true;
    
	int nRowTotal = AddRow(fiTotal);

	if( -1 != nRowTotal )
	{
		//mark the line with the summary info
		m_ListCtrl.SetItemData(nRowTotal, DWORD(-1));
	}

    CString msg, s;
    s.Format("%d", files);
    AfxFormatString1(msg, IDS_FILECOUNT, s);
    SetWindowText(msg);

    if (!cfg_bProcessBlanks)
    {
        blank = -1;
    }
    if (!cfg_bProcessCPPComments)
    {
        com = mixed = -1;
    }

    SetPair(IDC_LINESC,    IDC_LINESP,      total,          total);
    SetPair(IDC_CODEC,     IDC_CODEP,       code,           total);
    SetPair(IDC_NETLINESC, IDC_NETLINESP,   total - blank,  total);
    SetPair(IDC_BLANKC,    IDC_BLANKP,      blank,          total);
    SetPair(IDC_COMMENTSC, IDC_COMMENTSP,   com,            total);
    SetPair(IDC_MIXEDC,    IDC_MIXEDP,      mixed,          total);

    m_ListCtrl.SortCombinedColumns(true);

    m_ListCtrl.SetRedraw(TRUE);
    m_ListCtrl.RedrawWindow();
}

void CResultsDlg::AddFilter(const char *pszFilter, int data)
{
    int i = m_Filter.AddString(pszFilter);
    m_Filter.SetItemData(i, data);
}

int CResultsDlg::AddRow(const CFileInfo& fi)
{
    ASSERT(fi.m_bFull);

	int nRes = -1;

    LV_ITEM lvi;
    CString cStr;

    lvi.mask = LVIF_TEXT | LVIF_PARAM;
    lvi.iItem = m_ListCtrl.GetItemCount();
    lvi.lParam = (LPARAM)&fi;

    lvi.iSubItem = 0;
    lvi.pszText = (LPTSTR)(LPCTSTR)fi.m_sFileName;
    nRes = m_ListCtrl.InsertItem(&lvi);

    int iSubItem = 0;
    m_ListCtrl.SetItemText(lvi.iItem, ++iSubItem, fi.m_sFileExt);
    m_ListCtrl.SetItemText(lvi.iItem, ++iSubItem, fi.m_sFilePath);
    m_ListCtrl.SetItemText(lvi.iItem, ++iSubItem, NumStr(fi.m_iTotalLines));
    m_ListCtrl.SetItemText(lvi.iItem, ++iSubItem, NumStr(fi.m_iLinesWithCode));

    if (!cfg_bProcessCPPComments)
        cStr = "n/a";
    if (cfg_bProcessCPPComments) cStr = NumStr(fi.m_iLinesWithComments);
    m_ListCtrl.SetItemText(lvi.iItem, ++iSubItem, cStr);
    int mixed = CalculateMixedLines(fi.m_iTotalLines,
        fi.m_iLinesWithCode, fi.m_iLinesWithComments, fi.m_iBlankLines);
    if (cfg_bProcessCPPComments) cStr = NumStr(mixed);
    m_ListCtrl.SetItemText(lvi.iItem, ++iSubItem, cStr);

    cStr = cfg_bProcessBlanks? NumStr(fi.m_iBlankLines) : "n/a";
    m_ListCtrl.SetItemText(lvi.iItem, ++iSubItem, cStr);

	return nRes;
}

CString CResultsDlg::NumStr(int num)
{
    CString cStr;
    int pos;

    cStr.Format("%d", num);
    pos = cStr.GetLength() - 1;
    while (pos >= 3)
    {
        cStr = cStr.Left(pos - 2) + "," + cStr.Mid(pos - 2);
        pos -= 3;
    }

    return cStr;
}

void CResultsDlg::SetNum(int id, int num, TCHAR suffix)
{
    CString cStr = NumStr(num);
    if (suffix)
        cStr += suffix;
    GetDlgItem(id)->SetWindowText(cStr);
}

void CResultsDlg::SetPair(int idc, int idp, int count, int tot)
{
    if (count < 0)
    {
        GetDlgItem(idc)->SetWindowText(m_sNA);
        GetDlgItem(idp)->SetWindowText(m_sNA);
        return;
    }

    SetNum(idc, count);

    if (tot)
        SetNum(idp, (count * 100) / tot, '%');
    else
        SetNum(idp, 0, '%');
}

static const TCHAR *FILTERS =
        _T("Comma Separated Values (*.csv)|*.csv|")
        _T("XML Data (*.xml)|*.xml|")
        _T("|");
const int NUM_FILTERS = 2;

void CResultsDlg::OnExport() 
{
    if (cfg_iDefaultExportType <= 0  ||  cfg_iDefaultExportType > NUM_FILTERS)
    {
        cfg_iDefaultExportType = 1;
    }
    CFileDialog dlg(FALSE, "", NULL, 
        OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, FILTERS);
    dlg.m_ofn.nFilterIndex = cfg_iDefaultExportType;
    if (dlg.DoModal() == IDOK  &&  !dlg.GetPathName().IsEmpty())
    {
        CWaitCursor wc;

        cfg_iDefaultExportType = dlg.m_ofn.nFilterIndex;

        bool bSuccess = false;
        ProjectList projects;
        ProjectListFromFilter(m_iFilterIndex, projects);
        if (dlg.m_ofn.nFilterIndex <= 1)
        {
            bSuccess = ExportAsCSV(dlg.GetPathName(), projects);
        }
        else
        {
            bSuccess = ExportAsXML(dlg.GetPathName(), projects,
                m_pWWI->GetWorkspaceName());
        }

        wc.Restore();
        if (bSuccess)
        {
            AfxMessageBox(IDS_MSG_GOODEXPORT, MB_OK | MB_ICONINFORMATION);
        }
    }
}


void CResultsDlg::OnOptions() 
{
    COptionsSheet dlg;
    if (dlg.DoModal() == IDOK)
    {
        ::ResetStats();
        int iCurrFilter = m_iFilterIndex;
        m_iFilterIndex = -1;
        SetFilter(iCurrFilter);
    }
}

void CResultsDlg::OnAbout() 
{
    CAboutDialog dlg;
    dlg.DoModal();
}


// this code is based on CFrameWnd::OnInitMenuPopup
void CResultsDlg::OnInitMenuPopup(CMenu* pMenu, UINT nIndex, BOOL bSysMenu)
{
	if (bSysMenu)
		return;     // don't support system menu

	ASSERT(pMenu != NULL);
	// check the enabled state of various menu items

	CCmdUI state;
	state.m_pMenu = pMenu;
	ASSERT(state.m_pOther == NULL);
	ASSERT(state.m_pParentMenu == NULL);

	// determine if menu is popup in top-level menu and set m_pOther to
	//  it if so (m_pParentMenu == NULL indicates that it is secondary popup)
	HMENU hParentMenu;
	if (AfxGetThreadState()->m_hTrackingMenu == pMenu->m_hMenu)
		state.m_pParentMenu = pMenu;    // parent == child for tracking popup
	else if ((hParentMenu = ::GetMenu(m_hWnd)) != NULL)
	{
		CWnd* pParent = GetTopLevelParent();
			// child windows don't have menus -- need to go to the top!
		if (pParent != NULL &&
			(hParentMenu = ::GetMenu(pParent->m_hWnd)) != NULL)
		{
			int nIndexMax = ::GetMenuItemCount(hParentMenu);
			for (int nIndex = 0; nIndex < nIndexMax; nIndex++)
			{
				if (::GetSubMenu(hParentMenu, nIndex) == pMenu->m_hMenu)
				{
					// when popup is found, m_pParentMenu is containing menu
					state.m_pParentMenu = CMenu::FromHandle(hParentMenu);
					break;
				}
			}
		}
	}

	state.m_nIndexMax = pMenu->GetMenuItemCount();
	for (state.m_nIndex = 0; state.m_nIndex < state.m_nIndexMax;
	  state.m_nIndex++)
	{
		state.m_nID = pMenu->GetMenuItemID(state.m_nIndex);
		if (state.m_nID == 0)
			continue; // menu separator or invalid cmd - ignore it

		ASSERT(state.m_pOther == NULL);
		ASSERT(state.m_pMenu != NULL);
		if (state.m_nID == (UINT)-1)
		{
			// possibly a popup menu, route to first item of that popup
			state.m_pSubMenu = pMenu->GetSubMenu(state.m_nIndex);
			if (state.m_pSubMenu == NULL ||
				(state.m_nID = state.m_pSubMenu->GetMenuItemID(0)) == 0 ||
				state.m_nID == (UINT)-1)
			{
				continue;       // first item of popup can't be routed to
			}
			state.DoUpdate(this, FALSE);    // popups are never auto disabled
		}
		else
		{
			// normal menu item
			// Auto enable/disable if frame window has 'm_bAutoMenuEnable'
			//    set and command is _not_ a system command.
			state.m_pSubMenu = NULL;
			state.DoUpdate(this, state.m_nID < 0xF000);
		}

		// adjust for menu deletions and additions
		UINT nCount = pMenu->GetMenuItemCount();
		if (nCount < state.m_nIndexMax)
		{
			state.m_nIndex -= (state.m_nIndexMax - nCount);
			while (state.m_nIndex < nCount &&
				pMenu->GetMenuItemID(state.m_nIndex) == state.m_nID)
			{
				state.m_nIndex++;
			}
		}
		state.m_nIndexMax = nCount;
	}
}

void CResultsDlg::OnUpdateStatisticsFilterProjects(CCmdUI* pCmdUI) 
{
    pCmdUI->Enable(m_bHasProject);
    pCmdUI->SetCheck(m_Filter.GetItemData(m_Filter.GetCurSel()) == 
        (DWORD)(pCmdUI->m_nID));
}

void CResultsDlg::OnUpdateStatisticsFilterWorkspace(CCmdUI* pCmdUI) 
{
    pCmdUI->Enable(m_bHasProject);
    pCmdUI->SetCheck(m_iFilterIndex == FILTER_IDX_WORKSPACE);
}

void CResultsDlg::OnUpdateStatisticsFilterActiveproject(CCmdUI* pCmdUI) 
{
    pCmdUI->Enable(m_bHasProject);
    pCmdUI->SetCheck(m_iFilterIndex == FILTER_IDX_ACTIVE_PRJ);
}

void CResultsDlg::ProjectListFromFilter(int iFilterIndex, ProjectList& projects)
{
    switch (iFilterIndex)
    {
        case FILTER_IDX_ACTIVE_PRJ:
        {
            WWhizProject *pPrj = m_pWWI->GetCurrentProject();
            if (pPrj)
            {
                projects.AddTail(pPrj);
            }
            break;
        }

        case FILTER_IDX_WORKSPACE:
        {
            WWhizProjectList& prjList = m_pWWI->GetProjectList();
            ASSERT(prjList.GetProjectCount() != 0);
            for (int i = 0; i < prjList.GetProjectCount(); ++i)
            {
                projects.AddTail(prjList.GetProjectByIndex(i));
            }
            break;
        }

        default:
        {
            WWhizProjectList& prjList = m_pWWI->GetProjectList();
            int iPrj = iFilterIndex - 2;
            iPrj = m_Filter.GetItemData(iFilterIndex) - ID_STATISTICS_FILTER_PROJECT1;
            ASSERT(prjList.GetProjectCount() > iPrj);
            WWhizProject *pPrj = prjList.GetProjectByIndex(iPrj);
            if (pPrj)
            {
                projects.AddTail(pPrj);
            }
            break;
        }
    }
}


void CResultsDlg::SetFilter(int iIndex)
{
    ASSERT(iIndex >= 0  &&  iIndex < m_Filter.GetCount());

    if (iIndex == m_iFilterIndex  &&  m_ListCtrl.GetItemCount() > 0)
    {
        return;
    }

    CWnd *pFocusedWnd = GetFocus();

    m_Filter.SetCurSel(iIndex);

    // update the stats based on the new filter
    if (m_bHasProject)
    {
        ProjectList projects;
        ProjectListFromFilter(iIndex, projects);
        if (::UpdateStats(m_pWWI, projects))
        {
            m_iFilterIndex = iIndex;
            RefreshStats();

            m_Filter.GetWindowText(cfg_sLastFilter);
        }
    }

    if (m_iFilterIndex >= 0)
    {
        // this is necessary if user cancels the file scan:
        m_Filter.SetCurSel(m_iFilterIndex);  // reset to old index
    }

    if (pFocusedWnd)
    {
        pFocusedWnd->SetFocus();
    }
}

void CResultsDlg::OnStatisticsFilterActiveproject() 
{
	SetFilter(FILTER_IDX_ACTIVE_PRJ);
}

void CResultsDlg::OnStatisticsFilterWorkspace() 
{
	SetFilter(FILTER_IDX_WORKSPACE);
}

void CResultsDlg::OnStatisticsFilterProjects(int iCmd) 
{
    // combo box is sorted - find actual index for this command
    for (int i = 0; i < m_Filter.GetCount(); ++i)
    {
        if (m_Filter.GetItemData(i) == (DWORD)iCmd)
        {
            SetFilter(i);
            return;
        }
    }
}

void CResultsDlg::OnSelchangeFilter() 
{
    int iCmd = m_Filter.GetItemData(m_Filter.GetCurSel());
    PostMessage(WM_COMMAND, iCmd, 0);
}

void CResultsDlg::OnDownloads() 
{
    CHyperLink::GotoURL("http://www.wndtabs.com/downloads/", SW_SHOW);
}

void CResultsDlg::OnHomepage() 
{
    CHyperLink::GotoURL("http://www.wndtabs.com/plc/", SW_SHOW);
}

void CResultsDlg::OnFileSummary() 
{
    ProjectList projects;
    ProjectListFromFilter(m_iFilterIndex, projects);
    CFileSummaryDlg dlg(projects);
    dlg.DoModal();
}

void CResultsDlg::OnUpdateStatsCommand(CCmdUI* pCmdUI) 
{
    pCmdUI->Enable(m_bHasProject);
}

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 has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Experion
Canada Canada
You may know Oz from his WndTabs days. Oz has long since left client side development to work on web technologies and to consult in the R&D management field.

Comments and Discussions