Annotation of libwww/Library/src/HTHist.c, revision 2.9

2.1       frystyk     1: /*                                                                 HTHist.c
                      2: **     NAVIGATION MANAGER
                      3: **
2.2       frystyk     4: **     (c) COPYRIGHT MIT 1995.
2.1       frystyk     5: **     Please first read the full copyright statement in the file COPYRIGH.
2.9     ! frystyk     6: **     @(#) $Id: HTHist.c,v 2.8 1996/04/12 17:47:12 frystyk Exp $
2.3       frystyk     7: **
2.4       frystyk     8: **     The history manager for the Library. This module is not called any
                      9: **     where in the Library so if the application does not call it, it is
                     10: **     not linked in at all.
2.1       frystyk    11: */
                     12: 
                     13: /* Library include files */
2.9     ! frystyk    14: #include "wwwsys.h"
2.1       frystyk    15: #include "HTUtils.h"
2.3       frystyk    16: #include "HTAnchor.h"
                     17: #include "HTHist.h"                                     /* Implemented here */
2.1       frystyk    18: 
2.4       frystyk    19: struct _HTHistory {
                     20:     HTList *   alist;                                    /* List of anchors */
                     21:     int                pos;           /* Current position in list. 1 is home anchor */
                     22: };
2.1       frystyk    23: 
2.3       frystyk    24: /* ------------------------------------------------------------------------- */
2.1       frystyk    25: 
2.4       frystyk    26: /*     Create a new History List
                     27: **     -------------------------
                     28: **      Creates a new history list and returns a handle to it. There can be 
                     29: **     multiple history lists - for example one for each open window in
                     30: **     an application.
                     31: **     Returns HTHistory object if OK, else NULL
                     32: */
2.5       frystyk    33: PUBLIC HTHistory *HTHistory_new (void)
2.4       frystyk    34: {
2.6       frystyk    35:     HTHistory *element;
                     36:     if ((element = (HTHistory  *) HT_CALLOC(1, (sizeof(HTHistory)))) == NULL)
                     37:         HT_OUTOFMEM("HTHistory_new");
2.4       frystyk    38:     element->alist = HTList_new();
                     39:     return element;
                     40: }
                     41: 
                     42: /*     Delete a History list
                     43: **     ---------------------
                     44: **      Deletes the history list.
2.3       frystyk    45: **     Returns YES if OK, else NO
2.1       frystyk    46: */
2.5       frystyk    47: PUBLIC BOOL HTHistory_delete (HTHistory * hist)
2.1       frystyk    48: {
2.4       frystyk    49:     if (hist) {
                     50:        HTList_delete(hist->alist);
2.6       frystyk    51:        HT_FREE(hist);
2.4       frystyk    52:        return YES;
2.3       frystyk    53:     }
                     54:     return NO;
2.1       frystyk    55: }
                     56: 
2.4       frystyk    57: /*     Record an entry in a list
                     58: **     -------------------------
                     59: **      Registers the object in the linear list. The first entry is the
                     60: **     home page. No check is done for duplicates.
                     61: **     Returns YES if ok, else NO
2.1       frystyk    62: */
2.5       frystyk    63: PUBLIC BOOL HTHistory_record (HTHistory * hist, HTAnchor * cur)
2.1       frystyk    64: {
2.4       frystyk    65:     return (hist && cur && HTList_addObject(hist->alist, cur) && hist->pos++);
2.1       frystyk    66: }
                     67: 
2.4       frystyk    68: /*     Replace list with new element
                     69: **     -----------------------------
                     70: **      Inserts the new element at the current position and removes all any
                     71: **     old list from current position. For example if c is cur pos
                     72: **             before: a b c d e
                     73: **             after : a b f
                     74: **     Returns YES if ok, else NO
2.3       frystyk    75: */
2.5       frystyk    76: PUBLIC BOOL HTHistory_replace (HTHistory * hist, HTAnchor * cur)
2.4       frystyk    77: {
                     78:     if (hist && cur) {
                     79:        HTHistory_removeFrom(hist, hist->pos);
                     80:        HTHistory_record(hist, cur);
2.3       frystyk    81:     }
                     82:     return NO;
2.1       frystyk    83: }
                     84: 
2.4       frystyk    85: /*     Delete last entry in a list
                     86: **     ---------------------------
                     87: **      Deletes the last object from the list
2.3       frystyk    88: **     Returns YES if OK, else NO
                     89: */
2.5       frystyk    90: PUBLIC BOOL HTHistory_removeLast (HTHistory * hist)
2.4       frystyk    91: {
                     92:     return (hist && HTList_removeLastObject(hist->alist) && hist->pos--);
2.3       frystyk    93: }
2.1       frystyk    94: 
2.4       frystyk    95: /*     Remove the History list from position
                     96: **     ------------------------------------
                     97: **      Deletes the history list FROM the entry at position 'cur' (excluded).
                     98: **     Home page has position 1.
2.3       frystyk    99: **     Returns YES if OK, else NO
                    100: */
2.5       frystyk   101: PUBLIC BOOL HTHistory_removeFrom  (HTHistory * hist, int pos)
2.1       frystyk   102: {
2.4       frystyk   103:     if (hist && pos>=0) {
                    104:        int cnt = HTList_count(hist->alist) - pos;
                    105:        while (cnt-->0 && HTList_removeLastObject(hist->alist));
                    106:        if (hist->pos > pos)
                    107:            hist->pos = pos;
2.3       frystyk   108:        return YES;
2.1       frystyk   109:     }
2.3       frystyk   110:     return NO;
2.1       frystyk   111: }
                    112: 
2.3       frystyk   113: /*     Number of elements stored
                    114: **             -------------------------
                    115: **     Returns the size of the history list or -1 if none.
                    116: */
2.5       frystyk   117: PUBLIC int HTHistory_count (HTHistory * hist)
2.4       frystyk   118: {
                    119:     return (hist ? HTList_count(hist->alist) : -1);
                    120: }
                    121: 
                    122: /*     Current Location
                    123: **             ----------------
                    124: **     Returns the current position or -1
                    125: */
2.5       frystyk   126: PUBLIC int HTHistory_position (HTHistory * hist)
2.1       frystyk   127: {
2.4       frystyk   128:     return (hist ? hist->pos : -1);
2.1       frystyk   129: }
                    130: 
2.3       frystyk   131: /* ------------------------------------------------------------------------- */
                    132: /*                                 NAVIGATION                               */
                    133: /* ------------------------------------------------------------------------- */
2.1       frystyk   134: 
2.3       frystyk   135: /*     Find and re-register visited anchor
                    136: **             -----------------------------------
2.4       frystyk   137: **     Finds already registered anchor at given position and registers it
2.3       frystyk   138: **     again EXCEPT if last entry. This allows for `circular' history lists
2.4       frystyk   139: **     with duplicate entries. Position 1 is the home anchor.
2.3       frystyk   140: */
2.5       frystyk   141: PUBLIC HTAnchor * HTHistory_recall (HTHistory * hist, int pos)
2.1       frystyk   142: {
2.3       frystyk   143:     HTAnchor *cur = NULL;
2.4       frystyk   144:     if (hist && pos > 0) {
                    145:        int len = HTList_count(hist->alist);
                    146:        if ((cur = (HTAnchor *) HTList_objectAt(hist->alist, len-pos))) {
                    147:            if (cur != HTList_lastObject (hist->alist)) {
                    148:                HTHistory_record(hist, cur);
                    149:            } else
                    150:                hist->pos = pos;
                    151:        }
                    152:     }
                    153:     return cur;
                    154: }
                    155: 
                    156: /*     Find Entry at position
                    157: **     ----------------------
                    158: **     Entry with the given index in the list (1 is the home page). Like
                    159: **     HTHistory_recall but without re-registration. Current position is
                    160: **     updated.
                    161: */
2.5       frystyk   162: PUBLIC HTAnchor * HTHistory_find (HTHistory * hist, int pos)
2.4       frystyk   163: {
                    164:     HTAnchor *cur = NULL;
                    165:     if (hist && pos > 0) {
                    166:        if ((cur = (HTAnchor *)
                    167:             (HTList_objectAt(hist->alist, HTList_count(hist->alist)-pos))))
                    168:            hist->pos = pos;
2.3       frystyk   169:     }
                    170:     return cur;
2.1       frystyk   171: }
                    172: 
2.4       frystyk   173: /*     List Entry at position
                    174: **     ----------------------
2.3       frystyk   175: **     Entry with the given index in the list (1 is the home page). Like
2.4       frystyk   176: **     HTHistory_find but current position is NOT updated.
2.1       frystyk   177: */
2.5       frystyk   178: PUBLIC HTAnchor * HTHistory_list (HTHistory * hist, int pos)
2.3       frystyk   179: {
2.4       frystyk   180:     return (hist ? (HTAnchor *)
                    181:            (HTList_objectAt(hist->alist, HTList_count(hist->alist)-pos)) :
2.3       frystyk   182:            NULL);
                    183: }
2.1       frystyk   184: 
2.3       frystyk   185: /*     Can we back in history
                    186: **     ----------------------
                    187: **     Returns YES if the current anchor is not the first entry (home page)
                    188: */
2.5       frystyk   189: PUBLIC BOOL HTHistory_canBacktrack (HTHistory * hist)
2.3       frystyk   190: {
2.4       frystyk   191:     return ((hist && hist->pos > 1) ? YES : NO);
2.3       frystyk   192: }
2.1       frystyk   193: 
2.3       frystyk   194: /*
                    195: **     Backtrack with deletion
                    196: **     -----------------------
                    197: **     Returns the previous object and erases the last object. This does not
                    198: **     allow for 'forward' as we are always at the end of the list. If no
                    199: **     previous object exists, NULL is returned so that the application knows
                    200: **     that no previous object was found. See also HTHistory_back(). 
2.1       frystyk   201: */
2.5       frystyk   202: PUBLIC HTAnchor * HTHistory_backtrack (HTHistory * hist)
2.1       frystyk   203: {
2.4       frystyk   204:     if (HTHistory_canBacktrack(hist)) {
                    205:        HTHistory_removeLast(hist);
                    206:        return (HTAnchor *) HTList_lastObject(hist->alist);
2.1       frystyk   207:     }
2.3       frystyk   208:     return NULL;
2.1       frystyk   209: }
                    210: 
2.3       frystyk   211: /*
                    212: **     Backtrack without deletion
                    213: **     --------------------------
                    214: **     Returns the previos object but does not erase the last object. This
                    215: **     does not allow for 'forward'. If no previous object exists,  NULL is
                    216: **     returned so that the application knows that no previous object was
                    217: **     found. See also HTHistory_backtrack()
                    218: */
2.5       frystyk   219: PUBLIC HTAnchor * HTHistory_back (HTHistory * hist)
2.1       frystyk   220: {
2.4       frystyk   221:     if (HTHistory_canBacktrack(hist)) {        
                    222:        int pos = HTList_count(hist->alist) - (--hist->pos);
                    223:        return ((HTAnchor *) HTList_objectAt(hist->alist, pos));
2.3       frystyk   224:     }
                    225:     return NULL;
2.1       frystyk   226: }
                    227: 
2.3       frystyk   228: /*     Can we go forward
                    229: **     -----------------
                    230: **     Returns YES if the current anchor is not the last entry
2.1       frystyk   231: */
2.5       frystyk   232: PUBLIC BOOL HTHistory_canForward (HTHistory * hist)
2.3       frystyk   233: {
2.4       frystyk   234:     return ((hist && hist->pos < HTList_count(hist->alist)) ? YES : NO);
2.3       frystyk   235: }
2.1       frystyk   236: 
2.3       frystyk   237: /*
                    238: **     Forward
                    239: **     -------
                    240: **     Return the next object in the list or NULL if none
2.1       frystyk   241: */
2.5       frystyk   242: PUBLIC HTAnchor * HTHistory_forward (HTHistory * hist)
2.1       frystyk   243: {
2.4       frystyk   244:     if (HTHistory_canForward(hist)) {
                    245:        int pos = HTList_count(hist->alist) - (++hist->pos);
                    246:        return ((HTAnchor *) HTList_objectAt(hist->alist, pos));
2.3       frystyk   247:     }
                    248:     return NULL;
2.1       frystyk   249: }

Webmaster