607 lines
17 KiB
C++
607 lines
17 KiB
C++
// TitleC.cpp -- Implementation for class CTitleCollection
|
|
|
|
#include "StdAfx.h"
|
|
|
|
#include "TextSet.h"
|
|
#include "Tokens.h"
|
|
#include "TitleC.h"
|
|
#include "Memex.h"
|
|
|
|
CTitleCollection *CTitleCollection::NewTitleCollection(CTextSet **papts, UINT ctsSlots, CPersist *pPersistRelations)
|
|
{
|
|
CTitleCollection *ptc= NULL;
|
|
|
|
__try
|
|
{
|
|
ptc= New CTitleCollection();
|
|
|
|
ptc->AttachParameters(papts, ctsSlots, pPersistRelations);
|
|
}
|
|
__finally
|
|
{
|
|
if (_abnormal_termination() && ptc)
|
|
{
|
|
delete ptc; ptc= NULL;
|
|
}
|
|
}
|
|
|
|
return ptc;
|
|
}
|
|
|
|
CTitleCollection::CTitleCollection() :
|
|
#ifdef _DEBUG
|
|
CTokenList(FALSE, "TitleCollection")
|
|
#else // _DEBUG
|
|
CTokenList(FALSE)
|
|
#endif // _DEBUG
|
|
{
|
|
m_ctsSlots = 0;
|
|
m_cTitles = 0;
|
|
m_patsi = NULL;
|
|
m_paiTitleStart = NULL;
|
|
m_pati = NULL;
|
|
m_paptiSorted = NULL;
|
|
m_paiCategoryMaps = NULL;
|
|
m_pisActiveTitles = NULL;
|
|
m_fFromFile = FALSE;
|
|
}
|
|
|
|
CTitleCollection::~CTitleCollection()
|
|
{
|
|
if (m_pati ) VFree(m_pati );
|
|
if (m_paptiSorted ) VFree(m_paptiSorted );
|
|
if (m_paiTitleStart ) VFree(m_paiTitleStart );
|
|
if (m_paiCategoryMaps) VFree(m_paiCategoryMaps);
|
|
|
|
if (m_pisActiveTitles) DetachRef(m_pisActiveTitles);
|
|
|
|
if (m_patsi)
|
|
{
|
|
UINT c= m_ctsSlots;
|
|
|
|
for (; c--; ) if (m_patsi[c].pts) DetachRef(m_patsi[c].pts);
|
|
|
|
VFree(m_patsi);
|
|
}
|
|
}
|
|
|
|
void CTitleCollection::AttachParameters(CTextSet **papts, UINT ctsSlots, CPersist *pPersistRelations)
|
|
{
|
|
m_fFromFile= BOOL(pPersistRelations);
|
|
|
|
m_patsi= (PTextSetInfo) VAlloc(TRUE, ctsSlots * sizeof(TextSetInfo));
|
|
|
|
m_ctsSlots = ctsSlots;
|
|
|
|
UINT c;
|
|
|
|
for (c= ctsSlots; c--; )
|
|
{
|
|
CTextSet *pts= papts[c];
|
|
|
|
if (!pts) continue;
|
|
|
|
InstallTextSet(c, pts);
|
|
}
|
|
|
|
if (m_fFromFile) ReconstructRelations(pPersistRelations);
|
|
|
|
InvalidateRepresentatives(pPersistRelations);
|
|
}
|
|
|
|
typedef struct _TitleRelationHeader
|
|
{
|
|
UINT ctsSlots;
|
|
UINT cTitles;
|
|
|
|
} TitleRelationHeader, *PTitleRelationHeader;
|
|
|
|
void CTitleCollection::ReconstructRelations(CPersist *pPersistRelations)
|
|
{
|
|
CTokenList::ConnectImage2(pPersistRelations, TRUE);
|
|
|
|
// We set the PREVIOUSLY_PRESENT flag for every text set we encounter.
|
|
// That's necessary to skip the call to ReconstructCollection in InvalidateRepresentatives.
|
|
// For similar reasons we also set the PREVIOUSLY_ACTIVE flag.
|
|
|
|
UINT c= m_ctsSlots;
|
|
|
|
for (; c--; )
|
|
{
|
|
if (IsPresent(c)) m_patsi[c].fFlags |= PREVIOUSLY_PRESENT;
|
|
if (IsActive (c)) m_patsi[c].fFlags |= PREVIOUSLY_ACTIVE;
|
|
}
|
|
|
|
ASSERT(!m_pisActiveTitles);
|
|
|
|
AttachRef(m_pisActiveTitles, CIndicatorSet::NewIndicatorSet(m_cd, TRUE));
|
|
|
|
BuildTitleStarts();
|
|
|
|
PTitleRelationHeader ptrh= PTitleRelationHeader(pPersistRelations->ReserveTableSpace(sizeof(TitleRelationHeader)));
|
|
|
|
ASSERT(m_ctsSlots == ptrh->ctsSlots && m_cTitles == ptrh->cTitles);
|
|
|
|
m_paiCategoryMaps = PUINT(VAlloc(FALSE, m_cTitles * sizeof(UINT)));
|
|
|
|
PDESCRIPTOR *ppd;
|
|
|
|
for (c= m_cd, ppd= m_ppdSorted + m_cd; c--; )
|
|
m_paiCategoryMaps[*--ppd - m_pd] = c;
|
|
|
|
m_pati= (PTitleInfo) VAlloc(TRUE, m_cTitles * sizeof(TitleInfo));
|
|
|
|
PTitleInfo pti = m_pati + m_cTitles;
|
|
PTextSetInfo ptsi;
|
|
|
|
for (ptsi= m_patsi + m_ctsSlots, c= m_ctsSlots; c--; )
|
|
{
|
|
if (!(PRESENT & (--ptsi)->fFlags)) continue;
|
|
|
|
CTextSet *pts = ptsi->pts;
|
|
CTokenList *ptl = pts->TitleList();
|
|
UINT cd = pts->TopicCount();
|
|
|
|
for (; cd--; )
|
|
{
|
|
(--pti)->iaTSSlot = c;
|
|
pti ->iPartition = cd;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CTitleCollection::BuildTitleStarts()
|
|
{
|
|
m_paiTitleStart= PUINT(VAlloc(FALSE, (m_ctsSlots + 1) * sizeof(UINT)));
|
|
|
|
PUINT piStart = m_paiTitleStart;
|
|
PTextSetInfo ptsi = m_patsi;
|
|
UINT c = m_ctsSlots;
|
|
|
|
for (m_cTitles= 0, *piStart++= 0; c--; ptsi++)
|
|
{
|
|
if (ptsi->fFlags & PRESENT)
|
|
m_cTitles += ptsi->cd;
|
|
|
|
*piStart++= m_cTitles;
|
|
}
|
|
}
|
|
|
|
void CTitleCollection::ConstructCollection()
|
|
{
|
|
BuildTitleStarts();
|
|
|
|
m_pati= (PTitleInfo) VAlloc(TRUE, m_cTitles * sizeof(TitleInfo));
|
|
|
|
m_paptiSorted= (PTitleInfo *) VAlloc(FALSE, m_cTitles * sizeof(PTitleInfo));
|
|
|
|
PTitleInfo pti = m_pati + m_cTitles;
|
|
PTitleInfo *ppti = m_paptiSorted + m_cTitles;
|
|
|
|
m_lcidSorting = LCID(-1); // an invalid LCID value
|
|
|
|
BOOL fLCID_Initialed = FALSE;
|
|
|
|
PTextSetInfo ptsi;
|
|
UINT c;
|
|
|
|
for (ptsi= m_patsi + m_ctsSlots, c= m_ctsSlots; c--; )
|
|
{
|
|
if (!(PRESENT & (--ptsi)->fFlags)) continue;
|
|
|
|
CTextSet *pts= ptsi->pts;
|
|
|
|
if (fLCID_Initialed)
|
|
{
|
|
if (m_lcidSorting != pts->SortingLCID())
|
|
m_lcidSorting = LCID(-1);
|
|
}
|
|
else
|
|
{
|
|
m_lcidSorting = pts->SortingLCID();
|
|
fLCID_Initialed = TRUE;
|
|
}
|
|
|
|
pts->SyncIndices();
|
|
|
|
CTokenList *ptl= pts->TitleList();
|
|
|
|
INT cbMaxTitle= ptl->MaxWidthToken();
|
|
|
|
if (cbMaxTitle > m_cbMaxLength) m_cbMaxLength= cbMaxTitle;
|
|
|
|
UINT cd = ptl->m_cd;
|
|
PDESCRIPTOR *ppd = ptl->m_ppdSorted + cd;
|
|
PTitleInfo ptiBase = pti -= cd;
|
|
PDESCRIPTOR pdBase = ptl->m_pd;
|
|
|
|
for (; cd--; )
|
|
{
|
|
PDESCRIPTOR pd = *--ppd;
|
|
UINT iPartition = pd - pdBase;
|
|
PTitleInfo ptiTarget = ptiBase + iPartition;
|
|
|
|
ptiTarget->pd= pd;
|
|
|
|
ptiTarget->iaTSSlot = c;
|
|
ptiTarget->iPartition = iPartition;
|
|
|
|
*--ppti= ptiTarget;
|
|
}
|
|
}
|
|
|
|
CombineTitleLists(m_paptiSorted, m_paiTitleStart, m_ctsSlots, &ppti, &c);
|
|
|
|
ASSERT(c == m_cTitles);
|
|
|
|
if (m_ctsSlots > 1)
|
|
{
|
|
VFree(m_paptiSorted);
|
|
|
|
m_paptiSorted= ppti;
|
|
}
|
|
|
|
if (m_paiCategoryMaps)
|
|
{
|
|
VFree(m_paiCategoryMaps);
|
|
m_paiCategoryMaps= NULL;
|
|
}
|
|
}
|
|
|
|
BOOL CTitleCollection::InvalidateRepresentatives(CPersist *pPersistRelations)
|
|
{
|
|
UINT fChanges = 0;
|
|
UINT c;
|
|
|
|
for (c= m_ctsSlots; c--; )
|
|
{
|
|
UINT fFlags= m_patsi[c].fFlags;
|
|
|
|
ASSERT((fFlags & (PRESENT | ACTIVE)) != ACTIVE);
|
|
|
|
fChanges |= (fFlags & CURRENT_STATE) ^ ((fFlags & PREVIOUS_STATE) >> TIME_SHIFT);
|
|
}
|
|
|
|
if (!fChanges) return TRUE;
|
|
|
|
if (fChanges & PRESENT) ReconstructCollection();
|
|
|
|
if (fChanges & ACTIVE || !m_paiCategoryMaps) ReconstructRepresentatives();
|
|
|
|
PTextSetInfo ptsi= m_patsi;
|
|
|
|
for (c= m_ctsSlots; c--; ++ptsi)
|
|
{
|
|
UINT fOptions= ptsi->fFlags & (PRESENT | ACTIVE);
|
|
|
|
ptsi->fFlags &= ~(PRESENT | ACTIVE | PREVIOUSLY_PRESENT | PREVIOUSLY_ACTIVE);
|
|
|
|
ptsi->fFlags |= fOptions | (fOptions << TIME_SHIFT);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CTitleCollection::ReconstructCollection()
|
|
{
|
|
if (!m_pati) { ConstructCollection(); return; }
|
|
|
|
ASSERT(FALSE); // Collection Change to be completed...
|
|
}
|
|
|
|
void CTitleCollection::ConstructRepresentatives()
|
|
{
|
|
ASSERT(!m_paiCategoryMaps);
|
|
|
|
UINT c = m_ctsSlots;
|
|
PTextSetInfo ptsi = m_patsi;
|
|
|
|
PTitleInfo *ppti;
|
|
|
|
UINT cwcDisplayImages = 0;
|
|
UINT cwcSortKeyImages = 0;
|
|
|
|
for (c= m_cTitles, ppti= m_paptiSorted; c--; )
|
|
{
|
|
PDESCRIPTOR pd = (*ppti++)->pd;
|
|
cwcDisplayImages += CwDisplay(pd);
|
|
cwcSortKeyImages += CbImage (pd);
|
|
}
|
|
|
|
PWCHAR pwcDisplayImages = NULL;
|
|
PWCHAR pwcSortKeyImages = NULL;
|
|
PDESCRIPTOR pdTitles = NULL;
|
|
PDESCRIPTOR *ppdSortedTitles = NULL;
|
|
|
|
__try
|
|
{
|
|
ValidateHeap();
|
|
|
|
pdTitles = PDESCRIPTOR (VAlloc(FALSE, (m_cTitles+1) * sizeof(DESCRIPTOR )));
|
|
ppdSortedTitles = (PDESCRIPTOR *) VAlloc(FALSE, m_cTitles * sizeof(PDESCRIPTOR));
|
|
|
|
pwcDisplayImages = PWCHAR(VAlloc(FALSE, cwcDisplayImages * sizeof(WCHAR)));
|
|
pwcSortKeyImages = PWCHAR(VAlloc(FALSE, cwcSortKeyImages * sizeof(WCHAR)));
|
|
|
|
ValidateHeap();
|
|
|
|
PWCHAR pwcDisplay = pwcDisplayImages;
|
|
PWCHAR pwcSortKey = pwcSortKeyImages;
|
|
|
|
PDESCRIPTOR pd;
|
|
PDESCRIPTOR *ppd;
|
|
PTitleInfo pti;
|
|
|
|
for (c= m_cTitles, pti= m_pati, pd= pdTitles; c--; pti++, pd++)
|
|
{
|
|
PDESCRIPTOR pdTS = pti->pd;
|
|
|
|
pti->pd = pd;
|
|
|
|
*pd = *pdTS;
|
|
|
|
UINT cwcDisplay = CwDisplay(pdTS);
|
|
UINT cwcSortKey = CbImage (pdTS);
|
|
|
|
pd->iTextSet = pti->iaTSSlot;
|
|
pd->pwDisplay = pwcDisplay;
|
|
pd->pbImage = pwcSortKey;
|
|
|
|
CopyMemory(pwcDisplay, pdTS->pwDisplay, cwcDisplay * sizeof(WCHAR));
|
|
CopyMemory(pwcSortKey, pdTS->pbImage , cwcSortKey * sizeof(WCHAR));
|
|
|
|
pwcDisplay += cwcDisplay;
|
|
pwcSortKey += cwcSortKey;
|
|
}
|
|
|
|
ValidateHeap();
|
|
|
|
pd->pwDisplay = pwcDisplay; // To set a limit on the length of the last display image.
|
|
pd->pbImage = pwcSortKey; // To set a limit on the length of the last sort key.
|
|
|
|
ValidateHeap();
|
|
|
|
m_paiCategoryMaps = (PUINT) VAlloc(FALSE, m_cTitles * sizeof(UINT));
|
|
|
|
#ifdef _DEBUG
|
|
FillMemory(m_paiCategoryMaps, m_cTitles * sizeof(UINT), UCHAR(-1));
|
|
#endif // _DEBUG
|
|
|
|
for (c= m_cTitles, ppd= ppdSortedTitles + m_cTitles, ppti= m_paptiSorted + m_cTitles; c--; )
|
|
{
|
|
PDESCRIPTOR pd = (*--ppti)->pd;
|
|
|
|
*--ppd = pd;
|
|
|
|
m_paiCategoryMaps[pd - pdTitles] = c;
|
|
}
|
|
|
|
ValidateHeap();
|
|
}
|
|
__finally
|
|
{
|
|
if (_abnormal_termination())
|
|
{
|
|
if(pwcDisplayImages) { VFree(pwcDisplayImages); pwcDisplayImages = NULL; }
|
|
if(pwcSortKeyImages) { VFree(pwcSortKeyImages); pwcSortKeyImages = NULL; }
|
|
if(pdTitles ) { VFree(pdTitles ); pdTitles = NULL; }
|
|
if(ppdSortedTitles ) { VFree(ppdSortedTitles ); ppdSortedTitles = NULL; }
|
|
}
|
|
}
|
|
|
|
InitialTokenList(pwcDisplayImages, cwcDisplayImages, pdTitles,
|
|
m_cTitles, m_lcidSorting, pwcSortKeyImages, cwcSortKeyImages,
|
|
ppdSortedTitles, NULL
|
|
);
|
|
|
|
NotifyViewers (ShapeChange);
|
|
NotifyInterface(ShapeChange);
|
|
}
|
|
|
|
void CTitleCollection::ReconstructRepresentatives()
|
|
{
|
|
if (!m_paiCategoryMaps) ConstructRepresentatives();
|
|
|
|
ChangeRef(m_pisActiveTitles, CIndicatorSet::NewIndicatorSet(m_cd));
|
|
|
|
PDESCRIPTOR *ppd;
|
|
UINT c;
|
|
|
|
for (c= m_cd, ppd= m_ppdSorted + m_cd; c--; )
|
|
{
|
|
if ((m_patsi[(*--ppd)->iTextSet].fFlags & ACTIVE))
|
|
m_pisActiveTitles->RawSetBit(c);
|
|
}
|
|
|
|
m_pisActiveTitles->InvalidateCache();
|
|
}
|
|
|
|
#if 0
|
|
|
|
WORD auCredits[] =
|
|
{
|
|
0x2d30, 0x4420, 0x7665, 0x6c65, 0x706f, 0x656d, 0x746e, 0x5420, 0x6165,
|
|
0x206d, 0x002d, 0x5231, 0x6e6f, 0x4d20, 0x7275, 0x6172, 0x0079, 0x5231,
|
|
0x646f, 0x656e, 0x2079, 0x6f4b, 0x6e72, 0x3100, 0x6952, 0x6863, 0x7261,
|
|
0x2064, 0x614b, 0x7a74, 0x3100, 0x6f4a, 0x6e68, 0x4820, 0x6c61, 0x006c,
|
|
0x4b31, 0x6972, 0x6873, 0x616e, 0x4e20, 0x7261, 0x6465, 0x7964, 0x3100,
|
|
0x6152, 0x706c, 0x2068, 0x6157, 0x646c, 0x6e65, 0x3100, 0x794c, 0x6e6e,
|
|
0x4220, 0x6f72, 0x6e77, 0x6c65, 0x006c, 0x4d31, 0x6369, 0x6168, 0x6c65,
|
|
0x4620, 0x202e, 0x2e43, 0x4320, 0x6972, 0x6b63, 0x3100, 0x0020, 0x0032,
|
|
0x2d30, 0x5520, 0x6573, 0x2072, 0x6e49, 0x6574, 0x6672, 0x6361, 0x2065,
|
|
0x6544, 0x6973, 0x6e67, 0x2d20, 0x3100, 0x6f52, 0x206e, 0x754d, 0x7272,
|
|
0x7961, 0x3100, 0x6f52, 0x6e64, 0x7965, 0x4b20, 0x726f, 0x006e, 0x4731,
|
|
0x7961, 0x656c, 0x5020, 0x6369, 0x656b, 0x006e, 0x4931, 0x6572, 0x656e,
|
|
0x5020, 0x7361, 0x6574, 0x6e72, 0x6361, 0x006b, 0x5431, 0x6d61, 0x2069,
|
|
0x6542, 0x7475, 0x6c65, 0x3100, 0x7553, 0x617a, 0x206e, 0x614d, 0x6172,
|
|
0x6873, 0x0069, 0x4b31, 0x6e65, 0x2074, 0x7553, 0x6c6c, 0x7669, 0x6e61,
|
|
0x3100, 0x6550, 0x7274, 0x2061, 0x6f48, 0x6666, 0x616d, 0x006e, 0x4a31,
|
|
0x6e61, 0x2065, 0x6144, 0x6c69, 0x7965, 0x3100, 0x0020, 0x0032, 0x2d30,
|
|
0x4720, 0x6f6c, 0x6162, 0x696c, 0x617a, 0x6974, 0x6e6f, 0x2d20, 0x3100,
|
|
0x6f52, 0x206e, 0x754d, 0x7272, 0x7961, 0x3100, 0x6952, 0x6863, 0x7261,
|
|
0x2064, 0x614b, 0x7a74, 0x3100, 0x7341, 0x756d, 0x2073, 0x7246, 0x7965,
|
|
0x6174, 0x0067, 0x2031, 0x6120, 0x616b, 0x4420, 0x2e72, 0x5520, 0x696e,
|
|
0x6f63, 0x6564, 0x3100, 0x6f4c, 0x6972, 0x4820, 0x656f, 0x7472, 0x0068,
|
|
0x4331, 0x7461, 0x6568, 0x6972, 0x656e, 0x5720, 0x7369, 0x6973, 0x6b6e,
|
|
0x3100, 0x2e4b, 0x4420, 0x202e, 0x6843, 0x6e61, 0x0067, 0x2031, 0x3200,
|
|
0x3000, 0x202d, 0x6554, 0x7473, 0x6e69, 0x2067, 0x002d, 0x5431, 0x6d69,
|
|
0x4c20, 0x7765, 0x7369, 0x3100, 0x6152, 0x646e, 0x6c61, 0x206c, 0x7453,
|
|
0x6d69, 0x7370, 0x6e6f, 0x3100, 0x0020, 0x0032, 0x2d30, 0x4220, 0x7275,
|
|
0x6165, 0x6375, 0x6172, 0x7963, 0x4320, 0x6e6f, 0x7274, 0x6c6f, 0x2d20,
|
|
0x3100, 0x614d, 0x6972, 0x6e6f, 0x4820, 0x676f, 0x6e61, 0x3100, 0x694e,
|
|
0x6f63, 0x656c, 0x4d20, 0x7469, 0x6b73, 0x676f, 0x3100, 0x6952, 0x6b63,
|
|
0x5320, 0x6765, 0x6c61, 0x3100, 0x6154, 0x6d6d, 0x2079, 0x7453, 0x6565,
|
|
0x656c, 0x3100, 0x0020, 0x0032, 0x2d30, 0x5320, 0x6570, 0x6963, 0x6c61,
|
|
0x5420, 0x6168, 0x6b6e, 0x2073, 0x002d, 0x4331, 0x7268, 0x7369, 0x4d20,
|
|
0x7275, 0x6172, 0x2079, 0x3100, 0x6c45, 0x7a69, 0x6261, 0x7465, 0x2068,
|
|
0x6f4b, 0x6e72, 0x3100, 0x694c, 0x206e, 0x7548, 0x6e61, 0x0067, 0x5331,
|
|
0x7269, 0x7369, 0x6168, 0x4420, 0x6e6f, 0x6974, 0x6572, 0x6464, 0x0079,
|
|
0x2031, 0x3200, 0x0000, 0x6e45, 0x2064, 0x666f, 0x6420, 0x7461, 0x0061,
|
|
0x0000
|
|
};
|
|
|
|
UINT cnCode = 0;
|
|
UINT cbData = sizeof(auCredits);
|
|
UINT offData = 0;
|
|
|
|
#endif // 0
|
|
|
|
void CTitleCollection::RecordRelations(CPersist *pPersistDiskImage)
|
|
{
|
|
PUINT paiPermute= NULL;
|
|
|
|
CTokenList::StoreImage2(pPersistDiskImage, TRUE);
|
|
|
|
PTitleRelationHeader ptrh= (PTitleRelationHeader) (pPersistDiskImage->ReserveTableSpace(sizeof(TitleRelationHeader)));
|
|
|
|
ptrh->ctsSlots = m_ctsSlots;
|
|
ptrh->cTitles = m_cTitles;
|
|
|
|
#if 0
|
|
|
|
offData = pPersistDiskImage->NextOffset();
|
|
cnCode = pPersistDiskImage->Encode(PBYTE(auCredits), cbData);
|
|
|
|
#endif // 0
|
|
}
|
|
|
|
void CTitleCollection::CombineTitleLists(PTitleInfo *paptiSets, PUINT paiTitleStarts, UINT ctiSets,
|
|
PTitleInfo **ppptiSorted, PUINT pcti
|
|
)
|
|
{
|
|
PTitleInfo *paptiSortedLeft = NULL,
|
|
*paptiSortedRight = NULL;
|
|
PTitleInfo *paptiSortedResult= NULL;
|
|
|
|
UINT cFirst = 0;
|
|
UINT cSecond = 0;
|
|
|
|
__try
|
|
{
|
|
if (ctiSets == 1)
|
|
{
|
|
*ppptiSorted = paptiSets + *paiTitleStarts;
|
|
*pcti = *(paiTitleStarts + 1) - *paiTitleStarts;
|
|
|
|
__leave;
|
|
}
|
|
|
|
UINT ctiLeft = 0,
|
|
ctiRight = 0;
|
|
|
|
cFirst = ctiSets / 2;
|
|
cSecond = ctiSets - cFirst;
|
|
|
|
CombineTitleLists(paptiSets, paiTitleStarts, cFirst, &paptiSortedLeft, &ctiLeft);
|
|
|
|
CombineTitleLists(paptiSets, paiTitleStarts + cFirst, cSecond, &paptiSortedRight, &ctiRight);
|
|
|
|
UINT ctiResult= ctiLeft + ctiRight;
|
|
|
|
paptiSortedResult= (PTitleInfo *) VAlloc(FALSE, ctiResult * sizeof(PTitleInfo));
|
|
|
|
MergeImageRefSets((PVOID *) paptiSortedResult, ctiResult,
|
|
(PVOID *) paptiSortedLeft, ctiLeft,
|
|
(PVOID *) paptiSortedRight, ctiRight,
|
|
CompareTitleInfo
|
|
);
|
|
|
|
*ppptiSorted = paptiSortedResult; paptiSortedResult= NULL;
|
|
*pcti = ctiResult;
|
|
}
|
|
__finally
|
|
{
|
|
if (paptiSortedLeft && cFirst > 1) { VFree(paptiSortedLeft ); paptiSortedLeft = NULL; }
|
|
if (paptiSortedRight && cSecond > 1) { VFree(paptiSortedRight); paptiSortedRight = NULL; }
|
|
|
|
if (_abnormal_termination() && paptiSortedResult)
|
|
{
|
|
VFree(paptiSortedResult); paptiSortedResult= NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
int __cdecl CTitleCollection::CompareTitleInfo(const void *pvL, const void *pvR)
|
|
{
|
|
return CompareImagesLR(&(*(const TitleInfo **) pvL)->pd, &(*(const TitleInfo **) pvR)->pd);
|
|
}
|
|
|
|
UINT CTitleCollection::MapToTitleLists(CIndicatorSet * pisTitles, PTitleInfo *paptiLists, UINT cLists)
|
|
{
|
|
PUINT paiBuffer= NULL;
|
|
|
|
UINT cTitlesFound= 0;
|
|
|
|
__try
|
|
{
|
|
ASSERT(cLists >= m_ctsSlots);
|
|
|
|
UINT cTitles= pisTitles? pisTitles->SelectionCount() : m_cd;
|
|
|
|
UINT cChunk= C_INDICES_CHUNK;
|
|
|
|
if (cChunk > cTitles) cChunk= cTitles;
|
|
|
|
paiBuffer= PUINT(VAlloc(FALSE, cChunk * sizeof(UINT)));
|
|
|
|
ZeroMemory(paptiLists, cLists * sizeof(PTokenInfo));
|
|
|
|
UINT iTitleFirst;
|
|
|
|
for (iTitleFirst= 0; cTitles; iTitleFirst += cChunk, cTitles -= cChunk)
|
|
{
|
|
if (cChunk > cTitles) cChunk= cTitles;
|
|
|
|
UINT c, i;
|
|
PUINT pi;
|
|
|
|
if (pisTitles) pisTitles->MarkedItems(iTitleFirst, PINT(paiBuffer), cChunk);
|
|
else
|
|
for (i= iTitleFirst, c= cChunk, pi= paiBuffer; c--; ) *pi++ = i++;
|
|
|
|
for (c= cChunk, pi= paiBuffer + cChunk; c--; )
|
|
{
|
|
PTitleInfo pti= m_pati + (m_ppdSorted[*--pi] - m_pd);
|
|
|
|
UINT iSlot= pti->iaTSSlot;
|
|
|
|
ASSERT(m_patsi[iSlot].fFlags & PRESENT);
|
|
|
|
if (!(ACTIVE & m_patsi[iSlot].fFlags)) continue;
|
|
|
|
++cTitlesFound;
|
|
|
|
pti->ptiNext= paptiLists[iSlot];
|
|
|
|
paptiLists[iSlot]= pti;
|
|
}
|
|
}
|
|
}
|
|
__finally
|
|
{
|
|
if (paiBuffer) { VFree(paiBuffer); paiBuffer= NULL; }
|
|
}
|
|
|
|
return cTitlesFound;
|
|
}
|