home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: WPS_PM
/
WPS_PM.zip
/
xfld085s.zip
/
main
/
cnrsort.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-02-23
|
17KB
|
479 lines
/*
*@@sourcefile cnrsort.c:
* This file contains the new folder sort comparison functions only.
* It is used by the new sort methods in xfldr.c.
*
* For introductory information on how XFolder extended sorting
* is implemented, refer to the XFolder programming guide.
*
* This file was called "xfsort.c" in V0.80.
*
* When sorting a container, one has to provide comparison
* functions which will be called by PM's internal sort
* algorithm (I don't know if it's a quicksort or whatever,
* but this doesn't matter anyway). In other words, one does
* _not_ have to write some sort algorithm oneself,
* but only provides a comparision function.
*
* These functions are used in two contexts:
* 1) with the CM_SORTRECORD msg for sorting just once;
* 2) in the CNRINFO.pSortRecord field, when a container
* should always be sorted.
*
* Sort comparison functions need to be like this:
+ SHORT EXPENTRY fnCompareExt(PMINIRECORDCORE pmrc1,
+ PMINIRECORDCORE pmrc2,
+ PVOID pStorage)
*
* All these sort functions are used by XFolder in the context
* of the extended sort functions. All the "pmrc" parameters
* therefore point to WPS MINIRECORDCOREs (not RECORDCOREs). To
* compare object titles, we can simply use the pszIcon fields.
* If we need the actual SOM objects, we can use the
* OBJECT_FROM_PREC macro.
*
* Note: the information in the PM reference is flat out wrong.
* Container sort functions need to return the following:
+ 0 pmrc1 == pmrc2
+ -1 pmrc1 < pmrc2
+ +1 pmrc1 > pmrc2
*
*@@include #define INCL_WINSTDCNR
*@@include #include <os2.h>
*@@include #include "cnrsort.h"
*/
/*
* Copyright (C) 1997-99 Ulrich Möller.
* This file is part of the XFolder source package.
* XFolder is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, in version 2 as it comes in the
* "COPYING" file of the XFolder main distribution.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <stdio.h>
#define INCL_WIN
#include <os2.h>
#pragma hdrstop
#include <wpfolder.h> // WPFolder
#include <wpshadow.h> // WPShadow
/*
*@@ fnCompareExt:
* container sort comparison function for
* sorting records by file name extension.
*/
SHORT EXPENTRY fnCompareExt(PMINIRECORDCORE pmrc1, PMINIRECORDCORE pmrc2, PVOID pStorage)
{
HAB habDesktop = WinQueryAnchorBlock(HWND_DESKTOP);
SHORT src = 0;
pStorage = pStorage; // to keep the compiler happy
if ((pmrc1) && (pmrc2))
if ((pmrc1->pszIcon) && (pmrc2->pszIcon))
{
// find last dot char in icon titles;
// strrchr finds LAST occurence (as opposed to strchr)
PSZ pDot1 = strrchr(pmrc1->pszIcon, '.');
PSZ pDot2 = strrchr(pmrc2->pszIcon, '.');
if (pDot1 == NULL)
if (pDot2 == NULL)
// both titles have no extension: return names comparison
switch (WinCompareStrings(habDesktop, 0, 0,
pmrc1->pszIcon, pmrc2->pszIcon, 0))
{
case WCS_LT: src = -1; break;
case WCS_GT: src = 1; break;
default: src = 0; break;
}
else
// pmrc1 has no ext, but pmrc2 does:
src = -1;
else
if (pDot2 == NULL)
// pmrc1 has extension, but pmrc2 doesn't:
src = 1;
else {
// both records have extensions:
// compare extensions
switch (WinCompareStrings(habDesktop, 0, 0,
pDot1, pDot2, 0))
{
case WCS_LT: src = -1; break;
case WCS_GT: src = 1; break;
default:
// same ext: compare names
switch (WinCompareStrings(habDesktop, 0, 0,
pmrc1->pszIcon, pmrc2->pszIcon, 0))
{
case WCS_LT: src = -1; break;
case WCS_GT: src = 1; break;
default: src = 0; break;
}
}
}
// printf("psz1: %s, psz2: %s --> %d\n", pmrc1->pszIcon, pmrc2->pszIcon, src);
}
return (src);
}
/*
*@@ fnCompareFoldersFirst:
* container sort comparison function for
* sorting folders first.
*/
SHORT EXPENTRY fnCompareFoldersFirst(PMINIRECORDCORE pmrc1, PMINIRECORDCORE pmrc2, PVOID pStorage)
{
HAB habDesktop = WinQueryAnchorBlock(HWND_DESKTOP);
pStorage = pStorage; // to keep the compiler happy
if ((pmrc1) && (pmrc2))
if ((pmrc1->pszIcon) && (pmrc2->pszIcon))
{
// get SOM objects from cnr record cores
WPObject *pObj1 = OBJECT_FROM_PREC(pmrc1);
WPObject *pObj2 = OBJECT_FROM_PREC(pmrc2);
if ((pObj1) && (pObj2))
{
// determine if the objects are either folders
// or shadows of folders
BOOL IsFldr1 = _somIsA(pObj1, _WPFolder)
? TRUE
: (_somIsA(pObj1, _WPShadow)
? (_somIsA(_wpQueryShadowedObject(pObj1, TRUE), _WPFolder))
: FALSE
);
BOOL IsFldr2 = _somIsA(pObj2, _WPFolder)
? TRUE
: (_somIsA(pObj2, _WPShadow)
? (_somIsA(_wpQueryShadowedObject(pObj2, TRUE), _WPFolder))
: FALSE
);
if (IsFldr1)
if (IsFldr2)
// both are folders: compare titles
switch (WinCompareStrings(habDesktop, 0, 0,
pmrc1->pszIcon, pmrc2->pszIcon, 0))
{
case WCS_LT: return (-1);
case WCS_GT: return (1);
default: return (0);
}
else
// pmrc1 is folder, pmrc2 is not
return (-1);
else
if (IsFldr2)
// pmrc1 is NOT a folder, but pmrc2 is
return (1);
else
// both are NOT folders: compare titles
switch (WinCompareStrings(habDesktop, 0, 0,
pmrc1->pszIcon, pmrc2->pszIcon, 0))
{
case WCS_LT: return (-1);
case WCS_GT: return (1);
default: return (0);
}
}
}
return (0);
}
/*
*@@ fnCompareName:
* comparison func for sort by name. This is
* not terribly fast because it keeps using
* WinCompareStrings, but at least this will
* get special national characters right, which
* the C library funcs won't.
*/
SHORT EXPENTRY fnCompareName(PMINIRECORDCORE pmrc1, PMINIRECORDCORE pmrc2, PVOID pStorage)
{
HAB habDesktop = WinQueryAnchorBlock(HWND_DESKTOP);
pStorage = pStorage; // to keep the compiler happy
if ((pmrc1) && (pmrc2))
if ((pmrc1->pszIcon) && (pmrc2->pszIcon))
switch (WinCompareStrings(habDesktop, 0, 0,
pmrc1->pszIcon, pmrc2->pszIcon, 0))
{
case WCS_LT: return (-1);
case WCS_GT: return (1);
}
return (0);
}
/*
*@@ fnCompareType:
* comparison func for sort by type (.TYPE EA)
*/
SHORT EXPENTRY fnCompareType(PMINIRECORDCORE pmrc1, PMINIRECORDCORE pmrc2, PVOID pStorage)
{
HAB habDesktop = WinQueryAnchorBlock(HWND_DESKTOP);
pStorage = pStorage; // to keep the compiler happy
if ((pmrc1) && (pmrc2))
if ((pmrc1->pszIcon) && (pmrc2->pszIcon))
{
// get SOM objects from cnr record cores
WPObject *pObj1 = OBJECT_FROM_PREC(pmrc1);
WPObject *pObj2 = OBJECT_FROM_PREC(pmrc2);
PSZ pType1 = NULL, pType2 = NULL;
if ((pObj1) && (pObj2))
{
if (_somIsA(pObj1, _WPFileSystem))
pType1 = _wpQueryType(pObj1);
if (_somIsA(pObj2, _WPFileSystem))
pType2 = _wpQueryType(pObj2);
if (pType1) {
if (pType2)
switch (WinCompareStrings(habDesktop, 0, 0,
pType1, pType2, 0))
{
case WCS_LT: return (-1);
case WCS_GT: return (1);
}
else
// obj1 has type, obj2 has not
return (-1);
} else
if (pType2)
// obj1 has NO type, but obj2 does
return (1);
}
}
return (0);
}
/*
*@@ fnCompareClass:
* comparison func for sort by object class
*/
SHORT EXPENTRY fnCompareClass(PMINIRECORDCORE pmrc1, PMINIRECORDCORE pmrc2, PVOID pStorage)
{
HAB habDesktop = WinQueryAnchorBlock(HWND_DESKTOP);
pStorage = pStorage; // to keep the compiler happy
if ((pmrc1) && (pmrc2))
if ((pmrc1->pszIcon) && (pmrc2->pszIcon))
{
// get SOM objects from cnr record cores
WPObject *pObj1 = OBJECT_FROM_PREC(pmrc1);
WPObject *pObj2 = OBJECT_FROM_PREC(pmrc2);
PSZ psz1, psz2;
if ((pObj1) && (pObj2))
{
SOMClass *Metaclass = _somGetClass(pObj1);
if (Metaclass)
psz1 = _wpclsQueryTitle(Metaclass);
Metaclass = _somGetClass(pObj2);
if (Metaclass)
psz2 = _wpclsQueryTitle(Metaclass);
if ((psz1) && (psz2))
switch (WinCompareStrings(habDesktop, 0, 0,
psz1, psz2, 0))
{
case WCS_LT: return (-1);
case WCS_GT: return (1);
}
}
}
return (0);
}
/*
*@@ fnCompareRealName:
* comparison func for sort by real name
*/
SHORT EXPENTRY fnCompareRealName(PMINIRECORDCORE pmrc1, PMINIRECORDCORE pmrc2, PVOID pStorage)
{
HAB habDesktop = WinQueryAnchorBlock(HWND_DESKTOP);
pStorage = pStorage; // to keep the compiler happy
if ((pmrc1) && (pmrc2))
if ((pmrc1->pszIcon) && (pmrc2->pszIcon))
{
// get SOM objects from cnr record cores
WPObject *pObj1 = OBJECT_FROM_PREC(pmrc1);
WPObject *pObj2 = OBJECT_FROM_PREC(pmrc2);
// the following defaults sort objects last that
// have no real name (non-file-system objects)
CHAR sz1[CCHMAXPATH] = {'\255', '\0'},
sz2[CCHMAXPATH] = {'\255', '\0'};
if ((pObj1) && (pObj2))
{
if (_somIsA(pObj1, _WPFileSystem))
_wpQueryFilename(pObj1, sz1, FALSE);
if (_somIsA(pObj2, _WPFileSystem))
_wpQueryFilename(pObj2, sz2, FALSE);
switch (WinCompareStrings(habDesktop, 0, 0,
sz1, sz2, 0))
{
case WCS_LT: return (-1);
case WCS_GT: return (1);
}
}
}
return (0);
}
/*
*@@ fnCompareSize:
* comparison func for sort by size
*/
SHORT EXPENTRY fnCompareSize(PMINIRECORDCORE pmrc1, PMINIRECORDCORE pmrc2, PVOID pStorage)
{
pStorage = pStorage; // to keep the compiler happy
if ((pmrc1) && (pmrc2))
{
// get SOM objects from cnr record cores
WPObject *pObj1 = OBJECT_FROM_PREC(pmrc1);
WPObject *pObj2 = OBJECT_FROM_PREC(pmrc2);
ULONG ul1 = 0, ul2 = 0;
if ((pObj1) && (pObj2))
{
if (_somIsA(pObj1, _WPFileSystem))
ul1 = _wpQueryFileSize(pObj1);
if (_somIsA(pObj2, _WPFileSystem))
ul2 = _wpQueryFileSize(pObj2);
if (ul1 < ul2)
return (1);
else if (ul1 > ul2)
return (-1);
}
}
return (0);
}
/*
*@@ fnCompareCommonDate:
* common comparison func for sort by date functions below;
* ulWhat must be:
* -- 1: compare write date
* -- 2: compare access date
* -- 3: compare creation date
*
* This gets called by fnCompareLastWriteDate,
* fnCompareLastAccessDate, and fnCompareCreationDate
* and should not be specified as a sort function.
*/
SHORT EXPENTRY fnCompareCommonDate(PMINIRECORDCORE pmrc1, PMINIRECORDCORE pmrc2,
ULONG ulWhat)
{
HAB habDesktop = WinQueryAnchorBlock(HWND_DESKTOP);
if ((pmrc1) && (pmrc2))
{
// get SOM objects from cnr record cores
WPObject *pObj1 = OBJECT_FROM_PREC(pmrc1);
WPObject *pObj2 = OBJECT_FROM_PREC(pmrc2);
CHAR sz1[30] = "9999.99.99 99:99:99",
sz2[30] = "9999.99.99 99:99:99";
FDATE fdate;
FTIME ftime;
if ((pObj1) && (pObj2))
{
if (_somIsA(pObj1, _WPFileSystem))
{
switch (ulWhat) {
case 1: _wpQueryLastWrite(pObj1, &fdate, &ftime); break;
case 2: _wpQueryLastAccess(pObj1, &fdate, &ftime); break;
case 3: _wpQueryCreation(pObj1, &fdate, &ftime); break;
}
sprintf(sz1, "%04d.%02d.%02d %02d:%02d:%02d",
((fdate.year)+1980),
fdate.month,
fdate.day,
ftime.hours,
ftime.minutes,
(ftime.twosecs * 2));
}
if (_somIsA(pObj2, _WPFileSystem))
{
switch (ulWhat) {
case 1: _wpQueryLastWrite(pObj2, &fdate, &ftime); break;
case 2: _wpQueryLastAccess(pObj2, &fdate, &ftime); break;
case 3: _wpQueryCreation(pObj2, &fdate, &ftime); break;
}
sprintf(sz2, "%04d.%02d.%02d %02d:%02d:%02d",
((fdate.year)+1980),
fdate.month,
fdate.day,
ftime.hours,
ftime.minutes,
(ftime.twosecs * 2));
}
// printf("%s -- %s\n", sz1, sz2);
switch (WinCompareStrings(habDesktop, 0, 0,
sz1, sz2, 0))
{
case WCS_LT: return (-1);
case WCS_GT: return (1);
}
}
}
return (0);
}
/*
*@@ fnCompareLastWriteDate:
* comparison func for sort by write date.
* This calls fnCompareCommonDate.
*/
SHORT EXPENTRY fnCompareLastWriteDate(PMINIRECORDCORE pmrc1, PMINIRECORDCORE pmrc2, PVOID pStorage)
{
pStorage = pStorage;
return (fnCompareCommonDate(pmrc1, pmrc2, 1));
}
/*
*@@ fnCompareLastAccessDate:
* comparison func for sort by last access date.
* This calls fnCompareCommonDate.
*/
SHORT EXPENTRY fnCompareLastAccessDate(PMINIRECORDCORE pmrc1, PMINIRECORDCORE pmrc2, PVOID pStorage)
{
pStorage = pStorage;
return (fnCompareCommonDate(pmrc1, pmrc2, 2));
}
/*
*@@ fnCompareCreationDate:
* comparison func for sort by creation date.
* This calls fnCompareCommonDate.
*/
SHORT EXPENTRY fnCompareCreationDate(PMINIRECORDCORE pmrc1, PMINIRECORDCORE pmrc2, PVOID pStorage)
{
pStorage = pStorage;
return (fnCompareCommonDate(pmrc1, pmrc2, 3));
}