DragonNest/Third/XTToolkitPro/Source/Controls/XTSortClass.cpp
2024-12-19 09:48:26 +08:00

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();
}