178 lines
4.1 KiB
C++
178 lines
4.1 KiB
C++
// XTSortClass.cpp : implementation of the CXTSortClass class.
|
|
//
|
|
// This file is a part of the XTREME CONTROLS MFC class library.
|
|
// (c)1998-2008 Codejock Software, All Rights Reserved.
|
|
//
|
|
// THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
|
|
// RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
|
|
// CONSENT OF CODEJOCK SOFTWARE.
|
|
//
|
|
// THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
|
|
// IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
|
|
// YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
|
|
// SINGLE COMPUTER.
|
|
//
|
|
// CONTACT INFORMATION:
|
|
// support@codejock.com
|
|
// http://www.codejock.com
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "stdafx.h"
|
|
#include "XTDefines.h"
|
|
#include "XTGlobal.h"
|
|
#include "XTSortClass.h"
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#define new DEBUG_NEW
|
|
#endif
|
|
|
|
struct CXTSortClass::SORT_ITEM
|
|
{
|
|
SORT_ITEM(const DWORD_PTR dwData, const CString &strItemText)
|
|
{
|
|
m_dwData = dwData;
|
|
m_strItemText = strItemText;
|
|
}
|
|
DWORD_PTR m_dwData;
|
|
CString m_strItemText;
|
|
};
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// CXTSortClass
|
|
//
|
|
CXTSortClass::CXTSortClass(CListCtrl* pListCtrl, const int nCol)
|
|
{
|
|
ASSERT(pListCtrl);
|
|
if (!pListCtrl)
|
|
return;
|
|
|
|
m_pListCtrl = pListCtrl;
|
|
int nCount = m_pListCtrl->GetItemCount();
|
|
|
|
// Replace Item data with pointer to XT_SORT_ITEM structure
|
|
int i;
|
|
for (i = 0; i < nCount; i++)
|
|
{
|
|
DWORD_PTR dwData = m_pListCtrl->GetItemData(i); // save current data to restore it later
|
|
CString strItemText = m_pListCtrl->GetItemText(i, nCol);
|
|
m_pListCtrl->SetItemData(i, (DWORD_PTR)new SORT_ITEM(dwData, strItemText));
|
|
}
|
|
}
|
|
|
|
CXTSortClass::~CXTSortClass()
|
|
{
|
|
ASSERT(m_pListCtrl);
|
|
if (!m_pListCtrl)
|
|
return;
|
|
|
|
int nCount = m_pListCtrl->GetItemCount();
|
|
|
|
int i;
|
|
for (i = 0; i < nCount; i++)
|
|
{
|
|
SORT_ITEM* pItem = (SORT_ITEM*)m_pListCtrl->GetItemData(i);
|
|
ASSERT(pItem);
|
|
if (pItem)
|
|
{
|
|
m_pListCtrl->SetItemData(i, pItem->m_dwData);
|
|
delete pItem;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CXTSortClass::Sort(bool bAsc, XTSortType eType)
|
|
{
|
|
long lParamSort = eType;
|
|
|
|
// if lParamSort positive - ascending sort order, negative - descending
|
|
if (!bAsc)
|
|
{
|
|
lParamSort *= -1;
|
|
}
|
|
|
|
m_pListCtrl->SortItems(Compare, lParamSort);
|
|
}
|
|
|
|
int CALLBACK CXTSortClass::Compare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
|
|
{
|
|
SORT_ITEM* item1 = (SORT_ITEM*)lParam1;
|
|
SORT_ITEM* item2 = (SORT_ITEM*)lParam2;
|
|
|
|
ASSERT(item1 && item2);
|
|
if (!item1 || !item2)
|
|
return 0;
|
|
|
|
// Restore data type and sort order from lParamSort
|
|
// if lParamSort positive - ascending sort order, negative - descending
|
|
short sOrder = lParamSort < 0 ? (short) -1 : (short) 1;
|
|
|
|
XTSortType eType = (XTSortType) (lParamSort * sOrder); // get rid of sign
|
|
|
|
// declare typed buffers
|
|
COleDateTime t1, t2;
|
|
|
|
switch (eType)
|
|
{
|
|
case xtSortInt:
|
|
{
|
|
CString cs1 = item1->m_strItemText;
|
|
CString cs2 = item2->m_strItemText;
|
|
RemoveNonNumeric(cs1);
|
|
RemoveNonNumeric(cs2);
|
|
return (_ttol(cs1) - _ttol(cs2)) * sOrder;
|
|
}
|
|
|
|
case xtSortDecimal:
|
|
#ifdef _UNICODE
|
|
{
|
|
char szText1[ 256 ];
|
|
char szText2[ 256 ];
|
|
|
|
::WideCharToMultiByte(CP_ACP, 0, item1->m_strItemText, -1, szText1,
|
|
255, NULL, NULL);
|
|
|
|
::WideCharToMultiByte(CP_ACP, 0, item2->m_strItemText, -1, szText2,
|
|
255, NULL, NULL);
|
|
|
|
return (atof(szText1) < atof(szText2) ? -1 : 1) * sOrder;
|
|
}
|
|
#else
|
|
return (atof (item1->m_strItemText) < atof(item2->m_strItemText) ? -1 : 1) * sOrder;
|
|
#endif
|
|
|
|
case xtSortDateTime:
|
|
if (t1.ParseDateTime(item1->m_strItemText) && t2.ParseDateTime(item2->m_strItemText))
|
|
{
|
|
return (t1 < t2 ? -1 : 1) * sOrder;
|
|
}
|
|
return 0;
|
|
|
|
case xtSortString:
|
|
return item1->m_strItemText.CompareNoCase(item2->m_strItemText) * sOrder;
|
|
|
|
default:
|
|
ASSERT("Error: attempt to sort a column without type.");
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
int CXTSortClass::RemoveNonNumeric(CString &csSource)
|
|
{
|
|
TCHAR ch;
|
|
CString temp;
|
|
int nLen = csSource.GetLength();
|
|
int i = 0;
|
|
|
|
while (i < nLen)
|
|
{
|
|
ch = csSource.GetAt(i);
|
|
if (_istdigit(ch))
|
|
temp += ch;
|
|
++i;
|
|
}
|
|
csSource = temp;
|
|
return csSource.GetLength();
|
|
}
|