mirror of
https://github.com/sheumann/DiskBrowser.git
synced 2024-11-21 22:31:13 +00:00
Add support for fetching more results.
This commit is contained in:
parent
567c60040e
commit
ef301fd7fc
@ -84,14 +84,7 @@ static void HandleEvent(int eventCode, WmTaskRec *taskRec) {
|
|||||||
case wInControl:
|
case wInControl:
|
||||||
switch (taskRec->wmTaskData4) {
|
switch (taskRec->wmTaskData4) {
|
||||||
case searchButton:
|
case searchButton:
|
||||||
DoSearch();
|
DoSearch(false);
|
||||||
break;
|
|
||||||
|
|
||||||
case forIIGSRadio:
|
|
||||||
gsDisksOnly = true;
|
|
||||||
break;
|
|
||||||
case forAnyAppleIIRadio:
|
|
||||||
gsDisksOnly = false;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case mountDiskButton:
|
case mountDiskButton:
|
||||||
|
@ -23,11 +23,15 @@
|
|||||||
#include "browserwindow.h"
|
#include "browserwindow.h"
|
||||||
#include "diskbrowser.h"
|
#include "diskbrowser.h"
|
||||||
#include "browserevents.h"
|
#include "browserevents.h"
|
||||||
|
#include "disksearch.h"
|
||||||
|
|
||||||
/* Rectangles outlining the buttons in the style of "default" buttons */
|
/* Rectangles outlining the buttons in the style of "default" buttons */
|
||||||
static Rect searchRect = {8, 305, 26, 414};
|
static Rect searchRect = {8, 305, 26, 414};
|
||||||
static Rect mountRect = {150, 301, 168, 414};
|
static Rect mountRect = {150, 301, 168, 414};
|
||||||
|
|
||||||
|
static char showMoreString[] = "\pShow More";
|
||||||
|
static char mountDiskString[] = "\pMount Disk";
|
||||||
|
|
||||||
/* Has the resource file been opened? (True while window is displayed.) */
|
/* Has the resource file been opened? (True while window is displayed.) */
|
||||||
static Boolean resourceFileOpened;
|
static Boolean resourceFileOpened;
|
||||||
|
|
||||||
@ -48,6 +52,9 @@ static CtlRecHndl searchButtonHandle;
|
|||||||
/* Target control ID last time we checked */
|
/* Target control ID last time we checked */
|
||||||
static unsigned long lastTargetCtlID = 0;
|
static unsigned long lastTargetCtlID = 0;
|
||||||
|
|
||||||
|
/* Is "More Results" selected in the disk list? */
|
||||||
|
static boolean moreResultsSelected = false;
|
||||||
|
|
||||||
|
|
||||||
static void DrawContents(void);
|
static void DrawContents(void);
|
||||||
static void DrawButtonOutlines(boolean justChanged);
|
static void DrawButtonOutlines(boolean justChanged);
|
||||||
@ -109,7 +116,17 @@ void ShowBrowserWindow(void) {
|
|||||||
|
|
||||||
wantToOpenWindow = 0;
|
wantToOpenWindow = 0;
|
||||||
|
|
||||||
|
moreResultsSelected = false;
|
||||||
|
|
||||||
InitEventState();
|
InitEventState();
|
||||||
|
|
||||||
|
diskList = malloc(DISK_LIST_MAX_LENGTH * sizeof(*diskList));
|
||||||
|
if (diskList == NULL) {
|
||||||
|
CloseWindow(window);
|
||||||
|
windowOpened = false;
|
||||||
|
window = NULL;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (resourceFileOpened && !windowOpened) {
|
if (resourceFileOpened && !windowOpened) {
|
||||||
@ -127,20 +144,16 @@ void CloseBrowserWindow(void) {
|
|||||||
CloseWindow(window);
|
CloseWindow(window);
|
||||||
windowOpened = false;
|
windowOpened = false;
|
||||||
window = NULL;
|
window = NULL;
|
||||||
|
|
||||||
/* reset state */
|
|
||||||
gsDisksOnly = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resourceFileOpened) {
|
if (resourceFileOpened) {
|
||||||
CloseResourceFile(resourceFileID);
|
CloseResourceFile(resourceFileID);
|
||||||
resourceFileOpened = false;
|
resourceFileOpened = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(diskList);
|
||||||
|
|
||||||
if (json) {
|
FreeJSON();
|
||||||
json_value_free(json);
|
|
||||||
json = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#pragma databank 0
|
#pragma databank 0
|
||||||
|
|
||||||
@ -202,7 +215,23 @@ void UpdateControlState(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Only allow "Mount Disk" to be clicked if there is a disk selected */
|
/* Only allow "Mount Disk" to be clicked if there is a disk selected */
|
||||||
if (NextMember2(0, (Handle)disksListHandle) != 0) {
|
int currentSelection = NextMember2(0, (Handle)disksListHandle);
|
||||||
|
if (currentSelection != 0) {
|
||||||
|
if (diskList[currentSelection-1].memPtr == moreResultsString) {
|
||||||
|
if (!moreResultsSelected) {
|
||||||
|
SetCtlMoreFlags(GetCtlMoreFlags(mountButtonHandle) & 0xFFFC,
|
||||||
|
mountButtonHandle);
|
||||||
|
SetCtlTitle(showMoreString, (Handle)mountButtonHandle);
|
||||||
|
moreResultsSelected = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (moreResultsSelected) {
|
||||||
|
SetCtlMoreFlags(GetCtlMoreFlags(mountButtonHandle) & 0xFFFC,
|
||||||
|
mountButtonHandle);
|
||||||
|
SetCtlTitle(mountDiskString, (Handle)mountButtonHandle);
|
||||||
|
moreResultsSelected = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
HiliteControl(noHilite, mountButtonHandle);
|
HiliteControl(noHilite, mountButtonHandle);
|
||||||
} else {
|
} else {
|
||||||
HiliteControl(inactiveHilite, mountButtonHandle);
|
HiliteControl(inactiveHilite, mountButtonHandle);
|
||||||
|
@ -27,24 +27,24 @@ GrafPortPtr window;
|
|||||||
/* Is the window open? */
|
/* Is the window open? */
|
||||||
Boolean windowOpened;
|
Boolean windowOpened;
|
||||||
|
|
||||||
/* User preference: IIGS disks or all Apple II disks? */
|
|
||||||
boolean gsDisksOnly = true;
|
|
||||||
|
|
||||||
/* Disks list control */
|
/* Disks list control */
|
||||||
CtlRecHndl disksListHandle;
|
CtlRecHndl disksListHandle;
|
||||||
|
|
||||||
/* List of disks, used for list control & mounting disks */
|
/* List of disks, used for list control & mounting disks */
|
||||||
struct diskListEntry diskList[DISK_LIST_LENGTH];
|
struct diskListEntry *diskList;
|
||||||
|
|
||||||
/* Do we want to open a window with disk contents? Counts down until ready. */
|
/* Do we want to open a window with disk contents? Counts down until ready. */
|
||||||
int wantToOpenWindow = 0;
|
int wantToOpenWindow = 0;
|
||||||
|
|
||||||
/* JSON for current disk list (needs to be kept in memory while it's shown) */
|
/* JSON for current disk list (needs to be kept in memory while it's shown) */
|
||||||
json_value *json = NULL;
|
json_value *json[MAX_PAGES];
|
||||||
|
|
||||||
/* User ID of this program */
|
/* User ID of this program */
|
||||||
Word myUserID;
|
Word myUserID;
|
||||||
|
|
||||||
|
/* String for "More Results" (used to identify that list entry) */
|
||||||
|
char moreResultsString[] = " <More Results>";
|
||||||
|
|
||||||
/***/
|
/***/
|
||||||
|
|
||||||
static char menuTitle[] = "\pArchive.org Disk Browser\xC9";
|
static char menuTitle[] = "\pArchive.org Disk Browser\xC9";
|
||||||
|
@ -22,15 +22,9 @@ extern GrafPortPtr window;
|
|||||||
/* Is the window open? */
|
/* Is the window open? */
|
||||||
extern Boolean windowOpened;
|
extern Boolean windowOpened;
|
||||||
|
|
||||||
/* User preference: IIGS disks or all Apple II disks? */
|
|
||||||
extern boolean gsDisksOnly;
|
|
||||||
|
|
||||||
/* Disks list control */
|
/* Disks list control */
|
||||||
extern CtlRecHndl disksListHandle;
|
extern CtlRecHndl disksListHandle;
|
||||||
|
|
||||||
/* Length of disks list */
|
|
||||||
#define DISK_LIST_LENGTH 30
|
|
||||||
|
|
||||||
struct diskListEntry {
|
struct diskListEntry {
|
||||||
char *memPtr;
|
char *memPtr;
|
||||||
Byte memFlag;
|
Byte memFlag;
|
||||||
@ -38,14 +32,25 @@ struct diskListEntry {
|
|||||||
char *extPtr;
|
char *extPtr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Maximum number of entries in list */
|
||||||
|
#define DISK_LIST_MAX_LENGTH (int)(0xFFFF/sizeof(struct diskListEntry))
|
||||||
|
|
||||||
|
/* How many results to fetch at a time */
|
||||||
|
#define PAGE_SIZE 30
|
||||||
|
|
||||||
|
#define MAX_PAGES ((DISK_LIST_MAX_LENGTH + PAGE_SIZE - 1) / PAGE_SIZE)
|
||||||
|
|
||||||
/* List of disks, used for list control & mounting disks */
|
/* List of disks, used for list control & mounting disks */
|
||||||
extern struct diskListEntry diskList[DISK_LIST_LENGTH];
|
extern struct diskListEntry *diskList;
|
||||||
|
|
||||||
|
/* String for "More Results" (used to identify that list entry) */
|
||||||
|
extern char moreResultsString[];
|
||||||
|
|
||||||
/* Do we want to open a window with disk contents? Counts down until ready. */
|
/* Do we want to open a window with disk contents? Counts down until ready. */
|
||||||
extern int wantToOpenWindow;
|
extern int wantToOpenWindow;
|
||||||
|
|
||||||
/* JSON for current disk list (needs to be kept in memory while it's shown) */
|
/* JSON for current disk list (needs to be kept in memory while it's shown) */
|
||||||
extern json_value *json;
|
extern json_value *json[MAX_PAGES];
|
||||||
|
|
||||||
/* User ID of this program */
|
/* User ID of this program */
|
||||||
extern Word myUserID;
|
extern Word myUserID;
|
||||||
|
@ -123,14 +123,14 @@ resource rPString (forAnyAppleIIRadio) {"Any Apple II"};
|
|||||||
|
|
||||||
resource rControlTemplate (disksList) {
|
resource rControlTemplate (disksList) {
|
||||||
disksList, /* control ID */
|
disksList, /* control ID */
|
||||||
{45, 10, 147, 410}, /* control rect */
|
{45, 10, 147, 386}, /* control rect */
|
||||||
ListControl {{
|
ListControl {{
|
||||||
$0007, /* flags */
|
$0000, /* flags */
|
||||||
$1400, /* more flags */
|
$1400, /* more flags */
|
||||||
0, /* refcon */
|
0, /* refcon */
|
||||||
0, /* list size */
|
0, /* list size */
|
||||||
10, /* List View */
|
10, /* List View */
|
||||||
$0000, /* List Type */
|
$0003, /* List Type */
|
||||||
0, /* List Start */
|
0, /* List Start */
|
||||||
10, /* ListMemHeight */
|
10, /* ListMemHeight */
|
||||||
13, /* List Mem Size */
|
13, /* List Mem Size */
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "diskbrowser.h"
|
#include "diskbrowser.h"
|
||||||
#include "diskmount.h"
|
#include "diskmount.h"
|
||||||
#include "browserutil.h"
|
#include "browserutil.h"
|
||||||
|
#include "disksearch.h"
|
||||||
|
|
||||||
/* Item ID and file extension for the disk image we want to open */
|
/* Item ID and file extension for the disk image we want to open */
|
||||||
static char *wantedExt;
|
static char *wantedExt;
|
||||||
@ -50,6 +51,11 @@ void DoMount(void) {
|
|||||||
}
|
}
|
||||||
itemNumber--;
|
itemNumber--;
|
||||||
|
|
||||||
|
if (diskList[itemNumber].memPtr == moreResultsString) {
|
||||||
|
DoSearch(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (diskList[itemNumber].idPtr == NULL) {
|
if (diskList[itemNumber].idPtr == NULL) {
|
||||||
result = 2;
|
result = 2;
|
||||||
goto errorReturn;
|
goto errorReturn;
|
||||||
|
103
disksearch.c
103
disksearch.c
@ -8,8 +8,10 @@
|
|||||||
|
|
||||||
#include <control.h>
|
#include <control.h>
|
||||||
#include <list.h>
|
#include <list.h>
|
||||||
|
#include <misctool.h>
|
||||||
#include <quickdraw.h>
|
#include <quickdraw.h>
|
||||||
#include <qdaux.h>
|
#include <qdaux.h>
|
||||||
|
#include <window.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -24,22 +26,47 @@
|
|||||||
#include "disksearch.h"
|
#include "disksearch.h"
|
||||||
#include "browserutil.h"
|
#include "browserutil.h"
|
||||||
|
|
||||||
/* Current position in disk list */
|
/* Rectangle of the disk list control */
|
||||||
static int diskListPos = 0;
|
static Rect diskListRect = {45, 10, 147, 386};
|
||||||
|
|
||||||
|
/* Current length in disk list */
|
||||||
|
static int diskListLength = 0;
|
||||||
|
|
||||||
|
/* Number of current page of results from server */
|
||||||
|
int pageNum;
|
||||||
|
|
||||||
static boolean processDoc(json_value *docObj);
|
static boolean processDoc(json_value *docObj);
|
||||||
static char *EncodeQueryString(char *queryString);
|
static char *EncodeQueryString(char *queryString);
|
||||||
|
|
||||||
|
struct diskListEntry moreResultsEntry = {moreResultsString , 0, "", ""};
|
||||||
|
|
||||||
|
static void InsertDiskListEntry(struct diskListEntry *entry);
|
||||||
|
|
||||||
/* Do a search */
|
/* Do a search */
|
||||||
void DoSearch(void) {
|
void DoSearch(boolean getMore) {
|
||||||
static char queryBuf[257];
|
static char queryBuf[257];
|
||||||
|
static boolean gsDisksOnly = true; /* User preference: IIGS disks only? */
|
||||||
|
|
||||||
char *searchURL = NULL;
|
char *searchURL = NULL;
|
||||||
enum NetDiskError result = 0;
|
enum NetDiskError result = 0;
|
||||||
|
|
||||||
|
int initialDiskListLength = diskListLength;
|
||||||
|
|
||||||
WaitCursor();
|
WaitCursor();
|
||||||
|
|
||||||
GetLETextByID(window, searchLine, (StringPtr)&queryBuf);
|
if (!getMore) {
|
||||||
|
FreeJSON();
|
||||||
|
GetLETextByID(window, searchLine, (StringPtr)&queryBuf);
|
||||||
|
gsDisksOnly = (FindRadioButton(window, 2) == 0);
|
||||||
|
pageNum = 0;
|
||||||
|
} else {
|
||||||
|
if (pageNum >= MAX_PAGES - 1) {
|
||||||
|
InitCursor();
|
||||||
|
SysBeep();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pageNum++;
|
||||||
|
}
|
||||||
|
|
||||||
char *queryString = EncodeQueryString(queryBuf+1);
|
char *queryString = EncodeQueryString(queryBuf+1);
|
||||||
if (queryString == NULL) {
|
if (queryString == NULL) {
|
||||||
@ -56,8 +83,8 @@ void DoSearch(void) {
|
|||||||
"&rows=%i&page=%i&output=json",
|
"&rows=%i&page=%i&output=json",
|
||||||
gsDisksOnly ? "apple2gs" : "apple2%2A",
|
gsDisksOnly ? "apple2gs" : "apple2%2A",
|
||||||
queryString,
|
queryString,
|
||||||
DISK_LIST_LENGTH,
|
PAGE_SIZE,
|
||||||
/*pageNum*/ 0);
|
pageNum + 1);
|
||||||
if (searchURL == NULL) {
|
if (searchURL == NULL) {
|
||||||
result = URL_TOO_LONG;
|
result = URL_TOO_LONG;
|
||||||
goto errorReturn;
|
goto errorReturn;
|
||||||
@ -65,19 +92,25 @@ void DoSearch(void) {
|
|||||||
free(queryString);
|
free(queryString);
|
||||||
queryString = NULL;
|
queryString = NULL;
|
||||||
|
|
||||||
if (json)
|
if (!getMore) {
|
||||||
json_value_free(json);
|
FreeJSON();
|
||||||
result = ReadJSONFromURL(searchURL, &json);
|
}
|
||||||
|
result = ReadJSONFromURL(searchURL, &json[pageNum]);
|
||||||
if (result != OPERATION_SUCCESSFUL)
|
if (result != OPERATION_SUCCESSFUL)
|
||||||
goto errorReturn;
|
goto errorReturn;
|
||||||
|
|
||||||
json_value *response = findEntryInObject(json, "response", json_object);
|
json_value *response =
|
||||||
|
findEntryInObject(json[pageNum], "response", json_object);
|
||||||
if (response == NULL) {
|
if (response == NULL) {
|
||||||
result = NOT_EXPECTED_CONTENTS;
|
result = NOT_EXPECTED_CONTENTS;
|
||||||
goto errorReturn;
|
goto errorReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
diskListPos = 0;
|
if (!getMore) {
|
||||||
|
diskListLength = 0;
|
||||||
|
} else {
|
||||||
|
diskListLength--;
|
||||||
|
}
|
||||||
json_value *docs = findEntryInObject(response, "docs", json_array);
|
json_value *docs = findEntryInObject(response, "docs", json_array);
|
||||||
if (docs == NULL) {
|
if (docs == NULL) {
|
||||||
result = NOT_EXPECTED_CONTENTS;
|
result = NOT_EXPECTED_CONTENTS;
|
||||||
@ -85,9 +118,14 @@ void DoSearch(void) {
|
|||||||
}
|
}
|
||||||
processArray(docs, json_object, processDoc);
|
processArray(docs, json_object, processDoc);
|
||||||
|
|
||||||
diskList[0].memFlag = 0x80;
|
if (!getMore) {
|
||||||
for (int i = 1; i < DISK_LIST_LENGTH; i++) {
|
diskList[0].memFlag = 0x80;
|
||||||
diskList[i].memFlag = 0;
|
}
|
||||||
|
|
||||||
|
json_value *numFoundValue =
|
||||||
|
findEntryInObject(response, "numFound", json_integer);
|
||||||
|
if (numFoundValue != NULL && numFoundValue->u.integer > diskListLength) {
|
||||||
|
InsertDiskListEntry(&moreResultsEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update state of controls once disk list is available */
|
/* Update state of controls once disk list is available */
|
||||||
@ -97,9 +135,16 @@ void DoSearch(void) {
|
|||||||
disksListHandle);
|
disksListHandle);
|
||||||
|
|
||||||
NewList2(NULL, 1, (Ref) diskList, refIsPointer,
|
NewList2(NULL, 1, (Ref) diskList, refIsPointer,
|
||||||
diskListPos, (Handle)disksListHandle);
|
diskListLength, (Handle)disksListHandle);
|
||||||
|
|
||||||
if (diskListPos > 0) {
|
if (getMore) {
|
||||||
|
if (diskListLength >= initialDiskListLength) {
|
||||||
|
SelectMember2(initialDiskListLength, (Handle)disksListHandle);
|
||||||
|
ValidRect(&diskListRect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (diskListLength > 0) {
|
||||||
if (FindTargetCtl() != disksListHandle) {
|
if (FindTargetCtl() != disksListHandle) {
|
||||||
MakeThisCtlTarget(disksListHandle);
|
MakeThisCtlTarget(disksListHandle);
|
||||||
CallCtlDefProc(disksListHandle, ctlChangeTarget, 0);
|
CallCtlDefProc(disksListHandle, ctlChangeTarget, 0);
|
||||||
@ -119,7 +164,7 @@ errorReturn:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static boolean processDoc(json_value *docObj) {
|
static boolean processDoc(json_value *docObj) {
|
||||||
if (diskListPos >= DISK_LIST_LENGTH)
|
if (diskListLength >= DISK_LIST_MAX_LENGTH)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (docObj == NULL || docObj->type != json_object)
|
if (docObj == NULL || docObj->type != json_object)
|
||||||
@ -129,10 +174,11 @@ static boolean processDoc(json_value *docObj) {
|
|||||||
json_value *ext = findEntryInObject(docObj, "emulator_ext", json_string);
|
json_value *ext = findEntryInObject(docObj, "emulator_ext", json_string);
|
||||||
if (id == NULL || title == NULL || ext == NULL)
|
if (id == NULL || title == NULL || ext == NULL)
|
||||||
return true;
|
return true;
|
||||||
diskList[diskListPos].idPtr = id->u.string.ptr;
|
diskList[diskListLength].idPtr = id->u.string.ptr;
|
||||||
// TODO character set translation
|
// TODO character set translation
|
||||||
diskList[diskListPos].memPtr = title->u.string.ptr;
|
diskList[diskListLength].memPtr = title->u.string.ptr;
|
||||||
diskList[diskListPos++].extPtr = ext->u.string.ptr;
|
diskList[diskListLength].extPtr = ext->u.string.ptr;
|
||||||
|
diskList[diskListLength++].memFlag = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,3 +210,20 @@ static char *EncodeQueryString(char *queryString) {
|
|||||||
*s = '\0';
|
*s = '\0';
|
||||||
return encodedStr;
|
return encodedStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void InsertDiskListEntry(struct diskListEntry *entry) {
|
||||||
|
if (diskListLength >= DISK_LIST_MAX_LENGTH)
|
||||||
|
return;
|
||||||
|
|
||||||
|
diskList[diskListLength++] = *entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FreeJSON(void) {
|
||||||
|
for (int i = 0; i < MAX_PAGES; i++) {
|
||||||
|
if (json[i] != NULL) {
|
||||||
|
json_value_free(json[i]);
|
||||||
|
json[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#ifndef DISKSEARCH_H
|
#ifndef DISKSEARCH_H
|
||||||
#define DISKSEARCH_H
|
#define DISKSEARCH_H
|
||||||
|
|
||||||
void DoSearch(void);
|
void DoSearch(boolean getMore);
|
||||||
|
void FreeJSON(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user