#include /* * $Author: garbled $ * $Date: 2001/01/04 20:15:31 $ * $Revision: 1.2 $ */ /* * Declare some local definitions. */ #define DOWN 0 #define UP 1 /* * Declare file local prototypes. */ static int searchForWord (CDKVIEWER *viewer, char *pattern, int direction); static int jumpToLine (CDKVIEWER *viewer); static void popUpLabel (CDKVIEWER *viewer, char *mesg); static void getAndStorePattern (CDKSCREEN *screen); static void drawCDKViewerButtons (CDKVIEWER *viewer); static void drawCDKViewerInfo (CDKVIEWER *viewer); /* * Declare file local variables. */ static char * SearchPattern = 0; int SearchDirection = DOWN; DeclareCDKObjects(my_funcs, Viewer); /* * This function creates a new viewer object. */ CDKVIEWER *newCDKViewer (CDKSCREEN *cdkscreen, int xplace, int yplace, int height, int width, char **buttonLabel, int buttonCount, chtype buttonHighlight, boolean Box, boolean shadow) { /* Declare local variables. */ CDKVIEWER *viewer = newCDKObject(CDKVIEWER, &my_funcs); int parentWidth = getmaxx(cdkscreen->window); int parentHeight = getmaxy(cdkscreen->window); int boxWidth = width; int boxHeight = height; int xpos = xplace; int ypos = yplace; int buttonWidth, buttonPos, buttonAdj; int x, junk2; /* * If the height is a negative value, the height will * be ROWS-height, otherwise, the height will be the * given height. */ boxHeight = setWidgetDimension (parentHeight, height, 0); /* * If the width is a negative value, the width will * be COLS-width, otherwise, the width will be the * given width. */ boxWidth = setWidgetDimension (parentWidth, width, 0); /* Translate the button label char * to a chtype * */ buttonWidth = 0; for (x=0; x < buttonCount; x++) { viewer->buttonLabel[x] = char2Chtype (buttonLabel[x], &viewer->buttonLen[x], &junk2); buttonWidth += viewer->buttonLen[x] + 1; } buttonWidth--; /* Determine the final dimensions of the box. */ boxWidth = MAXIMUM (boxWidth, buttonWidth + 2); viewer->fieldWidth = boxWidth - 2; if (buttonCount > 0) { viewer->viewSize = boxHeight - 4; } else { viewer->viewSize = boxHeight - 2; } /* Rejustify the x and y positions if we need to. */ alignxy (cdkscreen->window, &xpos, &ypos, boxWidth, boxHeight); /* Make the viewer window. */ viewer->win = newwin (boxHeight + !!shadow, boxWidth + !!shadow, ypos, xpos); /* Is the window null? */ if (viewer->win == 0) { /* Clean up any used memory. */ for (x=0; x < viewer->buttonCount; x++) { freeChtype (viewer->buttonLabel[x]); } free (viewer); /* Return a null pointer. */ return (0); } keypad (viewer->win, TRUE); leaveok (viewer->win, TRUE); /* Make the info window. */ viewer->infoWin = subwin (viewer->win, viewer->viewSize, viewer->fieldWidth, ypos + 1, xpos + 1); /* Make the button window. */ if (buttonCount > 0) { viewer->buttonWin = subwin (viewer->win, 1, boxWidth - 2, ypos + viewer->viewSize + 2, xpos + 1); } /* Set the rest of the variables */ ScreenOf(viewer) = cdkscreen; viewer->parent = cdkscreen->window; viewer->buttonCount = buttonCount; viewer->buttonHighlight = buttonHighlight; viewer->currentButton = 0; viewer->boxHeight = boxHeight; viewer->boxWidth = boxWidth - 2; viewer->exitType = vNEVER_ACTIVATED; ObjOf(viewer)->box = Box; viewer->shadow = shadow; viewer->currentTop = 0; viewer->length = 0; viewer->leftChar = 0; viewer->maxLeftChar = 0; viewer->maxTopLine = 0; viewer->characters = 0; viewer->infoSize = 0; viewer->showLineInfo = 1; viewer->titleLines = 0; viewer->ULChar = ACS_ULCORNER; viewer->URChar = ACS_URCORNER; viewer->LLChar = ACS_LLCORNER; viewer->LRChar = ACS_LRCORNER; viewer->HChar = ACS_HLINE; viewer->VChar = ACS_VLINE; viewer->BoxAttrib = A_NORMAL; /* Create the buttons. */ buttonAdj = (boxWidth - 2 - buttonWidth) / (buttonCount + 1); buttonPos = buttonAdj; for (x=0; x < buttonCount; x++) { viewer->buttonPos[x] = buttonPos; buttonPos += viewer->buttonLen[x] + buttonAdj; } /* Clean the key bindings. */ cleanCDKObjectBindings (vVIEWER, viewer); /* Register this baby. */ registerCDKObject (cdkscreen, vVIEWER, viewer); /* Return the viewer object. */ return (viewer); } /* * This function sets various attributes of the widget. */ int setCDKViewer (CDKVIEWER *viewer, char *title, char **info, int infoSize, chtype buttonHighlight, boolean attrInterp, boolean showLineInfo, boolean Box) { setCDKViewerTitle (viewer, title); setCDKViewerHighlight (viewer, buttonHighlight); setCDKViewerInfoLine (viewer, showLineInfo); setCDKViewerBox (viewer, Box); return setCDKViewerInfo (viewer, info, infoSize, attrInterp); } /* * This sets the title of the viewer. (A null title is allowed. * It just means that the viewer will not have a title when drawn.) */ void setCDKViewerTitle (CDKVIEWER *viewer, char *title) { char **temp; int x; /* Clean out the old title. */ if (viewer->titleLines > 0) { for (x=0; x < viewer->titleLines; x++) { freeChtype (viewer->title[x]); } delwin (viewer->titleWin); } /* Create the new title if there is one. */ if (title != 0) { temp = CDKsplitString (title, '\n'); viewer->titleLines = CDKcountStrings (temp); /* For each line in the title, convert from char * to chtype * */ for (x=0; x < viewer->titleLines; x++) { viewer->title[x] = char2Chtype (temp[x], &viewer->titleLen[x], &viewer->titlePos[x]); viewer->titlePos[x] = justifyString (viewer->boxWidth - 2, viewer->titleLen[x], viewer->titlePos[x]); } CDKfreeStrings(temp); } else { /* No title? Set the required variables. */ viewer->titleLines = 0; } /* Set the rest of the variables. */ if (viewer->buttonCount > 0) { viewer->viewSize = viewer->boxHeight - 4 - viewer->titleLines; } else { viewer->viewSize = viewer->boxHeight - 2 - viewer->titleLines; } if (viewer->titleLines > 0) { viewer->titleWin = subwin (viewer->win, viewer->titleLines, viewer->boxWidth - 2, getbegy (viewer->win) + 1, getbegx (viewer->win) + 1); } delwin (viewer->infoWin); viewer->infoWin = subwin (viewer->win, viewer->viewSize, viewer->fieldWidth, getbegy (viewer->win) + viewer->titleLines + 1, getbegx (viewer->win) + 1); } chtype **getCDKViewerTitle (CDKVIEWER *viewer) { return viewer->title; } /* * This function sets the contents of the viewer. */ int setCDKViewerInfo (CDKVIEWER *viewer, char **info, int infoSize, boolean interpret) { /* Declare local variables. */ char filename[512]; int widestLine = -1; int currentLine = 0; int x = 0; /* Clean out the old viewer info. (if there is any) */ for (x=0; x < viewer->infoSize; x++) { freeChtype (viewer->info[x]); viewer->info[x] = 0; } memset (filename, '\0', 512); /* Keep some semi-perinant info. */ viewer->interpret = interpret; /* Copy the information given. */ currentLine = 0; for (x=0; x < infoSize; x++) { if (info[x] == 0) { viewer->info[currentLine] = 0; viewer->infoLen[currentLine] = 0; viewer->infoPos[currentLine] = 0; currentLine++; } else { /* Check if we have a file link in this line. */ if (checkForLink (info[x], filename) == 1) { /* We have a link, open the file. */ char *fileContents[MAX_LINES], temp[256]; int fileLen = 0; int fileLine = 0; /* Open the file and put it into the viewer. */ fileLen = readFile (filename, fileContents, MAX_LINES); if (fileLen == -1) { int adj = 0; int len = 0; /* Could not open the file. */ #ifdef HAVE_START_COLOR sprintf (temp, "Link Failed: Could not open the file %s", filename); #else sprintf (temp, "Link Failed: Could not open the file %s", filename); #endif viewer->info[currentLine] = char2Chtype (temp, &len, &adj); viewer->infoPos[currentLine] = justifyString (viewer->boxWidth, len, adj); viewer->infoLen[currentLine] = len; widestLine = MAXIMUM (widestLine, viewer->infoLen[currentLine]); currentLine++; } else { /* For each line read, copy it into the viewer. */ for (fileLine=0; fileLine < fileLen ; fileLine++) { int len = (int)strlen (fileContents[fileLine]); int y; /* Init memory and clean it. */ viewer->info[currentLine] = (chtype *)malloc (sizeof(chtype) * (len + 3)); cleanChtype (viewer->info[currentLine], len + 3, '\0'); /* Copy from one to the other. */ for (y=0; y < len; y++) { viewer->info[currentLine][y] = fileContents[fileLine][y]; } viewer->infoLen[currentLine] = len; viewer->infoPos[currentLine] = 0; widestLine = MAXIMUM(widestLine, len); viewer->characters += len; freeChar (fileContents[fileLine]); currentLine++; } } } else { /* Did they ask for attribute interpretation? */ if (!viewer->interpret) { int len = (int)strlen (info[x]); int y; /* Init memory and clean it. */ viewer->info[currentLine] = (chtype *)malloc (sizeof(chtype) * (len + 3)); cleanChtype (viewer->info[currentLine], len + 3, '\0'); /* Copy from one to the other. */ for (y=0; y < len; y++) { viewer->info[currentLine][y] = info[x][y]; } viewer->infoLen[currentLine] = len; viewer->infoPos[currentLine] = 0; widestLine = MAXIMUM(widestLine, len); viewer->characters += len; currentLine++; } else { viewer->info[currentLine] = char2Chtype (info[x], &viewer->infoLen[currentLine], &viewer->infoPos[currentLine]); viewer->infoPos[currentLine] = justifyString (viewer->boxWidth, viewer->infoLen[currentLine], viewer->infoPos[currentLine]); widestLine = MAXIMUM(widestLine, viewer->infoLen[currentLine]); viewer->characters += viewer->infoLen[currentLine]; currentLine++; } } } } /* * Determine how many characters we can shift to the right * before all the items have been viewer off the screen. */ viewer->maxLeftChar = MAXIMUM (0, widestLine - viewer->boxWidth); /* Set up the needed vars for the viewer list. */ viewer->infoSize = currentLine; viewer->maxTopLine = MAXIMUM (0, viewer->infoSize - viewer->viewSize); return viewer->infoSize; } chtype **getCDKViewerInfo (CDKVIEWER *viewer, int *size) { (*size) = viewer->infoSize; return viewer->info; } /* * This function sets the highlight type of the buttons. */ void setCDKViewerHighlight (CDKVIEWER *viewer, chtype buttonHighlight) { viewer->buttonHighlight = buttonHighlight; } chtype getCDKViewerHighlight (CDKVIEWER *viewer) { return viewer->buttonHighlight; } /* * This sets whether or not you want to set the viewer info line. */ void setCDKViewerInfoLine (CDKVIEWER *viewer, boolean showLineInfo) { viewer->showLineInfo = showLineInfo; } boolean getCDKViewerInfoLine (CDKVIEWER *viewer) { return viewer->showLineInfo; } /* * This sets the widgets box attribute. */ void setCDKViewerBox (CDKVIEWER *viewer, boolean Box) { ObjOf(viewer)->box = Box; } boolean getCDKViewerBox (CDKVIEWER *viewer) { return ObjOf(viewer)->box; } /* * This function actually controls the viewer... */ int activateCDKViewer (CDKVIEWER *viewer, chtype *actions GCC_UNUSED) { /* Declare local variables. */ CDKLABEL *fileInfoLabel; char *fileInfo[10], temp[500]; chtype emptyString[256]; chtype input; int x, REFRESH; /* Create a string full of spaces. */ cleanChtype (emptyString, viewer->boxWidth-1, '\0'); cleanChtype (emptyString, viewer->boxWidth-3, ' '); /* Create the information about the file stats. */ sprintf (temp, " File Statistics "); fileInfo[0] = copyChar(temp); sprintf (temp, " "); fileInfo[1] = copyChar(temp); sprintf (temp, "Character Count: %-4d ", viewer->characters); fileInfo[2] = copyChar(temp); sprintf (temp, "Line Count : %-4d ", viewer->infoSize); fileInfo[3] = copyChar(temp); sprintf (temp, " "); fileInfo[4] = copyChar(temp); sprintf (temp, "Press Any Key To Continue."); fileInfo[5] = copyChar(temp); /* Set the current button. */ viewer->currentButton = 0; /* Draw the viewer list. */ drawCDKViewer (viewer, ObjOf(viewer)->box); /* Do this until KEY_RETURN is hit. */ for (;;) { /* Reset the refresh flag. */ REFRESH = FALSE; /* Get the user input. */ wrefresh (viewer->win); input = wgetch (viewer->win); if (! checkCDKObjectBind (vVIEWER, viewer, input)) { switch (input) { case KEY_TAB : case CDK_NEXT : if (viewer->buttonCount > 1) { if (viewer->currentButton == (viewer->buttonCount - 1)) { viewer->currentButton = 0; } else { viewer->currentButton++; } /* Redraw the buttons. */ drawCDKViewerButtons (viewer); } break; case CDK_PREV : if (viewer->buttonCount > 1) { if (viewer->currentButton == 0) { viewer->currentButton = viewer->buttonCount - 1; } else { viewer->currentButton--; } /* Redraw the buttons. */ drawCDKViewerButtons (viewer); } break; case KEY_UP : if (viewer->currentTop > 0) { viewer->currentTop--; REFRESH = TRUE; } else { Beep(); } break; case KEY_DOWN : if (viewer->currentTop < viewer->maxTopLine) { viewer->currentTop++; REFRESH = TRUE; } else { Beep(); } break; case KEY_RIGHT : if (viewer->leftChar < viewer->maxLeftChar) { viewer->leftChar++; REFRESH = TRUE; } else { Beep(); } break; case KEY_LEFT : if (viewer->leftChar > 0) { viewer->leftChar--; REFRESH = TRUE; } else { Beep(); } break; case KEY_PPAGE : case CONTROL('B') : case 'b' : case 'B' : if (viewer->currentTop > 0) { if ((viewer->currentTop - (viewer->viewSize-1)) > 0) { viewer->currentTop = viewer->currentTop - (viewer->viewSize - 1); } else { viewer->currentTop = 0; } REFRESH = TRUE; } else { Beep(); } break; case KEY_NPAGE : case CONTROL('F') : case ' ' : case 'f' : case 'F' : if (viewer->currentTop < viewer->maxTopLine) { if ((viewer->currentTop + viewer->viewSize) < viewer->maxTopLine) { viewer->currentTop = viewer->currentTop + (viewer->viewSize - 1); } else { viewer->currentTop = viewer->maxTopLine; } REFRESH = TRUE; } else { Beep(); } break; case KEY_HOME : case '|' : viewer->leftChar = 0; REFRESH = TRUE; break; case KEY_END : case '$' : viewer->leftChar = viewer->maxLeftChar; REFRESH = TRUE; break; case 'g' : case '1' : viewer->currentTop = 0; REFRESH = TRUE; break; case 'G' : viewer->currentTop = viewer->maxTopLine; REFRESH = TRUE; break; case 'L' : x = (int) ((viewer->infoSize + viewer->currentTop) / 2); if (x < viewer->maxTopLine) { viewer->currentTop = x; REFRESH = TRUE; } else { Beep(); } break; case 'l' : x = (int) (viewer->currentTop / 2); if (x >= 0) { viewer->currentTop = x; REFRESH = TRUE; } else { Beep(); } break; case '?' : SearchDirection = UP; getAndStorePattern (ScreenOf(viewer)); if (! searchForWord(viewer, SearchPattern, SearchDirection)) { sprintf (temp, "Pattern '%s' not found.", SearchPattern); popUpLabel (viewer, temp); } REFRESH = TRUE; break; case '/' : SearchDirection = DOWN; getAndStorePattern (ScreenOf(viewer)); if (! searchForWord(viewer, SearchPattern, SearchDirection)) { sprintf (temp, "Pattern '%s' not found.", SearchPattern); popUpLabel (viewer, temp); } REFRESH = TRUE; break; case 'n' : if (SearchPattern == 0) { popUpLabel (viewer, "There is no pattern in the buffer."); } else { if (! searchForWord(viewer, SearchPattern, SearchDirection)) { sprintf (temp, "Pattern '%s' not found.", SearchPattern); popUpLabel (viewer, temp); } } REFRESH = TRUE; break; case ':' : viewer->currentTop = jumpToLine (viewer); REFRESH = TRUE; break; case 'i' : case 's' : case 'S' : fileInfoLabel = newCDKLabel (ScreenOf(viewer), CENTER, CENTER, fileInfo, 6, TRUE, FALSE); drawCDKLabel (fileInfoLabel, TRUE); waitCDKLabel (fileInfoLabel, 0); destroyCDKLabel (fileInfoLabel); REFRESH = TRUE; break; case KEY_ESC : freeCharList (fileInfo, 6); viewer->exitType = vESCAPE_HIT; return -1; case KEY_RETURN : case KEY_ENTER : case KEY_CR : freeCharList (fileInfo, 6); viewer->exitType = vNORMAL; return viewer->currentButton; case CDK_REFRESH : eraseCDKScreen (ScreenOf(viewer)); refreshCDKScreen (ScreenOf(viewer)); break; default : Beep(); break; } } /* Do we need to redraw the screen??? */ if (REFRESH) { drawCDKViewerInfo (viewer); } } } /* * This searches the document looking for the given word. */ static void getAndStorePattern (CDKSCREEN *screen) { /* Declare local variables. */ CDKENTRY *getPattern = 0; char *temp = 0; char *info = 0; /* Check the direction. */ if (SearchDirection == UP) { temp = "Search Up : "; } else { temp = "Search Down: "; } /* Pop up the entry field. */ getPattern = newCDKEntry (screen, CENTER, CENTER, 0, temp, COLOR_PAIR(5)|A_BOLD, '.'|COLOR_PAIR(5)|A_BOLD, vMIXED, 10, 0, 256, TRUE, FALSE); /* Is there an old search pattern? */ if (SearchPattern != 0) { setCDKEntry (getPattern, SearchPattern, getPattern->min, getPattern->max, ObjOf(getPattern)->box); } freeChar (SearchPattern); /* Activate this baby. */ info = activateCDKEntry (getPattern, 0); /* Save the info. */ if ((info != 0) || (strlen (info) != 0)) { SearchPattern = copyChar (info); } /* Clean up. */ destroyCDKEntry (getPattern); } /* * This searches for the word and realigns the value on the screen. */ static int searchForWord (CDKVIEWER *viewer, char *pattern, int direction) { /* Declare local variables. */ int x, y, pos, len, plen; /* If the pattern is null then return. */ if (pattern == 0) { return(0); } plen = (int)strlen(pattern); /* Given the direction, start looking.... */ if (direction == DOWN) { /* Start looking from 'here' down. */ for (x = viewer->currentTop + 1; x < viewer->infoSize; x++) { /* * Start looking. If we find it, then set the value of * viewer->currentTop and possibly even leftChar... */ len = chlen (viewer->info[x]); pos = 0; for (y=0; y < len; y++) { /* We have to tear the attributes from the chtype. */ char plainChar = viewer->info[x][y] & A_CHARTEXT; /* We have found the word at this point. */ if (pos == plen) { viewer->currentTop = (x < viewer->maxTopLine ? x : viewer->maxTopLine); viewer->leftChar = (y < viewer->boxWidth ? 0 : viewer->maxLeftChar); return (1); } /* Keep trudging along. */ if (pattern[pos++] != plainChar) { pos = 0; } } } } else { /* Start looking from 'here' up. */ for (x = viewer->currentTop - 1; x >= 0; x--) { /* * Start looking. If we find it, then set the value of * viewer->currentTop and possibly even leftChar... */ len = chlen (viewer->info[x]); pos = 0; for (y=0; y < len; y++) { /* We have to tear the attributes from the chtype. */ char plainChar = viewer->info[x][y] & A_CHARTEXT; /* We have found the word at this point. */ if (pos == plen) { viewer->currentTop = x; viewer->leftChar = (y < viewer->boxWidth ? 0 : viewer->maxLeftChar); return (1); } /* Keep trudging along. */ if (pattern[pos++] != plainChar) { pos = 0; } } } } return(0); } /* * This allows us to 'jump' to a given line in the file. */ static int jumpToLine (CDKVIEWER *viewer) { /* Declare local variables. */ int line = 0; CDKSCALE * newline = newCDKScale (ScreenOf(viewer), CENTER, CENTER, "Jump To Line", "Line :", A_BOLD, 5, 0, 0, viewer->maxTopLine + 1, 1, 10, TRUE, TRUE); line = activateCDKScale (newline, 0); destroyCDKScale (newline); return ((line-1)); } /* * This pops a little message up on the screen. */ static void popUpLabel (CDKVIEWER *viewer, char *mesg) { /* Declare local variables. */ char *info[3]; CDKLABEL *label; /* Set up variables. */ info[0] = mesg; label = newCDKLabel (ScreenOf(viewer), CENTER, CENTER, info, 1, TRUE, FALSE); /* Draw the label and wait. */ drawCDKLabel (label, TRUE); waitCDKLabel (label, 0); /* Clean up. */ destroyCDKLabel (label); } /* * This moves the viewer field to the given location. */ static void _moveCDKViewer (CDKOBJS *object, int xplace, int yplace, boolean relative, boolean refresh_flag) { CDKVIEWER *viewer = (CDKVIEWER *)object; /* * If this is a relative move, then we will adjust where we want * to move to. */ if (relative) { xplace += getbegx(viewer->win); yplace += getbegy(viewer->win); } /* Adjust the window if we need to. */ alignxy (WindowOf(viewer), &xplace, &yplace, viewer->boxWidth, viewer->boxHeight); /* Move the window to the new location. */ moveCursesWindow(viewer->win, xplace, yplace); /* Redraw the window, if they asked for it. */ if (refresh_flag) { drawCDKViewer (viewer, ObjOf(viewer)->box); } } /* * This function draws the viewer widget. */ static void _drawCDKViewer (CDKOBJS *object, boolean Box) { CDKVIEWER *viewer = (CDKVIEWER *)object; int x; /* Box it if it was asked for. */ if (Box) { attrbox (viewer->win, viewer->ULChar, viewer->URChar, viewer->LLChar, viewer->LRChar, viewer->HChar, viewer->VChar, viewer->BoxAttrib, viewer->shadow); } if (viewer->titleLines > 0) { /* Redraw the title. */ for (x=0; x < viewer->titleLines; x++) { writeChtype (viewer->titleWin, viewer->titlePos[x], x, viewer->title[x], HORIZONTAL, 0, viewer->titleLen[x]); } wnoutrefresh (viewer->titleWin); } /* Draw the info in the viewer. */ drawCDKViewerInfo (viewer); } /* * This redraws the viewer buttons. */ static void drawCDKViewerButtons (CDKVIEWER *viewer) { /* Declare local variables. */ int x; if (viewer->buttonCount > 0) { for (x=0; x < viewer->buttonCount; x++) { if (x == viewer->currentButton) { writeChtypeAttrib (viewer->buttonWin, viewer->buttonPos[x], 0, viewer->buttonLabel[x], viewer->buttonHighlight, HORIZONTAL, 0, viewer->buttonLen[x]); } else { writeChtype (viewer->buttonWin, viewer->buttonPos[x], 0, viewer->buttonLabel[x], HORIZONTAL, 0, viewer->buttonLen[x]); } } wnoutrefresh (viewer->buttonWin); } wnoutrefresh (viewer->win); } /* * These functions set the drawing characters of the widget. */ void setCDKViewerULChar (CDKVIEWER *viewer, chtype character) { viewer->ULChar = character; } void setCDKViewerURChar (CDKVIEWER *viewer, chtype character) { viewer->URChar = character; } void setCDKViewerLLChar (CDKVIEWER *viewer, chtype character) { viewer->LLChar = character; } void setCDKViewerLRChar (CDKVIEWER *viewer, chtype character) { viewer->LRChar = character; } void setCDKViewerVerticalChar (CDKVIEWER *viewer, chtype character) { viewer->VChar = character; } void setCDKViewerHorizontalChar (CDKVIEWER *viewer, chtype character) { viewer->HChar = character; } void setCDKViewerBoxAttribute (CDKVIEWER *viewer, chtype character) { viewer->BoxAttrib = character; } /* * This sets the background color of the widget. */ void setCDKViewerBackgroundColor (CDKVIEWER *viewer, char *color) { chtype *holder = 0; int junk1, junk2; /* Make sure the color isn't null. */ if (color == 0) { return; } /* Convert the value of the environment variable to a chtype. */ holder = char2Chtype (color, &junk1, &junk2); /* Set the widgets background color. */ wbkgd (viewer->win, holder[0]); /* Clean up. */ freeChtype (holder); } /* * This function destroys the viewer widget. */ void destroyCDKViewer (CDKVIEWER *viewer) { /* Declare local variables. */ int x; /* Erase the object. */ eraseCDKViewer (viewer); /* Clear up the char pointers. */ for (x=0; x < viewer->titleLines; x++) { freeChtype (viewer->title[x]); } for (x=0; x < viewer->infoSize; x++) { freeChtype (viewer->info[x]); } for (x=0; x < viewer->buttonCount; x++) { freeChtype (viewer->buttonLabel[x]); } /* Clean up the windows. */ deleteCursesWindow (viewer->win); /* Unregister this object. */ unregisterCDKObject (vVIEWER, viewer); /* Finish cleaning up. */ free (viewer); } /* * This function erases the viewer widget from the screen. */ static void _eraseCDKViewer (CDKOBJS *object) { CDKVIEWER *viewer = (CDKVIEWER *)object; eraseCursesWindow (viewer->win); } /* * This draws the viewer info lines. */ static void drawCDKViewerInfo (CDKVIEWER *viewer) { /* Declare some local vars */ int infoAdjust = 0; char temp[256]; int screenPos, x; /* Clear the window. */ werase (viewer->infoWin); /* Draw in the current line at the top. */ if (viewer->showLineInfo == TRUE) { /* Set up the info line and draw it. */ if (viewer->infoSize != 0) { sprintf (temp, "%d/%d %2.0f%%", viewer->currentTop + 1, viewer->infoSize, (float)(viewer->currentTop + 1) / (float)viewer->infoSize * 100); } else { sprintf (temp, "%d/%d %2.0f%%", 0, 0, 0.0); } /* * The infoAdjust variable tells us if we have to shift down * one line because the person asked for the line X of Y line * at the top of the screen. We only want to set this to 1 if * they asked for the info line and there is no title, or if the * two items overlap. */ if (viewer->titleLines == 0 || viewer->titlePos[0] < (int)strlen(temp) + 2) { infoAdjust = 1; } writeChar (viewer->infoWin, 0, 0, temp, HORIZONTAL, 0, (int)strlen(temp)); } /* Redraw the list. */ for (x=0; x < viewer->viewSize - infoAdjust; x++) { if (x + viewer->currentTop >= viewer->infoSize) { break; } screenPos = viewer->infoPos[viewer->currentTop + x] - viewer->leftChar; if (screenPos >= 0) { writeChtype (viewer->infoWin, screenPos, x + infoAdjust, viewer->info[x + viewer->currentTop], HORIZONTAL, 0, viewer->infoLen[x + viewer->currentTop]); } else { writeChtype (viewer->infoWin, 0, x + infoAdjust, viewer->info[x + viewer->currentTop], HORIZONTAL, -screenPos, viewer->infoLen[x + viewer->currentTop]); } } /* Draw the separation line. */ if (viewer->buttonCount > 0) { mvwaddch (viewer->win, viewer->boxHeight-3, 0, ACS_LTEE | viewer->BoxAttrib); mvwhline (viewer->win, viewer->boxHeight-3, 1, viewer->HChar | viewer->BoxAttrib, viewer->boxWidth); mvwaddch (viewer->win, viewer->boxHeight-3, viewer->boxWidth+1, ACS_RTEE | viewer->BoxAttrib); } wnoutrefresh (viewer->infoWin); /* Draw the buttons. This will call refresh on the viewer win. */ drawCDKViewerButtons (viewer); }