lynx-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

lynx-dev [PATCH 2.8.3.dev10] Multiple views of visited links


From: Ilya Zakharevich
Subject: lynx-dev [PATCH 2.8.3.dev10] Multiple views of visited links
Date: Tue, 9 Nov 1999 03:19:10 -0500 (EST)

This patch enables 5 different views of the visited links:

  a) same as now (reverse sorted by last visit);
  b) ibid not-reversed;
  c) sorted by first visit;
  d) ibid reversed;
  e) tree view.

The punch line is, of course, 'e'.  Tree is organized by "referer" of
the first visit.  It is somewhat similar to what WebExplorer was
doing.

Note that one could code 2 more views (backtrace and reversed
backtrace) and join HISTORY and VISITEDLINKS pages into one.

Since this is against 2.8.3.dev10, and there is a small patch for
LYMainloop.c, there might be conflicts with the current version.

Sorry, but I did 'diff' in a wrong directory, so the patch should be
-p1 in ./src directory.

Enjoy,
Ilya

P.S.  Tested for a couple of days, but I did not visit a lot of places...
      Before this tree-view-only version was tested for a month.

--- ./LYHistory.c.orig  Wed Sep 29 06:40:38 1999
+++ ./LYHistory.c       Sat Nov  6 19:30:58 1999
@@ -25,6 +25,14 @@
 #include <LYLeaks.h>
 
 PUBLIC HTList * Visited_Links = NULL;  /* List of safe popped docs. */
+PUBLIC int Visited_Links_As = VISITED_LINKS_AS_TREE;
+PRIVATE VisitedLink *PrevVisitedLink = NULL;       /* NULL on auxillary */
+PRIVATE VisitedLink *PrevActiveVisitedLink = NULL;  /* Last non-auxillary */
+PRIVATE VisitedLink Latest_first;
+PRIVATE VisitedLink Latest_last;
+PRIVATE VisitedLink *Latest_tree;
+PRIVATE VisitedLink *First_tree;
+PRIVATE VisitedLink *Last_by_first;
 
 #ifdef LY_FIND_LEAKS
 /*
@@ -35,6 +43,8 @@ PRIVATE void Visited_Links_free NOARGS
     VisitedLink *vl;
     HTList *cur = Visited_Links;
 
+    PrevVisitedLink = NULL;
+    PrevActiveVisitedLink = NULL;
     if (!cur)
        return;
 
@@ -45,6 +55,9 @@ PRIVATE void Visited_Links_free NOARGS
     }
     HTList_delete(Visited_Links);
     Visited_Links = NULL;
+    Latest_last.prev_latest = &Latest_first;
+    Latest_first.next_latest = &Latest_last;
+    Last_by_first = Latest_tree = First_tree = 0;
     return;
 }
 #endif /* LY_FIND_LEAKS */
@@ -57,11 +70,13 @@ PUBLIC void LYAddVisitedLink ARGS1(
        document *,     doc)
 {
     VisitedLink *new;
-    VisitedLink *old;
     HTList *cur;
+    char *title = (doc->title ? doc->title : NO_TITLE);
 
-    if (!(doc->address && *doc->address))
+    if (!(doc->address && *doc->address)) {
+       PrevVisitedLink = NULL;
        return;
+    }
 
     /*
      * Exclude POST or HEAD replies, and bookmark, menu
@@ -70,61 +85,115 @@ PUBLIC void LYAddVisitedLink ARGS1(
     if (doc->post_data || doc->isHEAD || doc->bookmark ||
        (/* special url or a temp file */
         (!strncmp(doc->address, "LYNX", 4) ||
-         !strncmp(doc->address, "file://localhost/", 17))
-        && (
-       !strcmp((doc->title ? doc->title : ""), HISTORY_PAGE_TITLE) ||
-       !strcmp((doc->title ? doc->title : ""), PRINT_OPTIONS_TITLE) ||
-       !strcmp((doc->title ? doc->title : ""), DOWNLOAD_OPTIONS_TITLE) ||
-       !strcmp((doc->title ? doc->title : ""), OPTIONS_TITLE) ||
+         !strncmp(doc->address, "file://localhost/", 17)))) {
+       int related = 1;        /* First approximation only */
+
+       if (    !strcmp(title, HISTORY_PAGE_TITLE) ||
+               !strcmp(title, VISITED_LINKS_TITLE) ||
+               !strcmp(title, SHOWINFO_TITLE) ||
+               !strcmp(title, STATUSLINES_TITLE) ||
+                       (related = 0)   ||
 #ifdef DIRED_SUPPORT
-       !strcmp((doc->title ? doc->title : ""), DIRED_MENU_TITLE) ||
-       !strcmp((doc->title ? doc->title : ""), UPLOAD_OPTIONS_TITLE) ||
-       !strcmp((doc->title ? doc->title : ""), PERMIT_OPTIONS_TITLE) ||
+               !strcmp(title, DIRED_MENU_TITLE) ||
+               !strcmp(title, UPLOAD_OPTIONS_TITLE) ||
+               !strcmp(title, PERMIT_OPTIONS_TITLE) ||
 #endif /* DIRED_SUPPORT */
-       !strcmp((doc->title ? doc->title : ""), CURRENT_KEYMAP_TITLE) ||
-       !strcmp((doc->title ? doc->title : ""), LIST_PAGE_TITLE) ||
+               !strcmp(title, PRINT_OPTIONS_TITLE) ||
+               !strcmp(title, DOWNLOAD_OPTIONS_TITLE) ||
+               !strcmp(title, OPTIONS_TITLE) ||
+               !strcmp(title, CURRENT_KEYMAP_TITLE) ||
+               !strcmp(title, LIST_PAGE_TITLE) ||
 #ifdef EXP_ADDRLIST_PAGE
-       !strcmp((doc->title ? doc->title : ""), ADDRLIST_PAGE_TITLE) ||
+               !strcmp(title, ADDRLIST_PAGE_TITLE) ||
 #endif
-       !strcmp((doc->title ? doc->title : ""), SHOWINFO_TITLE) ||
-       !strcmp((doc->title ? doc->title : ""), STATUSLINES_TITLE) ||
-       !strcmp((doc->title ? doc->title : ""), CONFIG_DEF_TITLE) ||
-       !strcmp((doc->title ? doc->title : ""), LYNXCFG_TITLE) ||
-       !strcmp((doc->title ? doc->title : ""), COOKIE_JAR_TITLE) ||
-       !strcmp((doc->title ? doc->title : ""), VISITED_LINKS_TITLE) ||
-       !strcmp((doc->title ? doc->title : ""), LYNX_TRACELOG_TITLE)))) {
-       return;
+               !strcmp(title, CONFIG_DEF_TITLE) ||
+               !strcmp(title, LYNXCFG_TITLE) ||
+               !strcmp(title, COOKIE_JAR_TITLE) ||
+               !strcmp(title, LYNX_TRACELOG_TITLE)     ) {
+           if (!related)
+               PrevVisitedLink = NULL;
+           return;
+       }
     }
 
-    if ((new = (VisitedLink *)calloc(1, sizeof(*new))) == NULL)
-       outofmem(__FILE__, "LYAddVisitedLink");
-    StrAllocCopy(new->address, doc->address);
-    StrAllocCopy(new->title, (doc->title ? doc->title : NO_TITLE));
-
     if (!Visited_Links) {
        Visited_Links = HTList_new();
 #ifdef LY_FIND_LEAKS
        atexit(Visited_Links_free);
-#endif
-       HTList_addObject(Visited_Links, new);
-       return;
+#endif       
+       Latest_last.prev_latest = &Latest_first;
+       Latest_first.next_latest = &Latest_last;
+       Latest_last.next_latest = NULL;         /* Find bugs quick! */
+       Latest_first.prev_latest = NULL;
+       Last_by_first = Latest_tree = First_tree = NULL;
     }
 
     cur = Visited_Links;
-    while (NULL != (old = (VisitedLink *)HTList_nextObject(cur))) {
-       if (!strcmp((old->address ? old->address : ""),
-                   (new->address ? new->address : ""))) {
-           if (!(new->title && *new->title) && old->title) {
-               StrAllocCopy(new->title, old->title);
-           }
-           FREE(old->address);
-           FREE(old->title);
-           HTList_removeObject(Visited_Links, old);
-           FREE(old);
-           break;
+    while (NULL != (new = (VisitedLink *)HTList_nextObject(cur))) {
+       if (!strcmp((new->address ? new->address : ""),
+                   (doc->address ? doc->address : ""))) {
+           PrevVisitedLink = PrevActiveVisitedLink = new;
+           /* Already visited.  Update the last-visited info. */
+           if (new->next_latest == &Latest_last)       /* optimization */
+               return;
+
+           /* Remove from "latest" chain */
+           new->prev_latest->next_latest = new->next_latest;
+           new->next_latest->prev_latest = new->prev_latest;
+
+           /* Insert at the end of the "latest" chain */
+           Latest_last.prev_latest->next_latest = new;
+           new->prev_latest = Latest_last.prev_latest;
+           new->next_latest = &Latest_last;
+           Latest_last.prev_latest = new;
+           return;
        }
     }
-    HTList_addObject(Visited_Links, new);
+
+    if ((new = (VisitedLink *)calloc(1, sizeof(*new))) == NULL)
+       outofmem(__FILE__, "LYAddVisitedLink");
+    StrAllocCopy(new->address, doc->address);
+    StrAllocCopy(new->title, title);
+
+    /* First-visited chain */
+    HTList_appendObject(Visited_Links, new);   /* At end */
+    new->prev_first = Last_by_first;
+    Last_by_first = new;
+
+    /* Tree structure */
+    if (PrevVisitedLink) {
+       VisitedLink *a = PrevVisitedLink;
+       VisitedLink *b = a->next_tree;
+       int l = PrevVisitedLink->level;
+
+       /* Find last on the deeper levels */
+       while (b && b->level > l)
+           a = b, b = b->next_tree;
+
+       if (a->next_tree)
+           a->next_tree->prev_tree = new;
+       new->prev_tree = a;
+       new->next_tree = a->next_tree;
+        a->next_tree = new;
+
+       new->level = PrevVisitedLink->level + 1;
+    } else {
+       if (Latest_tree)
+           Latest_tree->next_tree = new;
+       new->prev_tree = Latest_tree;
+       new->level = 0;
+       new->next_tree = NULL;
+    }
+    PrevVisitedLink = PrevActiveVisitedLink = new;
+    Latest_tree = new;
+    if (!First_tree)
+       First_tree = new;
+
+    /* "latest" chain */
+    Latest_last.prev_latest->next_latest = new;
+    new->prev_latest = Latest_last.prev_latest;
+    new->next_latest = &Latest_last;
+    Latest_last.prev_latest = new;
 
     return;
 }
@@ -556,8 +625,8 @@ PUBLIC BOOLEAN historytarget ARGS1(
 }
 
 /*
- *  This procedure outputs the Visited Links
- *  list into a temporary file. - FM
+ *  This procedure outputs the Visited Links list into a temporary file. - FM
+ *  Returns links's number to make active (1-based), or 0 if not required.
  */
 PUBLIC int LYShowVisitedLinks ARGS1(
        char **,        newfile)
@@ -565,10 +634,13 @@ PUBLIC int LYShowVisitedLinks ARGS1(
     static char tempfile[LY_MAXPATH] = "\0";
     char *Title = NULL;
     char *Address = NULL;
-    int x;
+    int x, tot;
     FILE *fp0;
     VisitedLink *vl;
     HTList *cur = Visited_Links;
+    int offset;
+    int ret = 0;
+    char *arrow, *post_arrow;
 
     if (!cur)
        return(-1);
@@ -591,16 +663,78 @@ PUBLIC int LYShowVisitedLinks ARGS1(
 
     BeginInternalPage(fp0, VISITED_LINKS_TITLE, VISITED_LINKS_HELP);
 
+    fprintf(fp0, "<form action=\"LYNXOPTIONS:\" method=\"post\">\n");
+    fprintf(fp0, "<select name=\"visited_pages_type\">\n");
+    fprintf(fp0, " <option value=\"first_visited\" %s>Sort By First Visited\n",
+                (Visited_Links_As == VISITED_LINKS_AS_FIRST_V ? "selected" : 
""));
+    fprintf(fp0, " <option value=\"first_visited_reversed\" %s>Reverse Sort By 
First Visited\n",
+                (Visited_Links_As == 
(VISITED_LINKS_AS_FIRST_V|VISITED_LINKS_REVERSE) ? "selected" : ""));
+    fprintf(fp0, " <option value=\"visit_tree\" %s>View As Visit Tree\n",
+                (Visited_Links_As == VISITED_LINKS_AS_TREE ? "selected" : ""));
+    fprintf(fp0, " <option value=\"last_visited\" %s>Sort By Last Visited\n",
+                (Visited_Links_As == VISITED_LINKS_AS_LATEST ? "selected" : 
""));
+    fprintf(fp0, " <option value=\"last_visited_reversed\" %s>Reverse Sort By 
Last Visited\n",
+                (Visited_Links_As == 
(VISITED_LINKS_AS_LATEST|VISITED_LINKS_REVERSE)
+                  ? "selected" : ""));
+    fprintf(fp0, "</select>\n");
+    fprintf(fp0, "<input type=\"submit\" value=\"Accept Changes\">\n");
+    fprintf(fp0, "</form>\n");
+    fprintf(fp0, "<P>\n");
+
     fprintf(fp0, "<pre>\n");
     fprintf(fp0, "<em>%s</em>\n",
            gettext("You visited (POSTs, bookmark, menu and list files 
excluded):"));
-    x = HTList_count(Visited_Links);
-    while (NULL != (vl = (VisitedLink *)HTList_nextObject(cur))) {
+    if (Visited_Links_As & VISITED_LINKS_REVERSE)
+       tot = x = HTList_count(Visited_Links);
+    else
+       x = -1;
+       
+    if (Visited_Links_As & VISITED_LINKS_AS_TREE) {
+       vl = First_tree;
+    } else if (Visited_Links_As & VISITED_LINKS_AS_LATEST) {
+       if (Visited_Links_As & VISITED_LINKS_REVERSE)
+           vl = Latest_last.prev_latest;
+       else
+           vl = Latest_first.next_latest;
+       if (vl == &Latest_last || vl == &Latest_first)
+           vl = NULL;
+    } else {
+       if (Visited_Links_As & VISITED_LINKS_REVERSE)
+           vl = Last_by_first;
+       else
+           vl = (VisitedLink *)HTList_nextObject(cur);
+    }
+    while (NULL != vl) {
        /*
         *  The number of the document (most recent highest),
         *  its title in a link, and its address. - FM
         */
-       x--;
+       post_arrow = arrow = "";
+       if (Visited_Links_As & VISITED_LINKS_REVERSE)
+           x--;
+       else
+           x++;
+       if (vl == PrevActiveVisitedLink) {
+           if (Visited_Links_As & VISITED_LINKS_REVERSE)
+               ret = tot - x + 2;
+           else
+               ret = x + 3;
+       }
+       if (vl == PrevActiveVisitedLink) {
+           post_arrow = "<A NAME=current></A>";
+           /* Otherwise levels 0 and 1 look the same when with arrow: */
+           arrow = (vl->level && (Visited_Links_As & VISITED_LINKS_AS_TREE))
+                        ? "==>" : "=>";
+           StrAllocCat(*newfile, "#current");
+       }
+       if (Visited_Links_As & VISITED_LINKS_AS_TREE) {
+           offset = 2 * vl->level;
+           if (offset > 24)
+               offset = (offset + 24)/2;
+           if (offset > LYcols * 3/4)
+               offset = LYcols * 3/4;
+       } else
+           offset = (x > 99 ? 0 : x < 10 ? 2 : 1);
        if (vl->title != NULL && *vl->title != '\0') {
            StrAllocCopy(Title, vl->title);
            LYEntify(&Title, TRUE);
@@ -615,13 +749,13 @@ PUBLIC int LYShowVisitedLinks ARGS1(
            StrAllocCopy(Address, vl->address);
            LYEntify(&Address, FALSE);
            fprintf(fp0,
-                   "%s<em>%d</em>. <tab id=t%d><a href=\"%s\">%s</a>\n",
-                   (x > 99 ? "" : x < 10 ? "  " : " "),
+                   "%-*s%s<em>%d</em>. <tab id=t%d><a href=\"%s\">%s</a>\n",
+                   offset, arrow, post_arrow,
                    x, x, Address, Title);
        } else {
            fprintf(fp0,
-                   "%s<em>%d</em>. <tab id=t%d><em>%s</em>\n",
-                   (x > 99 ? "" : x < 10 ? "  " : " "),
+                   "%-*s%s<em>%d</em>. <tab id=t%d><em>%s</em>\n",
+                   offset, arrow, post_arrow,
                    x, x, Title);
        }
        if (Address != NULL) {
@@ -630,6 +764,21 @@ PUBLIC int LYShowVisitedLinks ARGS1(
        }
        fprintf(fp0, "<tab to=t%d>%s\n", x,
                     ((Address != NULL) ? Address : gettext("(no address)")));
+       if (Visited_Links_As & VISITED_LINKS_AS_TREE)
+           vl = vl->next_tree;
+       else if (Visited_Links_As & VISITED_LINKS_AS_LATEST) {
+           if (Visited_Links_As & VISITED_LINKS_REVERSE)
+               vl = vl->prev_latest;
+           else
+               vl = vl->next_latest;
+           if (vl == &Latest_last || vl == &Latest_first)
+               vl = NULL;
+       } else {
+           if (Visited_Links_As & VISITED_LINKS_REVERSE)
+               vl = vl->prev_first;
+           else
+               vl = (VisitedLink *)HTList_nextObject(cur);
+       }
     }
     fprintf(fp0,"</pre>\n");
     EndInternalPage(fp0);
@@ -637,7 +786,7 @@ PUBLIC int LYShowVisitedLinks ARGS1(
     LYCloseTempFP(fp0);
     FREE(Title);
     FREE(Address);
-    return(0);
+    return(ret);
 }
 
 
--- ./LYStructs.h.orig  Thu Dec  3 13:28:20 1998
+++ ./LYStructs.h       Sat Nov  6 19:26:50 1999
@@ -60,9 +60,22 @@ typedef struct _histstruct {
                                   "internal links", otherwise -1 */
 } histstruct;
 
+extern int Visited_Links_As;
+
+#define VISITED_LINKS_AS_FIRST_V 0
+#define VISITED_LINKS_AS_TREE 1
+#define VISITED_LINKS_AS_LATEST 2
+#define VISITED_LINKS_REVERSE 4
+
 typedef struct _VisitedLink {
     char * title;
     char * address;
+    int level;
+    struct _VisitedLink *next_tree;
+    struct _VisitedLink *prev_tree;
+    struct _VisitedLink *prev_latest;
+    struct _VisitedLink *next_latest;
+    struct _VisitedLink *prev_first;
 } VisitedLink;
 
 extern histstruct history[MAXHIST];
--- ./LYOptions.c-pre   Wed Sep 29 06:40:38 1999
+++ ./LYOptions.c       Sat Nov  6 19:30:34 1999
@@ -3334,8 +3334,20 @@ static OptValues user_mode_values[] = {
        { INTERMEDIATE_MODE,    "Intermediate", "Intermediate" },
        { ADVANCED_MODE,        "Advanced",     "Advanced" },
        { 0, 0, 0 }};
+
 static char * vi_keys_string           = "vi_keys";
 
+static char * visited_pages_type_string        = "visited_pages_type";
+static OptValues visited_pages_type_values[] = {
+       { VISITED_LINKS_AS_FIRST_V, "By First Visit",   "first_visited" },
+       { VISITED_LINKS_AS_FIRST_V | VISITED_LINKS_REVERSE,
+                   "By First Visit Reversed",  "first_visited_reversed" },
+       { VISITED_LINKS_AS_TREE,    "As Visit Tree",    "visit_tree" },
+       { VISITED_LINKS_AS_LATEST,  "By Last Visit",    "last_visited" },
+       { VISITED_LINKS_AS_LATEST | VISITED_LINKS_REVERSE,
+                   "By Last Visit Reversed",   "last_visited_reversed" },
+       { 0, 0, 0 }};
+
 /*
  * Document Layout
  */
@@ -3785,6 +3797,10 @@ PUBLIC int postoptions ARGS1(
                display_lines = LYlines-2;
            }
        }
+
+       /* Type of visited pages page: SELECT */
+       if (!strcmp(data[i].tag, visited_pages_type_string))
+          GetOptValues(visited_pages_type_values, data[i].value, 
&Visited_Links_As);
 
        /* Show Images: SELECT */
        if (!strcmp(data[i].tag, images_string)) {
--- ./LYMainLoop.c.orig Wed Sep 29 06:40:38 1999
+++ ./LYMainLoop.c      Wed Oct 20 03:39:14 1999
@@ -532,6 +532,7 @@ int mainloop NOARGS
     char *temp = NULL;
     BOOLEAN ForcePush = FALSE;
     BOOLEAN override_LYresubmit_posts = FALSE;
+    BOOLEAN newdoc_link_is_absolute = FALSE;
     unsigned int len;
     int i;
     int n;
@@ -1604,6 +1605,17 @@ try_again:
                }
            }
 
+           /*
+            *  If the request is to highlight a link which is counted
+            *  from the start of document, correct the link number:
+            */
+           if (newdoc_link_is_absolute) {
+               newdoc_link_is_absolute = FALSE;
+               if (curdoc.line > 1)
+                   newdoc.link -= HText_LinksInLines(HTMainText, 1,
+                                                     curdoc.line - 1);
+           }
+
            if (arrowup) {
                /*
                 *  arrowup is set if we just came up from
@@ -5402,7 +5414,8 @@ if (!LYUseFormsOptions) {
            /*
             *  Print visited links page to file.
             */
-           if (LYShowVisitedLinks(&newdoc.address) < 0) {
+           c = LYShowVisitedLinks(&newdoc.address);
+           if (c < 0) {
                HTUserMsg(VISITED_LINKS_EMPTY);
                break;
            }
@@ -5414,6 +5427,11 @@ if (!LYUseFormsOptions) {
            newdoc.safe = FALSE;
            newdoc.internal_link = FALSE;
            refresh_screen = TRUE;
+           if (c > 0) {
+               /* Select a correct link. */
+               newdoc_link_is_absolute = TRUE;
+               newdoc.link = c - 1;
+           }
            if (LYValidate || check_realm) {
                LYPermitURL = TRUE;
                StrAllocCopy(lynxlinksfile, newdoc.address);

reply via email to

[Prev in Thread] Current Thread [Next in Thread]