/************************************************************************
*
* Resource ID Organiser Core Library
*
* (c) Copyright 2000-2004 by Riverblade Limited (UK). All rights reserved.
*
************************************************************************
*
* Description : CResOrgSymbolsListView - list view class for a resource
* symbol file
*
* Target
* Environment : Windows 98/NT/2000/XP
*
* NOTE:
*
* This software is provided "as is". All title and copyrights in and
* to the software, including but not limited to any images, text etc.
* etc. incorporated into it, are the property of Anna-Jayne Metcalfe
* and Riverblade Limited, except where acknowledged otherwise.
*
* Your may freely use this code in your own products, PROVIDED
* this notice is not removed or modified.
*
* For support and updates please visit http://www.riverblade.co.uk/products/resorg
* or email support@riverblade.co.uk
*
************************************************************************
*
* MODIFICATION HISTORY:
*
* This is a controlled document. See project configuration
* control tool for latest version and full version history.
*
* $Archive: /Projects/AddIns/ResOrg/ResOrgCore/ResOrgSymbolsListView.cpp $
* $Revision: 38 $
* $Date: 13/12/04 3:58 $
* $Author: Anna $
*
* $History: ResOrgSymbolsListView.cpp $
*
* ***************** Version 38 *****************
* User: Anna Date: 13/12/04 Time: 3:58
* Updated in $/Projects/AddIns/ResOrg/ResOrgCore
* 1. Modifications fo compatibility with dynamic splitters
* 2. Updated file banners
*
* ***************** Version 37 *****************
* User: Anna Date: 29/08/04 Time: 21:16
* Updated in $/Projects/AddIns/ResOrg/ResOrgCore
* CResourceSymbolsListView::OnCmdSymbolProperties() now allows the
* command to continue routing if there isn't a single selection...this
* allows CResOrgSymbolsDoc to handle it to display Symbol File properties
* instead.
*
* ***************** Version 36 *****************
* 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 35 *****************
* User: Anna Date: 2/06/04 Time: 22:56
* Updated in $/Projects/AddIns/ResOrg/ResOrgCore
* Added "Next Conflict" and "Previous Conflict" commands
*
* ***************** Version 34 *****************
* User: Anna Date: 26/06/03 Time: 19:51
* Updated in $/Projects/AddIns/ResOrg/ResOrgCore
* CResOrgSymbolsListView::OnUpdate() no longer does anything if the view
* has not yet been initialised. This prevents unnecessary refreshes with
* multi-file Symbols Displays, and ensures that the conflict filtering
* works properly
*
* ***************** Version 33 *****************
* User: Anna Date: 15/04/03 Time: 20:47
* Updated in $/Projects/AddIns/ResOrg/ResOrgCore
* CResOrgSymbolsListView::OnCmdFixConflicts() now switches if filtering
* (if enabled) if no conflicts remain afterwards
*
* ***************** Version 32 *****************
* User: Anna Date: 26/03/03 Time: 14:11
* Updated in $/Projects/AddIns/ResOrg/ResOrgCore
* New multi-file Symbols Displays are now only filtered if there are
* actually conflicts!
*
* ***************** Version 31 *****************
* User: Anna Date: 19/03/03 Time: 19:13
* Updated in $/Projects/AddIns/ResOrg/ResOrgCore
* CResOrgSymbolsListView::OnCmdFixConflicts() now removes symbols with no
* conflicts from the display after a "Fix Conflicts" operation if
* filtering is enabled
*
* ***************** Version 30 *****************
* User: Anna Date: 3/03/03 Time: 20:09
* Updated in $/Projects/AddIns/ResOrg/ResOrgCore
* Minor bug fix in CResOrgSymbolsListView::OnCmdFixConflicts()
*
* ***************** Version 29 *****************
* User: Anna Date: 15/02/03 Time: 20:48
* Updated in $/Projects/AddIns/ResOrg/ResOrgCore
* Changed big BOOLs into little bools
*
* ***************** Version 28 *****************
* User: Anna Date: 3/01/03 Time: 15:52
* Updated in $/Projects/AddIns/ResOrg/ResOrgCore
* Disabled the "Add Symbol" command if the view is multi-file. This ay be
* temporary - wait and see
*
* ***************** Version 27 *****************
* User: Anna Date: 3/01/03 Time: 7:36
* Updated in $/Projects/AddIns/ResOrg/ResOrgCore
* Added an option to filter multi-file Symbols Displays by default
*
* ***************** Version 26 *****************
* User: Anna Date: 2/01/03 Time: 23:54
* Updated in $/Projects/AddIns/ResOrg/ResOrgCore
* Added filtering to the Symbols Display
*
* ***************** Version 25 *****************
* User: Anna Date: 25/11/02 Time: 15:14
* Updated in $/Projects/AddIns/ResOrg/ResOrgCore
* Changed website address in banner
*
* ***************** Version 24 *****************
* User: Anna Date: 22/10/02 Time: 13:24
* Updated in $/Projects/AddIns/ResOrg/ResOrgCore
* Changed name/mail address (at last!)
*
* ***************** Version 23 *****************
* User: Andy Date: 7/06/02 Time: 17:04
* Updated in $/Projects/AddIns/ResOrg/ResOrgCore
* Renamed the ResOrgUtils module to ResOrgCore. Updated file banners
* accordingly
*
* ***************** Version 22 *****************
* User: Andy Date: 27/05/02 Time: 14:51
* Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
* Knock on changes from CResourceSymbolBuffer (now
* CResourceSymbolManager) and CResourceSymbol
*
* ***************** Version 21 *****************
* User: Andy Date: 10/05/02 Time: 15:58
* Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
* CResOrgSymbolsListView::OnCmdDeleteSymbol() now marks the document as
* modified if multiply selected symbols are deleted
*
* ***************** Version 20 *****************
* User: Andy Date: 27/04/02 Time: 0:34
* Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
* Corrected CResOrgSymbolsListView::OnCmdDeleteSymbol() - multiple symbol
* deletion was broken
*
* ***************** Version 19 *****************
* User: Andy Date: 12/29/01 Time: 11:42p
* Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
* Got rid of compiler warnings
*
* ***************** Version 18 *****************
* User: Andy Date: 12/29/01 Time: 6:26p
* Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
* Added "Restore Original Value" command
*
* ***************** Version 17 *****************
* User: Andy Date: 12/27/01 Time: 11:51p
* Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
* Minor bug fixes
*
* ***************** Version 16 *****************
* User: Andy Date: 10/03/01 Time: 12:27p
* Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
* CResOrgSymbolsListView::OnCmdSymbolProperties() now calls
* CResOrgSymbolsDoc::CheckNextSymbolValues() after loading to ensure that
* the "Next Symbol" values are OK.
*
* ***************** Version 15 *****************
* User: Andy Date: 15/08/01 Time: 13:37
* Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
* Added a "Fix Conflicts" context menu command
*
* ***************** Version 14 *****************
* User: Andy Date: 24/07/01 Time: 11:24
* Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
* The Symbols Display list control is now created with the
* LVS_SHOWSELALWAYS style so that the selection is retained when it loses
* the focus
*
* ***************** Version 13 *****************
* User: Andy Date: 26/05/01 Time: 15:23
* Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
* Added OnHelpHitTest() override
*
* ***************** Version 12 *****************
* User: Andy Date: 5/05/01 Time: 20:50
* Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
* Optimised OnInitialUpdate()
*
* ***************** Version 11 *****************
* User: Andy Date: 23/04/01 Time: 21:17
* Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
* Added icons to context menus
*
* ***************** Version 10 *****************
* User: Andy Date: 2/04/01 Time: 17:40
* Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
* Added "Autosize Columns" context menu entry
*
* ***************** Version 9 *****************
* User: Andy Date: 27/03/01 Time: 15:23
* Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
* Modifications to integrate the "Conflicts" tab to Resource Symbol
* properties
*
* ***************** Version 8 *****************
* User: Andy Date: 9/03/01 Time: 12:37
* Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
* Remove "Apply" button from Symbol Properties
*
* ***************** Version 7 *****************
* User: Andy Date: 9/03/01 Time: 7:07
* Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
* Interfacing changes to symbol properties sheet
*
* ***************** Version 6 *****************
* User: Andy Date: 5/03/01 Time: 19:02
* Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
* Set default item on context menu
*
* ***************** Version 5 *****************
* User: Andy Date: 2/03/01 Time: 17:10
* Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
* 1. Added accelerator keys to message boxes
* 2. Context Menu handler now displays a context menu even if the mouse
* position is not over an item in the list control
* 3. Implemented CResOrgSymbolsListView::OnCmdAddSymbol()
*
* ***************** Version 4 *****************
* User: Andy Date: 17/02/01 Time: 7:00
* Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
* 1. Moved generic list control code into a new class
* (CResOrgSymbolsListCtrl)
* 2. Class renamed for consistancy
* 3. Added a "Status" column
* 4. Show modified symbols in blue, and read-only symbols in grey
* [handled by CResOrgSymbolsListCtrl]
* 5. Use new wrapper methods in the document to manipulate its
* CResourceSymbolBuffer object rather than accessing it directly. This
* allows most of the view hints to be moved to the document
*
* ***************** Version 3 *****************
* User: Andy Date: 29/11/00 Time: 18:38
* Updated in $/Projects/AddIns/ResOrg/ResOrgUtils
* Added file banners
*
* $Nokeywords: $
*
************************************************************************/
#include "StdAfx.h"
#include <AfxPriv.h>
#include "ResOrgCore_Priv.h"
#include "ResourceSymbol.h"
#include "ResourceSymbolManager.h"
#include "ResourceSymbolManagerMultiFile.h"
#include "SymbolPropertySheet.h"
#include "SymbolPropertiesGeneralPage.h"
#include "SymbolPropertiesConflictsPage.h"
#include "ResOrgSymbolsDoc.h"
#include "ResOrgSymbolsListView.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,
TYPE_COLUMN,
ID_COLUMN
};
const UINT WM_SETSCROLLINFO = ::RegisterWindowMessage( _T("SetScrollInfo") );
/////////////////////////////////////////////////////////////////////////////
// CResOrgSymbolsListView
IMPLEMENT_DYNCREATE(CResOrgSymbolsListView, CResOrgSymbolsListView_BASE)
/******************************************************************************
* Message Map implementation
*
******************************************************************************/
BEGIN_MESSAGE_MAP(CResOrgSymbolsListView, CResOrgSymbolsListView_BASE)
ON_WM_CREATE()
ON_WM_SIZE()
ON_REGISTERED_MESSAGE( WM_SETSCROLLINFO, OnMsgSetScrollInfo)
ON_WM_HSCROLL()
ON_WM_VSCROLL()
ON_WM_CONTEXTMENU()
ON_MESSAGE( WM_HELPHITTEST, OnHelpHitTest)
ON_NOTIFY( LVN_ITEMCHANGED, IDC_RESORG_SYMBOLS, OnItemChangedListCtrl)
ON_NOTIFY( NM_DBLCLK, IDC_RESORG_SYMBOLS, OnDblClickListCtrl)
ON_COMMAND( ID_SYM_AUTOSIZE_COLS, OnCmdAutosizeColumns)
ON_COMMAND( ID_SYM_PROBLEMS_ONLY, OnCmdShowProblemSymbolsOnly)
ON_UPDATE_COMMAND_UI( ID_SYM_PROBLEMS_ONLY, OnUpdateShowProblemSymbolsOnly)
ON_COMMAND( ID_EDIT_SELECT_ALL, OnCmdEditSelectAll)
ON_UPDATE_COMMAND_UI( ID_EDIT_SELECT_ALL, OnUpdateEditSelectAll)
ON_COMMAND_EX( ID_SYM_PROPERTIES, OnCmdSymbolProperties)
ON_COMMAND( ID_SYM_ADD, OnCmdAddSymbol)
ON_UPDATE_COMMAND_UI( ID_SYM_ADD, OnUpdateAddSymbol)
ON_COMMAND( ID_EDIT_CLEAR, OnCmdDeleteSymbol)
ON_UPDATE_COMMAND_UI( ID_EDIT_CLEAR, OnUpdateDeleteSymbol)
ON_COMMAND( ID_SYM_RESORE_VALUE, OnCmdRestoreOriginalValue)
ON_UPDATE_COMMAND_UI( ID_SYM_RESORE_VALUE, OnUpdateRestoreOriginalValue)
ON_COMMAND( ID_SYM_FIX_NOW, OnCmdFixSymbolValue)
ON_UPDATE_COMMAND_UI( ID_SYM_FIX_NOW, OnUpdateFixSymbolValue)
ON_COMMAND( ID_SYM_PROBLEM_PREVIOUS, OnCmdPreviousProblemSymbol)
ON_UPDATE_COMMAND_UI( ID_SYM_PROBLEM_PREVIOUS, OnUpdatePreviousProblemSymbol)
ON_COMMAND( ID_SYM_PROBLEM_NEXT, OnCmdNextProblemSymbol)
ON_UPDATE_COMMAND_UI( ID_SYM_PROBLEM_NEXT, OnUpdateNextProblemSymbol)
// Standard printing commands
ON_COMMAND( ID_FILE_PRINT, CResOrgSymbolsListView_BASE::OnFilePrint)
ON_COMMAND( ID_FILE_PRINT_DIRECT, CResOrgSymbolsListView_BASE::OnFilePrint)
ON_COMMAND( ID_FILE_PRINT_PREVIEW, CResOrgSymbolsListView_BASE::OnFilePrintPreview)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CResOrgSymbolsListView construction/destruction
CResOrgSymbolsListView::CResOrgSymbolsListView(void)
{
m_bInitialised = FALSE;
m_nLastHPos = 0;
m_nLastVPos = 0;
}
CResOrgSymbolsListView::~CResOrgSymbolsListView(void)
{
}
/////////////////////////////////////////////////////////////////////////////
// CResOrgSymbolsListView overrides
/******************************************************************************
* This method is called by the framework before the creation of the
* window attached to this CWnd object.
*
* This override is used to modify the window styles here to set the List
* control style to report view.
*
* This is achieved by masking out the view style using LVS_TYPEMASK
* and setting the LVS_REPORT style. LVS_SINGLESEL is also set to allow
* only single selections.
*
* Note that we DON'T want the LVS_SORTASCENDING style as this sorts items
* by item text and in this case we cannot have a comparison function.
*
******************************************************************************/
BOOL CResOrgSymbolsListView::PreCreateWindow(CREATESTRUCT& cs)
{
cs.style = (cs.style & ~LVS_TYPEMASK) | LVS_REPORT;
return CResOrgSymbolsListView_BASE::PreCreateWindow(cs);
}
/******************************************************************************
* Called by the framework to render an image of the document.
*
* The framework calls this function to perform screen display, printing,
* and print preview, and it passes a different device context in each case.
*
* As the list control does everything for us, this override is not currently
* used.
*
* It will however be required if printing and print preview is to be
* implemented
*
******************************************************************************/
void CResOrgSymbolsListView::OnDraw(CDC* /*pDC*/)
{
}
/******************************************************************************
* Called by the framework after the view is first attached to the document,
* but before the view is initially displayed.
*
* This override is used to configure the list control before display.
*
******************************************************************************/
void CResOrgSymbolsListView::OnInitialUpdate(void)
{
// Initialise the List Control
if (!m_bInitialised)
{
Initialise();
//HideScrollBars(SB_VERT);
}
// Call the base class to fill in the list view and invalidate the entire area
// so that it will be painted
CResOrgSymbolsListView_BASE::OnInitialUpdate();
m_ctrlSymbols.AutoSizeColumn();
}
/******************************************************************************
* Called by the framework after the view�s document has been modified.
*
* This override is used to update the data in the list control
*
******************************************************************************/
void CResOrgSymbolsListView::OnUpdate(CView* pSender,
LPARAM lHint,
CObject* pHint)
{
UNREFERENCED_PARAMETER(pSender);
if (!m_bInitialised)
{
// If we haven't been initialised yet don't do anything -
// this is particularly important with multi-file symbol views
return;
}
switch (lHint)
{
case SYM_REFRESH:
{
CWaitCursor wait;
CResourceSymbolManager* pMngr = GetDocument()->GetSymbolBuffer();
if ( (NULL != pMngr) && (NULL == m_ctrlSymbols.GetSymbolManager() ) )
{
if (Options.FilterMultiFileSymbolsDisplays() &&
pMngr->IsKindOf(RUNTIME_CLASS(CResourceSymbolManagerMultiFile) ) &&
(pMngr->GetProblemSymbolCount() > 0) )
{
m_ctrlSymbols.ShowProblemSymbolsOnly(true);
}
}
m_ctrlSymbols.AddSymbols(pMngr); // Sledgehammer approach - slow but effective
}
break;
case SYM_ADDED:
m_ctrlSymbols.AddSymbol( (CResourceSymbol*)pHint );
m_ctrlSymbols.Sort();
break;
case SYM_CHANGED:
m_ctrlSymbols.UpdateSymbol( (CResourceSymbol*)pHint );
m_ctrlSymbols.Sort();
break;
case SYM_DELETED:
m_ctrlSymbols.RemoveSymbol( (CResourceSymbol*)pHint );
break;
default:
break;
}
}
/////////////////////////////////////////////////////////////////////////////
// CResOrgSymbolsListView printing
BOOL CResOrgSymbolsListView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CResOrgSymbolsListView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CResOrgSymbolsListView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
/////////////////////////////////////////////////////////////////////////////
// CResOrgSymbolsListView diagnostics
#ifdef _DEBUG
void CResOrgSymbolsListView::AssertValid(void) const
{
CResOrgSymbolsListView_BASE::AssertValid();
}
void CResOrgSymbolsListView::Dump(CDumpContext& dc) const
{
CResOrgSymbolsListView_BASE::Dump(dc);
}
CResOrgSymbolsDoc* CResOrgSymbolsListView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CResOrgSymbolsDoc)));
return (CResOrgSymbolsDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CResOrgSymbolsListView implementation
void CResOrgSymbolsListView::Initialise(void)
{
if (!m_bInitialised)
{
m_ctrlSymbols.Initialise(TRUE);
m_bInitialised = TRUE;
}
}
void CResOrgSymbolsListView::ConfigureScrollbars(void)
{
SCROLLINFO infoHorz;
m_ctrlSymbols.GetScrollInfo(SB_HORZ, &infoHorz);
SetScrollInfo(SB_HORZ, &infoHorz, true);
SCROLLINFO infoVert;
m_ctrlSymbols.GetScrollInfo(SB_VERT, &infoVert);
SetScrollInfo(SB_VERT, &infoVert, true);
}
BOOL CResOrgSymbolsListView::ConfirmDelete(const CString& sSymbol /*= _T("")*/ ) const
{
CNGMessageBox dlg;
if (!sSymbol.IsEmpty())
{
dlg.FormatMsgEx(MAKEINTRESOURCE(IDP_SYM_DELETE_WARNING_EX),
_T("RTF"),
sSymbol);
}
else
{
dlg.SetMsgEx( MAKEINTRESOURCE( IDP_SYM_DELETE_WARNING),
_T("RTF") );
}
dlg.SetRtf();
dlg.SetStandardIcon(IDI_WARNING);
dlg.AddButton(IDYES, FALSE, FALSE, _T("&Yes") );
dlg.AddButton(IDNO, TRUE, TRUE, _T("&No") );
return (IDYES == dlg.DoModal());
}
BOOL CResOrgSymbolsListView::IsValueUnique( CResourceSymbol* pSymbol,
UINT uValue)
{
BOOL bUnique = TRUE;
if ( (NULL != GetDocument()->GetSymbolBuffer()) && (NULL != pSymbol) )
{
CResourceSymbolList listSymbols;
GetDocument()->GetSymbolBuffer()->GetSymbols(uValue, listSymbols);
POSITION pos = listSymbols.GetHeadPosition();
while (pos != NULL)
{
CResourceSymbol* pNextSymbol = listSymbols.GetNext(pos);
if (pNextSymbol != NULL)
{
if (pNextSymbol != pSymbol)
{
bUnique = FALSE;
break;
}
}
}
}
return bUnique;
}
/////////////////////////////////////////////////////////////////////////////
// CResOrgSymbolsListView message handlers
int CResOrgSymbolsListView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
int nResult = CResOrgSymbolsListView_BASE::OnCreate(lpCreateStruct);
if (-1 != nResult)
{
if (!m_ctrlSymbols.Create( WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_SHOWSELALWAYS,
CRect(0,0,0,0),
this,
IDC_RESORG_SYMBOLS))
{
TRACE( _T("Failed to create symbols list control.\n"));
return -1;
}
}
return nResult;
}
void CResOrgSymbolsListView::OnSize(UINT nType, int cx, int cy)
{
CResOrgSymbolsListView_BASE::OnSize(nType, cx, cy);
if (m_ctrlSymbols.GetSafeHwnd() != NULL)
{
m_ctrlSymbols.SetWindowPos( NULL,
0,
0,
cx,
cy,
SWP_SHOWWINDOW|SWP_NOZORDER
);
ConfigureScrollbars();
}
}
LRESULT CResOrgSymbolsListView::OnMsgSetScrollInfo(WPARAM wParam, LPARAM lParam)
{
int eBar = (int)wParam;
LPSCROLLINFO pScrollInfo = (LPSCROLLINFO)lParam;
switch (eBar)
{
case SB_VERT:
m_nLastVPos = pScrollInfo->nPos;
SetScrollInfo(eBar, pScrollInfo);
break;
case SB_HORZ:
m_nLastHPos = pScrollInfo->nPos;
SetScrollInfo(eBar, pScrollInfo);
break;
default:
ASSERT(false);
break;
}
return 0L;
}
void CResOrgSymbolsListView::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
UNREFERENCED_PARAMETER(nPos);
// Get the minimum, maximum and current scroll-box positions.
SCROLLINFO info;
pScrollBar->GetScrollInfo(&info);
int nNewPosition = m_nLastHPos;
// Act on the scroll bar operation
switch (nSBCode)
{
case SB_TOP: // Scroll to top
nNewPosition = info.nMin;
break;
case SB_PAGEUP: // Scroll one page up.
nNewPosition = m_nLastHPos - info.nPage;
break;
case SB_LINEUP: // Scroll up
nNewPosition = m_nLastHPos - 1;
break;
case SB_BOTTOM: // Scroll to bottom
nNewPosition = info.nMax;
break;
case SB_LINEDOWN: // Scroll down
if (m_nLastHPos + info.nPage <= info.nMax)
{
nNewPosition = m_nLastHPos + 1;
}
break;
case SB_PAGEDOWN: // Scroll one page down.
if (m_nLastHPos + info.nPage <= info.nMax)
{
nNewPosition = m_nLastHPos + info.nPage;
}
break;
case SB_THUMBPOSITION: // Scroll to absolute position. nTrackPos is the position
nNewPosition = info.nTrackPos; // of the scroll box at the end of the drag operation.
break;
case SB_THUMBTRACK: // Drag scroll box to specified position. nTrackPos is the
nNewPosition = info.nTrackPos; // position that the scroll box has been dragged to.
break;
case SB_ENDSCROLL:
nNewPosition = info.nPos;
break;
default:
ASSERT(false);
break;
}
if (nNewPosition < info.nMin)
{
nNewPosition = info.nMin;
}
else if (nNewPosition > info.nMax)
{
nNewPosition = info.nMax;
}
int nScrollBy = nNewPosition - m_nLastHPos;
m_nLastHPos = nNewPosition;
if (0 != nScrollBy)
{
m_ctrlSymbols.Scroll( CSize(nScrollBy, 0 ) );
SetScrollPos(SB_HORZ, nNewPosition, true);
}
}
void CResOrgSymbolsListView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
UNREFERENCED_PARAMETER(nPos);
// Get the minimum, maximum and current scroll-box positions.
SCROLLINFO info;
pScrollBar->GetScrollInfo(&info);
int nNewPosition = m_nLastVPos;
// Act on the scroll bar operation
switch (nSBCode)
{
case SB_TOP: // Scroll to top
nNewPosition = info.nMin;
break;
case SB_PAGEUP: // Scroll one page up.
nNewPosition = m_nLastVPos - info.nPage;
break;
case SB_LINEUP: // Scroll up
nNewPosition = m_nLastVPos - 1;
break;
case SB_BOTTOM: // Scroll to bottom
nNewPosition = info.nMax;
break;
case SB_LINEDOWN: // Scroll down
if (m_nLastVPos + info.nPage <= info.nMax)
{
nNewPosition = m_nLastVPos + 1;
}
break;
case SB_PAGEDOWN: // Scroll one page down.
if (m_nLastVPos + info.nPage <= info.nMax)
{
nNewPosition = m_nLastVPos + info.nPage;
}
break;
case SB_THUMBPOSITION: // Scroll to absolute position. nTrackPos is the position
nNewPosition = info.nTrackPos; // of the scroll box at the end of the drag operation.
break;
case SB_THUMBTRACK: // Drag scroll box to specified position. nTrackPos is the
nNewPosition = info.nTrackPos; // position that the scroll box has been dragged to.
break;
case SB_ENDSCROLL:
nNewPosition = info.nPos;
break;
default:
ASSERT(false);
break;
}
if (nNewPosition < info.nMin)
{
nNewPosition = info.nMin;
}
else if (nNewPosition > info.nMax)
{
nNewPosition = info.nMax;
}
int nScrollBy = nNewPosition - m_nLastVPos;
m_nLastVPos = nNewPosition;
if (0 != nScrollBy)
{
CRect rectItem;
m_ctrlSymbols.GetItemRect(m_ctrlSymbols.GetTopIndex(), rectItem, LVIR_BOUNDS);
m_ctrlSymbols.Scroll( CSize(0, nScrollBy * rectItem.Height() ) );
SetScrollPos(SB_VERT, nNewPosition, true);
}
}
// Context Menu handler
void CResOrgSymbolsListView::OnContextMenu(CWnd* /*pWnd*/, CPoint point)
{
// Make sure window is active
GetParentFrame()->ActivateFrame();
CCJMenu menu;
if (menu.LoadMenu(IDM_SYM_CONTEXT_MENU))
{
menu.LoadToolbar(IDR_MAINFRAME);
CMenu* pPopup = menu.GetSubMenu(0);
ASSERT(NULL != pPopup);
pPopup->SetDefaultItem(ID_SYM_PROPERTIES);
pPopup->TrackPopupMenu(TPM_RIGHTBUTTON | TPM_LEFTALIGN,
point.x,
point.y,
AfxGetMainWnd() ); // Route commands through the main window
return;
}
Default(); // Default message handling if we didn't do anything
}
void CResOrgSymbolsListView::OnItemChangedListCtrl(NMHDR* /*pNMHDR*/, LRESULT* pResult)
{
*pResult = 0;
ConfigureScrollbars();
}
/******************************************************************************
* Called when the user double clicks on an item in the list
*
******************************************************************************/
void CResOrgSymbolsListView::OnDblClickListCtrl(NMHDR* /*pNMHDR*/, LRESULT* pResult)
{
*pResult = 0;
OnCmdSymbolProperties();
}
void CResOrgSymbolsListView::OnCmdAutosizeColumns(void)
{
m_ctrlSymbols.AutoSizeColumn();
}
/******************************************************************************
* Handlers for Edit|Select All menu command
*
******************************************************************************/
void CResOrgSymbolsListView::OnCmdEditSelectAll(void)
{
#if 0
CMapStringToPtr* pMap = GetDocument()->GetSymbolMap();
ASSERT(NULL != pMap);
POSITION pos = pMap->GetStartPosition();
// Zoom through the map...
CString sKey;
CResourceSymbol* pSymbol = NULL;
while (NULL != pos)
{
pMap->GetNextAssoc(pos, sKey, (LPVOID&)pSymbol );
if (NULL != pSymbol)
{
LV_FINDINFO FindInfo;
FindInfo.flags = LVFI_PARAM;
FindInfo.lParam = (DWORD)pSymbol;
int nItem = GetListCtrl().FindItem(&FindInfo);
if (nItem >= 0)
{
GetListCtrl().SetItemState(nItem, /*LVIS_FOCUSED |*/ LVIS_SELECTED, 0xff);
}
}
}
#endif
}
void CResOrgSymbolsListView::OnUpdateEditSelectAll(CCmdUI* pCmdUI)
{
pCmdUI->Enable( TRUE );
// pCmdUI->Enable( !GetDocument()->IsEmpty() );
}
/// Handler for the ID_SYM_PROPERTIES command.
///
/// If a single symbol is selected, this handler opens its properties.
/// If there is no selection or a multiple selection, the command is
/// allowed to continue routing. In this case, the document (CResOrgSymbolsDoc)
/// will handle the command to open the properties of the file instead.
///
BOOL CResOrgSymbolsListView::OnCmdSymbolProperties(UINT nID /*= 0*/)
{
UNREFERENCED_PARAMETER(nID);
CResourceSymbol* pSymbol = m_ctrlSymbols.GetSelection();
if (NULL != pSymbol)
{
// Create a dialog object and let it do the difficult bit
CSymbolPropertySheet dlg(IDP_SYM_PROPERTIES_CAPTION, this);
dlg.Initialise( GetDocument()->GetSymbolBuffer(),
pSymbol);
if (IDOK == dlg.DoModal())
{
GetDocument()->Set( pSymbol,
dlg.GeneralPage().GetName(),
dlg.GeneralPage().GetValue(),
(FALSE != dlg.GeneralPage().IsReadOnly() ) );
GetDocument()->CheckNextSymbolValues( Options.WarnIfNextSymbolValuesInUse() );
}
return true; // Handled
}
return false; // Not handled
}
void CResOrgSymbolsListView::OnCmdAddSymbol(void)
{
CResourceSymbolManager* pManager = GetDocument()->GetSymbolBuffer();
if (NULL == pManager)
{
ASSERT(FALSE);
return;
}
CString sName = pManager->GetUnusedName(SYM_RESOURCE);
ASSERT(!sName.IsEmpty());
CResourceSymbol Symbol(sName, pManager->GetNextResourceValue() );
// Create a dialog object and let it do the difficult bit
CSymbolPropertySheet dlg(IDP_SYM_ADD_CAPTION, this);
dlg.Initialise(pManager, &Symbol);
dlg.GeneralPage().DisableSymbolChangeWarnings(); // This is a new symbol, so don't warn
if (IDOK == dlg.DoModal())
{
CResourceSymbol* pSymbol = GetDocument()->Add( dlg.GeneralPage().GetName(),
dlg.GeneralPage().GetValue(),
0);
ASSERT(NULL!= pSymbol);
if (NULL!= pSymbol)
{
pSymbol->SetReadOnly(FALSE != dlg.GeneralPage().IsReadOnly() );
GetDocument()->UpdateAllViews(NULL, SYM_CHANGED, (CObject*)pSymbol); // For read only attribute only
// Select the new symbol
int nItem = m_ctrlSymbols.FindSymbol(pSymbol);
if (nItem >= 0)
{
m_ctrlSymbols.EnsureVisible(nItem, FALSE);
m_ctrlSymbols.SetItemState(nItem, LVIS_SELECTED, LVIS_SELECTED);
}
}
}
}
void CResOrgSymbolsListView::OnUpdateAddSymbol(CCmdUI* pCmdUI)
{
pCmdUI->Enable(!GetDocument()->GetSymbolBuffer()->IsKindOf(RUNTIME_CLASS(CResourceSymbolManagerMultiFile) ) );
}
void CResOrgSymbolsListView::OnCmdDeleteSymbol(void)
{
CResourceSymbol* pSymbol = NULL;
switch (m_ctrlSymbols.GetSelectedCount())
{
case 1:
pSymbol = m_ctrlSymbols.GetSelection();
if (NULL != pSymbol) // Single selection
{
BOOL bOkToDelete = TRUE;
if (Options.WarnOnSymbolChanges())
{
if (!ConfirmDelete(pSymbol->GetName() ) )
{
bOkToDelete = FALSE;
}
}
if (bOkToDelete)
{
GetDocument()->Remove(pSymbol);
}
}
break;
default: // Multiple (or no) selection
BOOL bOkToDelete = TRUE;
if (Options.WarnOnSymbolChanges())
{
if (!ConfirmDelete() )
{
bOkToDelete = FALSE;
}
}
if (bOkToDelete)
{
CResourceSymbolList listSymbols;
m_ctrlSymbols.GetSelection(listSymbols);
ASSERT(listSymbols.GetCount() > 0);
POSITION pos = listSymbols.GetHeadPosition();
while (NULL != pos)
{
pSymbol = listSymbols.GetNext(pos);
GetDocument()->GetSymbolBuffer()->Remove(pSymbol);
delete pSymbol;
}
GetDocument()->SetModifiedFlag();
GetDocument()->UpdateAllViews(NULL, SYM_REFRESH, NULL);
}
break;
}
}
void CResOrgSymbolsListView::OnUpdateDeleteSymbol(CCmdUI* pCmdUI)
{
pCmdUI->Enable( m_ctrlSymbols.GetSelectedCount() >= 1 );
}
LRESULT CResOrgSymbolsListView::OnHelpHitTest(WPARAM, LPARAM)
{
return IDR_DISPLAY_SYMBOLS + HID_BASE_RESOURCE;
}
void CResOrgSymbolsListView::OnCmdRestoreOriginalValue(void)
{
POSITION pos = m_ctrlSymbols.GetFirstSelectedItemPosition();
while (pos != NULL)
{
int nItem = m_ctrlSymbols.GetNextSelectedItem(pos);
CResourceSymbol* pSymbol = (CResourceSymbol*)m_ctrlSymbols.GetItemData(nItem);
if ( (NULL != pSymbol) && !pSymbol->IsReadOnly() )
{
UINT uOriginalValue = pSymbol->GetOriginalValue();
if (uOriginalValue > 0)
{
GetDocument()->Set( pSymbol,
pSymbol->GetName(),
uOriginalValue,
FALSE);
}
}
}
GetDocument()->CheckNextSymbolValues( Options.WarnIfNextSymbolValuesInUse() );
}
void CResOrgSymbolsListView::OnUpdateRestoreOriginalValue(CCmdUI* pCmdUI)
{
BOOL bEnable = FALSE;
POSITION pos = m_ctrlSymbols.GetFirstSelectedItemPosition();
while (pos != NULL)
{
int nItem = m_ctrlSymbols.GetNextSelectedItem(pos);
CResourceSymbol* pSymbol = (CResourceSymbol*)m_ctrlSymbols.GetItemData(nItem);
if (NULL != pSymbol)
{
if (!pSymbol->IsReadOnly() && (pSymbol->GetOriginalValue() > 0) )
{
bEnable = TRUE;
break;
}
}
}
pCmdUI->Enable(bEnable);
}
void CResOrgSymbolsListView::OnCmdFixSymbolValue(void)
{
BOOL bFailed = FALSE;
// Create a list of the selected symbols first
// This ensures the iteration isn't affected by our changes
CResourceSymbolList listSymbols;
POSITION pos = m_ctrlSymbols.GetFirstSelectedItemPosition();
while (pos != NULL)
{
int nItem = m_ctrlSymbols.GetNextSelectedItem(pos);
CResourceSymbol* pSymbol = (CResourceSymbol*)m_ctrlSymbols.GetItemData(nItem);
listSymbols.AddTail(pSymbol);
}
// Now fix them!
pos = listSymbols.GetHeadPosition();
while (NULL != pos)
{
CResourceSymbol* pSymbol = listSymbols.GetNext(pos);
if ( (NULL != pSymbol) && !pSymbol->IsReadOnly() )
{
CResourceSymbolManager* pManager = GetDocument()->GetSymbolBuffer();
if (pSymbol->HasConflicts() || pManager->IsOutOfRange(pSymbol) )
{
UINT uNewValue = pManager->GetBaseSymbolValue( pSymbol->GetType() );
while (!IsValueUnique(pSymbol, uNewValue) )
{
uNewValue++;
if (uNewValue >= IDC_STATIC)
{
bFailed = TRUE;
ASSERT(FALSE);
break; // Can't fix this one
}
}
if (!bFailed)
{
GetDocument()->Set( pSymbol,
pSymbol->GetName(),
uNewValue,
FALSE);
}
}
}
}
// Remove any symbols that should no longer be visible
if (m_ctrlSymbols.ShowProblemSymbolsOnly() )
{
if (GetDocument()->GetSymbolBuffer()->GetProblemSymbolCount() > 0)
{
CResourceSymbolList listSymbolsToRemove;
for (int nItem = 0; nItem < m_ctrlSymbols.GetItemCount(); nItem++)
{
CResourceSymbol* pSymbol = m_ctrlSymbols.GetSymbol(nItem);
if (!m_ctrlSymbols.IsVisible(pSymbol) )
{
listSymbolsToRemove.AddTail(pSymbol);
}
}
POSITION pos = listSymbolsToRemove.GetHeadPosition();
while (NULL != pos)
{
CResourceSymbol* pSymbol = listSymbolsToRemove.GetNext(pos);
m_ctrlSymbols.RemoveSymbol(pSymbol);
}
}
else
{
// There aren't any symbols left with conflicts - show the lot!
m_ctrlSymbols.ShowProblemSymbolsOnly(false);
}
}
GetDocument()->CheckNextSymbolValues( Options.WarnIfNextSymbolValuesInUse() );
}
void CResOrgSymbolsListView::OnUpdateFixSymbolValue(CCmdUI* pCmdUI)
{
BOOL bEnable = FALSE;
POSITION pos = m_ctrlSymbols.GetFirstSelectedItemPosition();
while (pos != NULL)
{
int nItem = m_ctrlSymbols.GetNextSelectedItem(pos);
CResourceSymbol* pSymbol = (CResourceSymbol*)m_ctrlSymbols.GetItemData(nItem);
if ( (NULL != pSymbol) && !pSymbol->IsReadOnly() )
{
if (pSymbol->HasConflicts() ||
GetDocument()->GetSymbolBuffer()->IsOutOfRange(pSymbol) )
{
bEnable = TRUE;
break;
}
}
}
pCmdUI->Enable(bEnable);
}
void CResOrgSymbolsListView::OnCmdShowProblemSymbolsOnly(void)
{
CWaitCursor wait;
m_ctrlSymbols.ShowProblemSymbolsOnly( !m_ctrlSymbols.ShowProblemSymbolsOnly() );
}
void CResOrgSymbolsListView::OnUpdateShowProblemSymbolsOnly(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck( m_ctrlSymbols.ShowProblemSymbolsOnly() );
}
void CResOrgSymbolsListView::OnCmdPreviousProblemSymbol(void)
{
bool bFound = false;
int nStartItem = m_ctrlSymbols.GetItemCount();
POSITION pos = m_ctrlSymbols.GetFirstSelectedItemPosition();
while (NULL != pos)
{
nStartItem = m_ctrlSymbols.GetNextSelectedItem(pos);
m_ctrlSymbols.SetItemState(nStartItem, !LVIS_SELECTED, LVIS_SELECTED);
if (0 == nStartItem)
{
nStartItem = m_ctrlSymbols.GetItemCount();
}
}
for (int nItem = nStartItem - 1; nItem >= 0; nItem--)
{
CResourceSymbol* pSymbol = m_ctrlSymbols.GetSymbol(nItem);
ASSERT(NULL != pSymbol);
if (NULL != pSymbol)
{
if (pSymbol->HasConflicts() || GetDocument()->GetSymbolBuffer()->IsOutOfRange(pSymbol) )
{
m_ctrlSymbols.EnsureVisible(nItem, FALSE);
m_ctrlSymbols.SetItemState(nItem, LVIS_SELECTED, LVIS_SELECTED);
bFound = true;
break;
}
}
if (nItem == 0 )
{
nItem = m_ctrlSymbols.GetItemCount();
}
}
}
void CResOrgSymbolsListView::OnUpdatePreviousProblemSymbol(CCmdUI* pCmdUI)
{
pCmdUI->Enable(GetDocument()->GetSymbolBuffer()->GetProblemSymbolCount() > 0);
}
void CResOrgSymbolsListView::OnCmdNextProblemSymbol(void)
{
bool bFound = false;
int nStartItem = 0;
POSITION pos = m_ctrlSymbols.GetFirstSelectedItemPosition();
if (NULL != pos)
{
nStartItem = m_ctrlSymbols.GetNextSelectedItem(pos);
m_ctrlSymbols.SetItemState(nStartItem, !LVIS_SELECTED, LVIS_SELECTED);
}
for (int nItem = nStartItem + 1; nItem < m_ctrlSymbols.GetItemCount(); nItem++)
{
CResourceSymbol* pSymbol = m_ctrlSymbols.GetSymbol(nItem);
ASSERT(NULL != pSymbol);
if (NULL != pSymbol)
{
if (pSymbol->HasConflicts() || GetDocument()->GetSymbolBuffer()->IsOutOfRange(pSymbol) )
{
m_ctrlSymbols.EnsureVisible(nItem, FALSE);
m_ctrlSymbols.SetItemState(nItem, LVIS_SELECTED, LVIS_SELECTED);
bFound = true;
break;
}
}
if (nItem + 1 == m_ctrlSymbols.GetItemCount() )
{
nItem = 0;
}
}
}
void CResOrgSymbolsListView::OnUpdateNextProblemSymbol(CCmdUI* pCmdUI)
{
pCmdUI->Enable(GetDocument()->GetSymbolBuffer()->GetProblemSymbolCount() > 0);
}