You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
289 lines
6.0 KiB
289 lines
6.0 KiB
// kmmsglist.cpp |
|
|
|
#include "kmmsglist.h" |
|
#include <assert.h> |
|
#include <stdlib.h> |
|
|
|
static KMMsgList::SortField sSortField; |
|
static bool sSortDescending; |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
KMMsgList::KMMsgList(int initSize): KMMsgListInherited(initSize) |
|
{ |
|
mHigh = size(); |
|
mCount = 0; |
|
clear(FALSE); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
KMMsgList::~KMMsgList() |
|
{ |
|
clear(TRUE); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
void KMMsgList::clear(bool doDelete) |
|
{ |
|
KMMsgBasePtr msg; |
|
long i; |
|
|
|
for (i=mHigh-1; i>=0; i--) |
|
{ |
|
msg = at(i); |
|
KMMsgListInherited::at(i) = NULL; |
|
|
|
if (msg && doDelete) delete msg; |
|
} |
|
mHigh = 0; |
|
mCount = 0; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
bool KMMsgList::resize(int aSize) |
|
{ |
|
int i, oldSize = size(); |
|
KMMsgBasePtr msg; |
|
|
|
assert(aSize>=0); |
|
|
|
// delete messages that will get lost, if any |
|
if (aSize < mHigh) |
|
{ |
|
for (i=aSize; i<mHigh; i++) |
|
{ |
|
msg = at(i); |
|
if (msg) |
|
{ |
|
delete msg; |
|
mCount--; |
|
} |
|
mHigh = aSize; |
|
} |
|
} |
|
|
|
// do the resizing |
|
if (!KMMsgListInherited::resize(aSize)) return FALSE; |
|
|
|
// initialize new elements |
|
for (i=oldSize; i<aSize; i++) |
|
KMMsgListInherited::at(i) = NULL; |
|
|
|
return TRUE; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
bool KMMsgList::reset(int aSize) |
|
{ |
|
if (!resize(aSize)) return FALSE; |
|
clear(); |
|
return TRUE; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
void KMMsgList::set(int idx, KMMsgBasePtr aMsg) |
|
{ |
|
int doubleSize; |
|
|
|
assert(idx>=0); |
|
|
|
if (idx >= size()) |
|
{ |
|
doubleSize = size() << 1; |
|
resize(idx>doubleSize ? idx+16 : doubleSize); |
|
} |
|
|
|
if (!at(idx) && aMsg) mCount++; |
|
else if (at(idx) && !aMsg) mCount--; |
|
|
|
KMMsgListInherited::at(idx) = aMsg; |
|
if (!aMsg || idx >= mHigh) rethinkHigh(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
void KMMsgList::insert(int idx, KMMsgBasePtr aMsg) |
|
{ |
|
int i, doubleSize; |
|
|
|
assert(idx>=0); |
|
|
|
if (idx >= size()) |
|
{ |
|
doubleSize = size() << 1; |
|
resize(idx>doubleSize ? idx+16 : doubleSize); |
|
} |
|
|
|
if (aMsg) mCount++; |
|
|
|
for (i=mHigh; i>idx; i--) |
|
KMMsgListInherited::at(i) = KMMsgListInherited::at(i-1); |
|
|
|
KMMsgListInherited::at(idx) = aMsg; |
|
mHigh++; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
int KMMsgList::append(KMMsgBasePtr aMsg) |
|
{ |
|
int idx = mHigh; |
|
insert(idx, aMsg); // mHigh gets modified in here |
|
return idx; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
void KMMsgList::remove(int idx) |
|
{ |
|
int i; |
|
|
|
assert(idx>=0 && idx<size()); |
|
|
|
if (KMMsgListInherited::at(idx)) mCount--; |
|
|
|
mHigh--; |
|
for (i=idx; i<mHigh; i++) |
|
KMMsgListInherited::at(i) = KMMsgListInherited::at(i+1); |
|
KMMsgListInherited::at(mHigh) = NULL; |
|
|
|
rethinkHigh(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
KMMsgBasePtr KMMsgList::take(int idx) |
|
{ |
|
KMMsgBasePtr msg=at(idx); |
|
remove(idx); |
|
return msg; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
void KMMsgList::rethinkHigh(void) |
|
{ |
|
int sz = (int)size(); |
|
|
|
if (mHigh < sz && at(mHigh)) |
|
{ |
|
// forward search |
|
while (mHigh < sz && at(mHigh)) |
|
mHigh++; |
|
} |
|
else |
|
{ |
|
// backward search |
|
while (mHigh>0 && !at(mHigh-1)) |
|
mHigh--; |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
void KMMsgList::qsort(int left, int right, SortField aField, bool aDescending) |
|
{ |
|
// debug("KMmsgList::qsort()"); |
|
|
|
if(right <= left) |
|
return; |
|
|
|
KMMsgBasePtr mb; |
|
int i = left; |
|
int j = right; |
|
|
|
// $markus: Yes, I am paranoid ;-) |
|
if((i + j / 2) < 0 || (i + j / 2) > (int)KMMsgListInherited::size()) |
|
return; |
|
KMMsgBasePtr pivot = KMMsgListInherited::at((int)((i + j) / 2)); |
|
|
|
do { |
|
while(msgSortCompFunc(KMMsgListInherited::at(i), pivot, aField, aDescending) < 0) |
|
i++; |
|
while(msgSortCompFunc(pivot, KMMsgListInherited::at(j), aField, aDescending) < 0) |
|
j--; |
|
if(i <= j) { |
|
if(i != j) { |
|
mb = KMMsgListInherited::at(i); |
|
KMMsgListInherited::at(i) = KMMsgListInherited::at(j); |
|
KMMsgListInherited::at(j) = mb; |
|
} |
|
i++; |
|
j--; |
|
} |
|
} while(i <= j); |
|
|
|
if(left < j) qsort(left, j, aField, aDescending); |
|
if(i < right) qsort(i, right, aField, aDescending); |
|
|
|
// debug("KMsgList::qsort() leaving"); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
int qsortCompFunc(const void* a, const void* b) |
|
{ |
|
return KMMsgList::msgSortCompFunc(*(KMMsgBasePtr*)a, *(KMMsgBasePtr*)b, |
|
sSortField, sSortDescending); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
void KMMsgList::sort(SortField aField, bool aDescending) |
|
{ |
|
#define SLOW_SORT |
|
#ifndef SLOW_SORT |
|
qsort(0, mHigh-1, aField, aDescending); |
|
#else /*SLOW_SORT*/ |
|
|
|
KMMsgBasePtr sortList[mHigh]; |
|
int i; |
|
|
|
if (mHigh < 2) return; |
|
|
|
sSortField = aField; |
|
sSortDescending = aDescending; |
|
|
|
for (i=0; i<mHigh; i++) |
|
sortList[i] = KMMsgListInherited::at(i); |
|
|
|
::qsort(sortList, mHigh, sizeof(KMMsgBasePtr), &qsortCompFunc); |
|
|
|
for (i=0; i<mHigh; i++) |
|
KMMsgListInherited::at(i) = sortList[i]; |
|
|
|
#endif /*SLOW_SORT*/ |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
int KMMsgList::msgSortCompFunc(KMMsgBasePtr mbA, KMMsgBasePtr mbB, |
|
KMMsgList::SortField sortCriteria, bool desc) |
|
{ |
|
int res = 0; |
|
|
|
if (sortCriteria==sfNone) |
|
res = mbA->compareByIndex(mbB); |
|
else |
|
{ |
|
if (sortCriteria==sfStatus) |
|
res = mbA->compareByStatus(mbB); |
|
|
|
else if (sortCriteria==sfFrom) |
|
res = mbA->compareByFrom(mbB); |
|
|
|
else if (res==0 || sortCriteria==sfSubject) |
|
res = mbA->compareBySubject(mbB); |
|
|
|
if (res==0 || sortCriteria==sfDate) |
|
res = mbA->compareByDate(mbB); |
|
} |
|
|
|
if (desc) return -res; |
|
return res; |
|
}
|
|
|