+++ /dev/null
-/* ------------ helpbox.c ----------- */
-
-#include "dflat.h"
-#include "htree.h"
-
-extern DF_DBOX HelpBox;
-
-/* -------- strings of D-Flat classes for calling default
- help text collections -------- */
-char *DfClassNames[] = {
- #undef DfClassDef
- #define DfClassDef(c,b,p,a) #c,
- #include "classes.h"
- NULL
-};
-
-#define MAXHEIGHT (DfGetScreenHeight()-10)
-
-/* --------- linked list of help text collections -------- */
-struct helps {
- char *hname;
- char *NextName;
- char *PrevName;
- long hptr;
- int bit;
- int hheight;
- int hwidth;
- DFWINDOW hwnd;
- struct helps *NextHelp;
-};
-static struct helps *FirstHelp;
-static struct helps *LastHelp;
-static struct helps *ThisHelp;
-
-/* --- linked stack of help windows that have beed used --- */
-struct HelpStack {
- char *hname;
- struct HelpStack *PrevStack;
-};
-static struct HelpStack *LastStack;
-static struct HelpStack *ThisStack;
-
-/* --- linked list of keywords in the current help
- text collection (listhead is in window) -------- */
-struct keywords {
- char *hname;
- int lineno;
- int off1, off2, off3;
- int isDefinition;
- struct keywords *nextword;
- struct keywords *prevword;
-};
-
-static FILE *helpfp;
-static char hline [160];
-static BOOL Helping;
-
-static void SelectHelp(DFWINDOW, char *);
-static void ReadHelp(DFWINDOW);
-static void FindHelp(char *);
-static void FindHelpWindow(DFWINDOW);
-static void DisplayDefinition(DFWINDOW, char *);
-static void BestFit(DFWINDOW, DF_DIALOGWINDOW *);
-
-/* ------------- DFM_CREATE_WINDOW message ------------ */
-static void CreateWindowMsg(DFWINDOW wnd)
-{
- Helping = TRUE;
- DfGetClass(wnd) = DF_HELPBOX;
- DfInitWindowColors(wnd);
- if (ThisHelp != NULL)
- ThisHelp->hwnd = wnd;
-}
-
-/* ------------- COMMAND message ------------ */
-static BOOL CommandMsg(DFWINDOW wnd, DF_PARAM p1)
-{
- switch ((int)p1) {
- case DF_ID_CANCEL:
- ThisStack = LastStack;
- while (ThisStack != NULL) {
- LastStack = ThisStack->PrevStack;
- if (ThisStack->hname != NULL)
- free(ThisStack->hname);
- free(ThisStack);
- ThisStack = LastStack;
- }
- break;
- case DF_ID_PREV:
- FindHelpWindow(wnd);
- if (ThisHelp != NULL)
- SelectHelp(wnd, ThisHelp->PrevName);
- return TRUE;
- case DF_ID_NEXT:
- FindHelpWindow(wnd);
- if (ThisHelp != NULL)
- SelectHelp(wnd, ThisHelp->NextName);
- return TRUE;
- case DF_ID_BACK:
- if (LastStack != NULL) {
- if (LastStack->PrevStack != NULL) {
- ThisStack = LastStack->PrevStack;
- if (LastStack->hname != NULL)
- free(LastStack->hname);
- free(LastStack);
- LastStack = ThisStack;
- SelectHelp(wnd, ThisStack->hname);
- }
- }
- return TRUE;
- default:
- break;
- }
- return FALSE;
-}
-
-/* ------------- DFM_KEYBOARD message ------------ */
-static BOOL KeyboardMsg(DFWINDOW wnd, DF_PARAM p1)
-{
- DFWINDOW cwnd;
- struct keywords *thisword;
- static char HelpName[50];
-
- cwnd = DfControlWindow(wnd->extension, DF_ID_HELPTEXT);
- if (cwnd == NULL || DfInFocus != cwnd)
- return FALSE;
- thisword = cwnd->thisword;
- switch ((int)p1) {
- case '\r':
- if (thisword != NULL) {
- if (thisword->isDefinition)
- DisplayDefinition(DfGetParent(wnd),
- thisword->hname);
- else {
- strncpy(HelpName, thisword->hname,
- sizeof HelpName);
- SelectHelp(wnd, HelpName);
- }
- }
- return TRUE;
- case '\t':
- if (thisword == NULL)
- thisword = cwnd->firstword;
- else {
- if (thisword->nextword == NULL)
- thisword = cwnd->firstword;
- else
- thisword = thisword->nextword;
- }
- break;
- case DF_SHIFT_HT:
- if (thisword == NULL)
- thisword = cwnd->lastword;
- else {
- if (thisword->prevword == NULL)
- thisword = cwnd->lastword;
- else
- thisword = thisword->prevword;
- }
- break;
- default:
- thisword = NULL;
- break;
- }
- if (thisword != NULL) {
- cwnd->thisword = thisword;
- if (thisword->lineno < cwnd->wtop ||
- thisword->lineno >=
- cwnd->wtop + DfClientHeight(cwnd)) {
- int distance = DfClientHeight(cwnd)/2;
- do {
- cwnd->wtop = thisword->lineno-distance;
- distance /= 2;
- }
- while (cwnd->wtop < 0);
- }
- DfSendMessage(cwnd, DFM_PAINT, 0, 0);
- return TRUE;
- }
- return FALSE;
-}
-
-/* ---- window processing module for the DF_HELPBOX ------- */
-int DfHelpBoxProc(DFWINDOW wnd, DFMESSAGE msg, DF_PARAM p1, DF_PARAM p2)
-{
- DF_DBOX *db = wnd->extension;
-
- switch (msg) {
- case DFM_CREATE_WINDOW:
- CreateWindowMsg(wnd);
- break;
- case DFM_INITIATE_DIALOG:
- ReadHelp(wnd);
- break;
- case DFM_COMMAND:
- if (p2 != 0)
- break;
- if (CommandMsg(wnd, p1))
- return TRUE;
- break;
- case DFM_KEYBOARD:
- if (DfWindowMoving)
- break;
- if (KeyboardMsg(wnd, p1))
- return TRUE;
- break;
- case DFM_CLOSE_WINDOW:
- if (db != NULL) {
- if (db->dwnd.title != NULL) {
- free(db->dwnd.title);
- db->dwnd.title = NULL;
- }
- }
- FindHelpWindow(wnd);
- if (ThisHelp != NULL)
- ThisHelp->hwnd = NULL;
- Helping = FALSE;
- break;
- default:
- break;
- }
- return DfBaseWndProc(DF_HELPBOX, wnd, msg, p1, p2);
-}
-
-/* ----- select a new help window from its name ----- */
-static void SelectHelp(DFWINDOW wnd, char *hname)
-{
- if (hname != NULL) {
- DFWINDOW pwnd = DfGetParent(wnd);
- DfPostMessage(wnd, DFM_ENDDIALOG, 0, 0);
- DfPostMessage(pwnd, DFM_DISPLAY_HELP, (DF_PARAM) hname, 0);
- }
-}
-
-/* ---- DFM_PAINT message for the helpbox text editbox ---- */
-static int PaintMsg(DFWINDOW wnd, DF_PARAM p1, DF_PARAM p2)
-{
- struct keywords *thisword;
- int rtn;
- if (wnd->thisword != NULL) {
- DFWINDOW pwnd = DfGetParent(wnd);
- char *cp;
- thisword = wnd->thisword;
- cp = DfTextLine(wnd, thisword->lineno);
- cp += thisword->off1;
- *(cp+1) =
- (pwnd->WindowColors[DF_SELECT_COLOR][DF_FG] & 255) | 0x80;
- *(cp+2) =
- (pwnd->WindowColors[DF_SELECT_COLOR][DF_BG] & 255) | 0x80;
- rtn = DfDefaultWndProc(wnd, DFM_PAINT, p1, p2);
- *(cp+1) =
- (pwnd->WindowColors[DF_HILITE_COLOR][DF_FG] & 255) | 0x80;
- *(cp+2) =
- (pwnd->WindowColors[DF_HILITE_COLOR][DF_BG] & 255) | 0x80;
- return rtn;
- }
- return DfDefaultWndProc(wnd, DFM_PAINT, p1, p2);
-}
-
-/* ---- DFM_LEFT_BUTTON message for the helpbox text editbox ---- */
-static int LeftButtonMsg(DFWINDOW wnd, DF_PARAM p1, DF_PARAM p2)
-{
- struct keywords *thisword;
- int rtn, mx, my;
-
- rtn = DfDefaultWndProc(wnd, DFM_LEFT_BUTTON, p1, p2);
- mx = (int)p1 - DfGetClientLeft(wnd);
- my = (int)p2 - DfGetClientTop(wnd);
- my += wnd->wtop;
- thisword = wnd->firstword;
- while (thisword != NULL) {
- if (my == thisword->lineno) {
- if (mx >= thisword->off2 &&
- mx < thisword->off3) {
- wnd->thisword = thisword;
- DfSendMessage(wnd, DFM_PAINT, 0, 0);
- if (thisword->isDefinition) {
- DFWINDOW pwnd = DfGetParent(wnd);
- if (pwnd != NULL)
- DisplayDefinition(DfGetParent(pwnd),
- thisword->hname);
- }
- break;
- }
- }
- thisword = thisword->nextword;
- }
- return rtn;
-}
-
-/* --- window processing module for DF_HELPBOX's text DF_EDITBOX -- */
-int HelpTextProc(DFWINDOW wnd, DFMESSAGE msg, DF_PARAM p1, DF_PARAM p2)
-{
- struct keywords *thisword;
- switch (msg) {
- case DFM_PAINT:
- return PaintMsg(wnd, p1, p2);
- case DFM_LEFT_BUTTON:
- return LeftButtonMsg(wnd, p1, p2);
- case DOUBLE_CLICK:
- DfPostMessage(wnd, DFM_KEYBOARD, '\r', 0);
- break;
- case DFM_CLOSE_WINDOW:
- thisword = wnd->firstword;
- while (thisword != NULL) {
- struct keywords *nextword = thisword->nextword;
- if (thisword->hname != NULL)
- free(thisword->hname);
- free(thisword);
- thisword = nextword;
- }
- break;
- default:
- break;
- }
- return DfDefaultWndProc(wnd, msg, p1, p2);
-}
-
-/* -------- read the help text into the editbox ------- */
-static void ReadHelp(DFWINDOW wnd)
-{
- DFWINDOW cwnd = DfControlWindow(wnd->extension, DF_ID_HELPTEXT);
- int linectr = 0;
- if (cwnd == NULL)
- return;
- cwnd->wndproc = HelpTextProc;
- /* ----- read the help text ------- */
- while (TRUE) {
- char *cp = hline, *cp1;
- int colorct = 0;
- if (DfGetHelpLine(hline) == NULL)
- break;
- if (*hline == '<')
- break;
- hline[strlen(hline)-1] = '\0';
- /* --- add help text to the help window --- */
- while (cp != NULL) {
- if ((cp = strchr(cp, '[')) != NULL) {
- /* ----- hit a new key word ----- */
- struct keywords *thisword;
- if (*(cp+1) != '.' && *(cp+1) != '*') {
- cp++;
- continue;
- }
- thisword = DfCalloc(1, sizeof(struct keywords));
- if (cwnd->firstword == NULL)
- cwnd->firstword = thisword;
- if (cwnd->lastword != NULL) {
- ((struct keywords *)
- (cwnd->lastword))->nextword = thisword;
- thisword->prevword = cwnd->lastword;
- }
- cwnd->lastword = thisword;
- thisword->lineno = cwnd->wlines;
- thisword->off1 = (int) ((int)cp - (int)hline);
- thisword->off2 = thisword->off1 - colorct * 4;
- thisword->isDefinition = *(cp+1) == '*';
- colorct++;
- *cp++ = DF_CHANGECOLOR;
- *cp++ =
- (wnd->WindowColors [DF_HILITE_COLOR] [DF_FG] & 255) | 0x80;
- *cp++ =
- (wnd->WindowColors [DF_HILITE_COLOR] [DF_BG] & 255) | 0x80;
- cp1 = cp;
- if ((cp = strchr(cp, ']')) != NULL) {
- if (thisword != NULL)
- thisword->off3 =
- thisword->off2 + (int) (cp - cp1);
- *cp++ = DF_RESETCOLOR;
- }
- if ((cp = strchr(cp, '<')) != NULL) {
- char *cp1 = strchr(cp, '>');
- if (cp1 != NULL) {
- int len = (int) ((int)cp1 - (int)cp);
- thisword->hname = DfCalloc(1, len);
- strncpy(thisword->hname, cp+1, len-1);
- memmove(cp, cp1+1, strlen(cp1));
- }
- }
- }
- }
- DfPutItemText(wnd, DF_ID_HELPTEXT, hline);
- /* -- display help text as soon as window is full -- */
- if (++linectr == DfClientHeight(cwnd))
- DfSendMessage(cwnd, DFM_PAINT, 0, 0);
- if (linectr > DfClientHeight(cwnd) &&
- !DfTestAttribute(cwnd, DF_VSCROLLBAR)) {
- DfAddAttribute(cwnd, DF_VSCROLLBAR);
- DfSendMessage(cwnd, DFM_BORDER, 0, 0);
- }
- }
-}
-
-/* ---- compute the displayed length of a help text line --- */
-static int HelpLength(char *s)
-{
- int len = strlen(s);
- char *cp = strchr(s, '[');
- while (cp != NULL) {
- len -= 4;
- cp = strchr(cp+1, '[');
- }
- cp = strchr(s, '<');
- while (cp != NULL) {
- char *cp1 = strchr(cp, '>');
- if (cp1 != NULL)
- len -= (int) (cp1-cp)+1;
- cp = strchr(cp1, '<');
- }
- return len;
-}
-
-/* ----------- load the help text file ------------ */
-void DfLoadHelpFile()
-{
- char *cp;
-
- if (Helping)
- return;
- DfUnLoadHelpFile();
- if ((helpfp = DfOpenHelpFile()) == NULL)
- return;
- *hline = '\0';
- while (*hline != '<') {
- if (DfGetHelpLine(hline) == NULL) {
- fclose(helpfp);
- return;
- }
- }
- while (*hline == '<') {
- if (strncmp(hline, "<end>", 5) == 0)
- break;
-
- /* -------- parse the help window's text name ----- */
- if ((cp = strchr(hline, '>')) != NULL) {
- ThisHelp = DfCalloc(1, sizeof(struct helps));
- if (FirstHelp == NULL)
- FirstHelp = ThisHelp;
- *cp = '\0';
- ThisHelp->hname=DfMalloc(strlen(hline+1)+1);
- strcpy(ThisHelp->hname, hline+1);
-
- DfHelpFilePosition(&ThisHelp->hptr, &ThisHelp->bit);
-
- if (DfGetHelpLine(hline) == NULL)
- break;
-
- /* ------- build the help linked list entry --- */
- while (*hline == '[') {
- DfHelpFilePosition(&ThisHelp->hptr,
- &ThisHelp->bit);
- /* ---- parse the <<prev button pointer ---- */
- if (strncmp(hline, "[<<]", 4) == 0) {
- char *cp = strchr(hline+4, '<');
- if (cp != NULL) {
- char *cp1 = strchr(cp, '>');
- if (cp1 != NULL) {
- int len = (int) (cp1-cp);
- ThisHelp->PrevName=DfCalloc(1,len);
- strncpy(ThisHelp->PrevName,
- cp+1,len-1);
- }
- }
- if (DfGetHelpLine(hline) == NULL)
- break;
- continue;
- }
- /* ---- parse the next>> button pointer ---- */
- else if (strncmp(hline, "[>>]", 4) == 0) {
- char *cp = strchr(hline+4, '<');
- if (cp != NULL) {
- char *cp1 = strchr(cp, '>');
- if (cp1 != NULL) {
- int len = (int) (cp1-cp);
- ThisHelp->NextName=DfCalloc(1,len);
- strncpy(ThisHelp->NextName,
- cp+1,len-1);
- }
- }
- if (DfGetHelpLine(hline) == NULL)
- break;
- continue;
- }
- else
- break;
- }
- ThisHelp->hheight = 0;
- ThisHelp->hwidth = 0;
- ThisHelp->NextHelp = NULL;
-
- /* ------ append entry to the linked list ------ */
- if (LastHelp != NULL)
- LastHelp->NextHelp = ThisHelp;
- LastHelp = ThisHelp;
- }
- /* -------- move to the next <helpname> token ------ */
- if (DfGetHelpLine(hline) == NULL)
- strcpy(hline, "<end>");
- while (*hline != '<') {
- ThisHelp->hwidth =
- max(ThisHelp->hwidth, HelpLength(hline));
- ThisHelp->hheight++;
- if (DfGetHelpLine(hline) == NULL)
- strcpy(hline, "<end>");
- }
- }
- fclose(helpfp);
-}
-
-/* ------ free the memory used by the help file table ------ */
-void DfUnLoadHelpFile(void)
-{
- while (FirstHelp != NULL) {
- ThisHelp = FirstHelp;
- if (ThisHelp->hname != NULL)
- free(ThisHelp->hname);
- if (ThisHelp->PrevName != NULL)
- free(ThisHelp->PrevName);
- if (ThisHelp->NextName != NULL)
- free(ThisHelp->NextName);
- FirstHelp = ThisHelp->NextHelp;
- free(ThisHelp);
- }
- ThisHelp = LastHelp = NULL;
- free(DfHelpTree);
- DfHelpTree = NULL;
-}
-
-/* ---------- display a specified help text ----------- */
-BOOL DfDisplayHelp(DFWINDOW wnd, char *Help)
-{
- BOOL rtn = FALSE;
- if (Helping)
- return TRUE;
- wnd->isHelping++;
- FindHelp(Help);
- if (ThisHelp != NULL) {
- if (LastStack == NULL ||
- _stricmp(Help, LastStack->hname)) {
- /* ---- add the window to the history stack ---- */
- ThisStack = DfCalloc(1,sizeof(struct HelpStack));
- ThisStack->hname = DfMalloc(strlen(Help)+1);
- if (ThisStack->hname != NULL)
- strcpy(ThisStack->hname, Help);
- ThisStack->PrevStack = LastStack;
- LastStack = ThisStack;
- }
- if ((helpfp = DfOpenHelpFile()) != NULL) {
- DF_DBOX *db;
- int offset, i;
-
- db = DfCalloc(1,sizeof HelpBox);
- memcpy(db, &HelpBox, sizeof HelpBox);
- /* -- seek to the first line of the help text -- */
- DfSeekHelpLine(ThisHelp->hptr, ThisHelp->bit);
- /* ----- read the title ----- */
- DfGetHelpLine(hline);
- hline[strlen(hline)-1] = '\0';
- db->dwnd.title = DfMalloc(strlen(hline)+1);
- strcpy(db->dwnd.title, hline);
- /* ----- set the height and width ----- */
- db->dwnd.h = min(ThisHelp->hheight, MAXHEIGHT)+7;
- db->dwnd.w = max(45, ThisHelp->hwidth+6);
- /* ------ position the help window ----- */
- BestFit(wnd, &db->dwnd);
- /* ------- position the command buttons ------ */
- db->ctl[0].dwnd.w = max(40, ThisHelp->hwidth+2);
- db->ctl[0].dwnd.h =
- min(ThisHelp->hheight, MAXHEIGHT)+2;
- offset = (db->dwnd.w-40) / 2;
- for (i = 1; i < 5; i++) {
- db->ctl[i].dwnd.y =
- min(ThisHelp->hheight, MAXHEIGHT)+3;
- db->ctl[i].dwnd.x += offset;
- }
- /* ---- disable ineffective buttons ---- */
- if (ThisStack != NULL)
- if (ThisStack->PrevStack == NULL)
- DfDisableButton(db, DF_ID_BACK);
- if (ThisHelp->NextName == NULL)
- DfDisableButton(db, DF_ID_NEXT);
- if (ThisHelp->PrevName == NULL)
- DfDisableButton(db, DF_ID_PREV);
- /* ------- display the help window ----- */
- DfDialogBox(NULL, db, TRUE, DfHelpBoxProc);
- free(db);
- fclose(helpfp);
- rtn = TRUE;
- }
- }
- --wnd->isHelping;
- return rtn;
-}
-
-/* ------- display a definition window --------- */
-static void DisplayDefinition(DFWINDOW wnd, char *def)
-{
- DFWINDOW dwnd;
- DFWINDOW hwnd = wnd;
- int y;
-
- if (DfGetClass(wnd) == DF_POPDOWNMENU)
- hwnd = DfGetParent(wnd);
- y = DfGetClass(hwnd) == DF_MENUBAR ? 2 : 1;
- FindHelp(def);
- if (ThisHelp != NULL) {
- if ((helpfp = DfOpenHelpFile()) != NULL) {
- dwnd = DfDfCreateWindow(
- DF_TEXTBOX,
- NULL,
- DfGetClientLeft(hwnd),
- DfGetClientTop(hwnd)+y,
- min(ThisHelp->hheight, MAXHEIGHT)+3,
- ThisHelp->hwidth+2,
- NULL,
- wnd,
- NULL,
- DF_HASBORDER | DF_NOCLIP | DF_SAVESELF);
- if (dwnd != NULL) {
- /* ----- read the help text ------- */
- DfSeekHelpLine(ThisHelp->hptr, ThisHelp->bit);
- while (TRUE) {
- if (DfGetHelpLine(hline) == NULL)
- break;
- if (*hline == '<')
- break;
- hline[strlen(hline)-1] = '\0';
- DfSendMessage(dwnd,DFM_ADDTEXT,(DF_PARAM)hline,0);
- }
- DfSendMessage(dwnd, DFM_SHOW_WINDOW, 0, 0);
- DfSendMessage(NULL, DFM_WAITKEYBOARD, 0, 0);
- DfSendMessage(NULL, DFM_WAITMOUSE, 0, 0);
- DfSendMessage(dwnd, DFM_CLOSE_WINDOW, 0, 0);
- }
- fclose(helpfp);
- }
- }
-}
-
-/* ------ compare help names with wild cards ----- */
-static BOOL wildcmp(char *s1, char *s2)
-{
- while (*s1 || *s2) {
- if (tolower(*s1) != tolower(*s2))
- if (*s1 != '?' && *s2 != '?')
- return TRUE;
- s1++, s2++;
- }
- return FALSE;
-}
-
-/* --- ThisHelp = the help window matching specified name --- */
-static void FindHelp(char *Help)
-{
- ThisHelp = FirstHelp;
- while (ThisHelp != NULL) {
- if (wildcmp(Help, ThisHelp->hname) == FALSE)
- break;
- ThisHelp = ThisHelp->NextHelp;
- }
-}
-
-/* --- ThisHelp = the help window matching specified wnd --- */
-static void FindHelpWindow(DFWINDOW wnd)
-{
- ThisHelp = FirstHelp;
- while (ThisHelp != NULL) {
- if (wnd == ThisHelp->hwnd)
- break;
- ThisHelp = ThisHelp->NextHelp;
- }
-}
-
-static int OverLap(int a, int b)
-{
- int ov = a - b;
- if (ov < 0)
- ov = 0;
- return ov;
-}
-
-/* ----- compute the best location for a help dialogbox ----- */
-static void BestFit(DFWINDOW wnd, DF_DIALOGWINDOW *dwnd)
-{
- int above, below, right, left;
- if (DfGetClass(wnd) == DF_MENUBAR ||
- DfGetClass(wnd) == DF_APPLICATION) {
- dwnd->x = dwnd->y = -1;
- return;
- }
- /* --- compute above overlap ---- */
- above = OverLap(dwnd->h, DfGetTop(wnd));
- /* --- compute below overlap ---- */
- below = OverLap(DfGetBottom(wnd), DfGetScreenHeight()-dwnd->h);
- /* --- compute right overlap ---- */
- right = OverLap(DfGetRight(wnd), DfGetScreenWidth()-dwnd->w);
- /* --- compute left overlap ---- */
- left = OverLap(dwnd->w, DfGetLeft(wnd));
-
- if (above < below)
- dwnd->y = max(0, DfGetTop(wnd)-dwnd->h-2);
- else
- dwnd->y = min(DfGetScreenHeight()-dwnd->h, DfGetBottom(wnd)+2);
- if (right < left)
- dwnd->x = min(DfGetRight(wnd)+2, DfGetScreenWidth()-dwnd->w);
- else
- dwnd->x = max(0, DfGetLeft(wnd)-dwnd->w-2);
-
- if (dwnd->x == DfGetRight(wnd)+2 ||
- dwnd->x == DfGetLeft(wnd)-dwnd->w-2)
- dwnd->y = -1;
- if (dwnd->y ==DfGetTop(wnd)-dwnd->h-2 ||
- dwnd->y == DfGetBottom(wnd)+2)
- dwnd->x = -1;
-}
-
-/* EOF */