/************************************************************************
*
* Resource ID Organiser Core Library
*
* (c) Copyright 2000-2003 by Anna-Jayne Metcalfe (resorg@annasplace.me.uk)
* All rights reserved.
*
************************************************************************
*
* Filename : ResOrgSymbolFilesListCtrl.cpp
*
* Description : CResOrgSymbolFilesListCtrl - list control class for
* resource symbol files (Used in the "File" page of the
* File Properties Dialog when multiple files are opened)
*
* Compiler : Microsoft Visual C++ 6.0, Service Pack 3 or later
* Microsoft Visual C++ .NET 2002
*
* Target
* Environment : Windows 98/NT/2000/XP
*
* NOTE:
*
* This software is provided "as is" free for personal use. All
* title and copyrights in and to the software, including but not
* limited to any images, text, etc. incorporated into it, are
* owned by Anna-Jayne Metcalfe, except where acknowledged otherwise.
*
* Your may freely to use this code in your own products, PROVIDED
* this notice is not removed or modified.
*
*
* Visit http://www.annasplace.me.uk/resorg for latest updates
*
************************************************************************
*
* MODIFICATION HISTORY:
*
* This is a controlled document. See project configuration
* control tool for latest version and full version history.
*
* $Archive: /Projects/AddIns/ResOrg/ResOrgCore/ResOrgSymbolFilesListCtrl.cpp $
* $Revision: 3 $
* $Date: 11/07/04 16:17 $
* $Author: Anna $
*
* $History: ResOrgSymbolFilesListCtrl.cpp $
*
* ***************** Version 3 *****************
* User: Anna Date: 11/07/04 Time: 16:17
* Updated in $/Projects/AddIns/ResOrg/ResOrgCore
* Added support for detection of out of range symbols
*
* ***************** Version 2 *****************
* User: Anna Date: 15/02/03 Time: 20:45
* Updated in $/Projects/AddIns/ResOrg/ResOrgCore
* Now supports multiple selection
*
* ***************** Version 1 *****************
* User: Anna Date: 19/01/03 Time: 17:27
* Created in $/Projects/AddIns/ResOrg/ResOrgCore
* CResOrgSymbolFilesListCtrl - list control class for resource symbol
* files (Used in the "File" page of the File Properties Dialog when
* multiple files are opened)
*
* $Nokeywords: $
*
************************************************************************/
#include "StdAfx.h"
#include "ResOrgCore_Priv.h"
#include "ResOrgSymbolFilesListCtrl.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
// Definitions for List Control column indices and titles
enum
{
UNKNOWN_COLUMN = -1,
NAME_COLUMN = 0,
SYMBOLS_COLUMN,
OUT_OF_RANGE_COLUMN,
INT_CONFLICTS_COLUMN,
EXT_CONFLICTS_COLUMN,
NEXT_SYM_COLUMN
};
static DATA_TYPE eColumnType[] =
{
DT_STRING, // Name
DT_DEC, // Symbols
DT_DEC, // Out of range symbols
DT_DEC, // Internal conflicts
DT_DEC, // External conflicts
DT_STRING, // Next symbols
};
/////////////////////////////////////////////////////////////////////////////
// CResOrgSymbolFilesListCtrl class
/******************************************************************************
* Message Map implementation
*
******************************************************************************/
BEGIN_MESSAGE_MAP(CResOrgSymbolFilesListCtrl, CResOrgSymbolFilesListCtrl_BASE)
ON_WM_CREATE()
ON_NOTIFY_REFLECT( NM_CUSTOMDRAW, OnCustomDraw)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CResOrgSymbolFilesListCtrl construction/destruction
CResOrgSymbolFilesListCtrl::CResOrgSymbolFilesListCtrl(void)
{
m_nSortColumn = NAME_COLUMN;
m_bSortAscending = true;
m_pResourceSymbolManager = NULL;
}
CResOrgSymbolFilesListCtrl::~CResOrgSymbolFilesListCtrl(void)
{
}
/////////////////////////////////////////////////////////////////////////////
// CResOrgSymbolFilesListCtrl overrides
void CResOrgSymbolFilesListCtrl::PreSubclassWindow(void)
{
CResOrgSymbolFilesListCtrl_BASE::PreSubclassWindow();
Initialise();
}
/******************************************************************************
* Sort the contents of the control by the specified column
*
******************************************************************************/
bool CResOrgSymbolFilesListCtrl::SortList(int nColumn, bool bAscending)
{
CResOrgSymbolFilesListCtrl_BASE::SortList(nColumn, bAscending);
m_nSortColumn = nColumn;
m_bSortAscending = bAscending;
// Re-sort contents if sorted before
if (m_nSortColumn >= 0)
{
CResOrgSymbolFilesListCtrl_BASE::SortList(nColumn, bAscending);
CCJSortClass sorter(this, nColumn);
sorter.Sort(bAscending, eColumnType[nColumn]);
return true;
}
return false;
}
/////////////////////////////////////////////////////////////////////////////
// CResOrgSymbolFilesListCtrl implementation
/// Initialise the list control before display.
void CResOrgSymbolFilesListCtrl::Initialise(void)
{
// Create the columns in the the List Control
//
// For each row the properties specified are:
//
// 1. SubItem field number (0 based)
// 2. Text
// 3. Justification
// 4. Initial width in pixels, size to content (LVSCW_AUTOSIZE) or
// size to header (LVSCW_AUTOSIZE_USEHEADER)
//
ModifyStyle(LVS_ICON | LVS_SMALLICON | LVS_LIST,
LVS_REPORT | LVS_SHOWSELALWAYS);
SetExtendedStyle(GetExtendedStyle() | LVS_EX_FULLROWSELECT );
VERIFY (-1 != InsertColumn(NAME_COLUMN, _T("Name"), LVCFMT_LEFT, 100, 0) );
VERIFY (-1 != InsertColumn(SYMBOLS_COLUMN, _T("Symbols"), LVCFMT_LEFT, 80, 0) );
VERIFY (-1 != InsertColumn(OUT_OF_RANGE_COLUMN, _T("Out of Range"), LVCFMT_LEFT, 80, 1));
VERIFY (-1 != InsertColumn(INT_CONFLICTS_COLUMN, _T("Int.Conflicts"), LVCFMT_LEFT, 80, 1));
VERIFY (-1 != InsertColumn(EXT_CONFLICTS_COLUMN, _T("Ext. Conflicts"), LVCFMT_LEFT, 80, 1));
VERIFY (-1 != InsertColumn(NEXT_SYM_COLUMN, _T("Next Sym."), LVCFMT_LEFT, 80, 1));
}
bool CResOrgSymbolFilesListCtrl::SetSymbolManager(CResourceSymbolManagerMultiFile* pResourceSymbolManager)
{
if (m_pResourceSymbolManager != pResourceSymbolManager)
{
if (::IsWindow(m_hWnd) )
{
DeleteAllItems();
}
m_pResourceSymbolManager = pResourceSymbolManager;
}
return (NULL != m_pResourceSymbolManager);
}
void CResOrgSymbolFilesListCtrl::AddFiles(CResourceSymbolManagerMultiFile* pResourceSymbolManager)
{
SetSymbolManager(pResourceSymbolManager);
SetRedraw(FALSE);
DeleteAllItems();
if (NULL != m_pResourceSymbolManager)
{
CStringArray arrayPathNames;
m_pResourceSymbolManager->GetSymbolFilePathNames(arrayPathNames);
for (int n = 0; n < arrayPathNames.GetSize(); n++)
{
CString sPathName = arrayPathNames[n];
if (!sPathName.IsEmpty() )
{
CResourceSymbolManager* pFile = m_pResourceSymbolManager->GetSymbolManager(sPathName);
if (NULL != pFile)
{
AddFile(pFile);
}
}
SortList(m_nSortColumn, m_bSortAscending);
//AutoSizeColumn();
}
}
SetRedraw(TRUE);
Invalidate();
UpdateWindow();
RedrawWindow();
}
bool CResOrgSymbolFilesListCtrl::AddFile(CResourceSymbolManager* pFile)
{
int nItem = FindFile(pFile);
if (nItem < 0)
{
int nItem = InsertItem( GetItemCount(),
_T(""));
if (nItem >= 0)
{
SetItemData(nItem, (LPARAM)pFile);
UpdateFile(pFile);
return true;
}
}
return false;
}
bool CResOrgSymbolFilesListCtrl::UpdateFile(CResourceSymbolManager* pFile)
{
int nItem = FindFile(pFile);
if (nItem >= 0)
{
CNGSplitPath split(pFile->GetPathName() );
CString sLabel = split.GetFileName() + split.GetExtension();
if (pFile->IsModified() )
{
sLabel += _T(" *");
}
int nOutOfRangeSymbols = pFile->GetOutOfRangeSymbolCount();
int nInternalConflicts = pFile->GetConflictCount();
int nTotalConflicts = m_pResourceSymbolManager->GetTotalConflictCount(pFile);
int nExternalConflicts = nTotalConflicts - nInternalConflicts;
SetItemText(nItem, NAME_COLUMN, sLabel);
SetItemText(nItem, SYMBOLS_COLUMN, ::IntToStr(pFile->GetSymbolCount() ) );
SetItemText(nItem, OUT_OF_RANGE_COLUMN, ::IntToStr(nOutOfRangeSymbols) );
SetItemText(nItem, INT_CONFLICTS_COLUMN, ::IntToStr(nInternalConflicts) );
SetItemText(nItem, EXT_CONFLICTS_COLUMN, ::IntToStr(nExternalConflicts) );
SetItemText(nItem, NEXT_SYM_COLUMN, pFile->AreNextSymbolValuesInUse() ? _T("In use") : _T("Ok") );
}
return (nItem != -1);
}
bool CResOrgSymbolFilesListCtrl::UpdateAllFiles(void)
{
SetRedraw(FALSE);
for (int nItem = 0; nItem < GetItemCount(); nItem++)
{
CResourceSymbolManager* pFile = GetFile(nItem);
if (NULL != pFile)
{
UpdateFile(pFile);
}
}
SetRedraw(TRUE);
return (GetItemCount() > 0);
}
bool CResOrgSymbolFilesListCtrl::RemoveFile(CResourceSymbolManager* pFile)
{
int nItem = FindFile(pFile);
if (nItem >= 0)
{
DeleteItem(nItem);
return true;
}
return false;
}
void CResOrgSymbolFilesListCtrl::RemoveAllFiles(void)
{
DeleteAllItems();
}
bool CResOrgSymbolFilesListCtrl::Sort(void)
{
if (m_nSortColumn >= NAME_COLUMN)
{
SortList(m_nSortColumn, m_bSortAscending);
return true;
}
return false;
}
int CResOrgSymbolFilesListCtrl::FindFile(CResourceSymbolManager* pFile) const
{
int nItem = -1;
if (NULL != pFile)
{
LV_FINDINFO FindInfo;
FindInfo.flags = LVFI_PARAM;
FindInfo.lParam = (DWORD)pFile;
nItem = FindItem(&FindInfo);
}
return nItem;
}
int CResOrgSymbolFilesListCtrl::GetSelection(CSymbolManagerPtrArray& rarrayManagers) const
{
rarrayManagers.RemoveAll();
int nItem = -1;
do
{
nItem = GetNextItem(nItem, LVNI_ALL | LVNI_SELECTED);
if (nItem >= 0)
{
// Get the data value from nItem
// This translates into a pointer to the data object
CResourceSymbolManager* pFile = GetFile(nItem);
#ifdef _DEBUG
ASSERT(NULL != pFile);
if (NULL != pFile)
{
ASSERT_KINDOF(CResourceSymbolManager, pFile);
}
#endif
rarrayManagers.Add(pFile);
}
} while (nItem >= 0);
return rarrayManagers.GetSize();
}
CResourceSymbolManager* CResOrgSymbolFilesListCtrl::GetFile(int nItem) const
{
if (nItem >= 0)
{
// Get the data value from nItem
// This translates into a pointer to the data object
CResourceSymbolManager* pFile = reinterpret_cast<CResourceSymbolManager*>( GetItemData(nItem) );
#ifdef _DEBUG
ASSERT(NULL != pFile);
if (NULL != pFile)
{
ASSERT(pFile->IsKindOf(RUNTIME_CLASS(CResourceSymbolManager) ) );
}
#endif
return pFile;
}
return NULL;
}
/////////////////////////////////////////////////////////////////////////////
// CResOrgSymbolFilesListCtrl message handlers
int CResOrgSymbolFilesListCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
int nResult = CResOrgSymbolFilesListCtrl_BASE::OnCreate(lpCreateStruct);
if (-1 != nResult)
{
Initialise();
}
return nResult;
}
void CResOrgSymbolFilesListCtrl::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)pNMHDR;
CResOrgSymbolFilesListCtrl_BASE::OnCustomDraw(pNMHDR, pResult);
switch (lplvcd->nmcd.dwDrawStage)
{
case CDDS_PREPAINT:
*pResult = CDRF_NOTIFYITEMDRAW; // Request prepaint notifications for each item.
break;
case CDDS_ITEMPREPAINT: // Requested notification
if (lplvcd->nmcd.dwItemSpec >= 0)
{
if (CLR_DEFAULT != m_clrText)
{
lplvcd->clrText = m_clrText;
}
CResourceSymbolManager* pFile = reinterpret_cast<CResourceSymbolManager*>(lplvcd->nmcd.lItemlParam);
if (NULL != pFile)
{
if ( pFile->GetProblemSymbolCount() > 0)
{
// Highlight files with problem symbols in red...
lplvcd->clrText = RGB(255,0,0);
}
else if (pFile->IsModified())
{
// ...and changed files in blue...
lplvcd->clrText = RGB(0,0,255);
}
}
}
break;
case CDDS_ITEMPOSTPAINT:
*pResult = CDRF_DODEFAULT;
break;
default:
break;
}
}