From a772c51a1672e5dd7c9c70ee7e50cfa79e13b023 Mon Sep 17 00:00:00 2001 From: Fumitoshi UKAI Date: Tue, 5 Nov 2002 17:10:04 +0000 Subject: [w3m-dev 03372] tab browser * display.c (displayBuffer): add ny rootY offset by tab tab line (cursorDown): offset rootY (arrangeCursor): offset rootY * etc.c (columnSkip): offset rootY (lineSkip): offset rootY (currentLineSkip): offset rootY * file.c (HTMLlineproc2body): ATTR_TARGET * fm.h (MapArea): add target (Buffer): add rootY (TabBuffer): added (Currentbuf): comment out (Firstbuf): comment out (CurrentTab): added (FirstTab): added (LastTab): added (open_tab_blank): added (close_tab_back): added (nTab): added (TabCols): added (N_TAB): added (Currentbuf): CurrentTab->currentBuffer (Firstbuf): CurrentTab->firstBuffer * funcname.tab (CLOSE_TAB): added (NEW_TAB): added (NEXT_TAB): added (PREV_TAB): added (TAB_GOTO): added (TAB_GOTO_RELATIVE): added (TAB_LEFT): added (TAB_LINK): added (TAB_MENU): added (TAB_RIGHT): added * html.c (ALST_AREA): add ATTR_TARGET * image.c (showImageProgress): offset rootY * main.c (_newT): added (followTab): added (moveTab): added (check_target): added (MAIN): init tab related values buf => tab (nscroll): offset rootY (pgFore): offset rootY (pgBack): offset rootY (ctrCsrV): offset rootY (_movD): offset rootY (_movU): offset rootY (_goLine): offset rootY (_mark): offset rootY (followA): check target (_followForm): offset rootY (drawAnchorCursor0): offset rootY (drawAnchorCursor): offset rootY (backBf): check close_tab_back (follow_map): rewrite for tab, check target (posTab): added (process_mouse): tab operation offset rootY (deleteFiles): for all buffers in all tabs (newTab): added (newT): added (numTab): added (deleteTab): added (closeT): added (nextT): added (prevT): added (followTab): added (tabA): added (tabURL0): added (tabURL): added (tabrURL): added (moveTab): added (tabR): added (tabL): added * map.c (follow_map_menu): return MapArea (newMapArea): add target args * menu.c (SelTabMenu): added (SelTabV): added (initSelTabMenu): added (smChTab): added (smDelTab): added (MainMenuItem): add Select Tab on New Tab (popupMenu): add initSelTabMenu() offset rootY (mainMn): offset rootY (selMn): offset rootY (initSelectMenu): offset rootY (tabMn): added * proto.h (newT): added (closeT): added (nextT): added (prevT): added (tabA): added (tabURL): added (tabrURL): added (tabR): added (tabL): added (newTab): added (deleteTab): added (follow_map_menu): return MapArea (newMapArea): add target arg (tabMn): added * rc.c (CMT_OPEN_TAB_BLANK): added (CMT_CLOSE_TAB_BACK): added (open_tab_blank): added (close_tab_back): added * doc/README.func (CLOSE_TAB): added (NEW_TAB): added (NEXT_TAB): added (PREV_TAB): added (TAB_GOTO): added (TAB_GOTO_RELATIVE): added (TAB_LEFT): added (TAB_LINK): added (TAB_MENU): added (TAB_RIGHT): added * doc-jp/README.func: ditto doc/README.func From: Hironori SAKAMOTO --- main.c | 516 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 477 insertions(+), 39 deletions(-) (limited to 'main.c') diff --git a/main.c b/main.c index 5f0b299..1ea0f87 100644 --- a/main.c +++ b/main.c @@ -1,4 +1,4 @@ -/* $Id: main.c,v 1.117 2002/11/05 15:56:13 ukai Exp $ */ +/* $Id: main.c,v 1.118 2002/11/05 17:10:06 ukai Exp $ */ #define MAINPROGRAM #include "fm.h" #include @@ -90,6 +90,10 @@ void set_buffer_environ(Buffer *); static void _followForm(int); static void _goLine(char *); +static void _newT(void); +static void followTab(TabBuffer *tab); +static void moveTab(TabBuffer *t, TabBuffer *t2, int right); +static int check_target = TRUE; #define PREC_NUM (prec_num ? prec_num : 1) #define PREC_LIMIT 10000 static int searchKeyNum(void); @@ -707,8 +711,10 @@ MAIN(int argc, char **argv, char **envp) sock_init(); #endif - Firstbuf = NULL; - Currentbuf = NULL; + FirstTab = NULL; + LastTab = NULL; + nTab = 0; + CurrentTab = NULL; CurrentKey = -1; if (BookmarkFile == NULL) BookmarkFile = rcFile(BOOKMARK); @@ -879,8 +885,11 @@ MAIN(int argc, char **argv, char **envp) else if (newbuf == NO_BUFFER) continue; newbuf->search_header = search_header; - if (Currentbuf == NULL) + if (CurrentTab == NULL) { + FirstTab = LastTab = CurrentTab = newTab(); + nTab = 1; Firstbuf = Currentbuf = newbuf; + } else { Currentbuf->nextBuffer = newbuf; Currentbuf = newbuf; @@ -914,7 +923,7 @@ MAIN(int argc, char **argv, char **envp) w3m_exit(0); } - if (!Firstbuf || Firstbuf == NO_BUFFER) { + if (!FirstTab || !Firstbuf || Firstbuf == NO_BUFFER) { if (newbuf == NO_BUFFER) { if (fmInitialized) inputChar("Hit any key to quit w3m:"); @@ -1313,7 +1322,8 @@ nscroll(int n, int mode) } else { tlnum = Currentbuf->topLine->linenumber; - llnum = Currentbuf->topLine->linenumber + LASTLINE - 1; + llnum = Currentbuf->topLine->linenumber + LASTLINE - Currentbuf->rootY + - 1; #ifdef NEXTPAGE_TOPLINE if (nextpage_topline) diff_n = 0; @@ -1336,10 +1346,11 @@ pgFore(void) { #ifdef VI_PREC_NUM if (vi_prec_num) - nscroll(searchKeyNum() * (LASTLINE - 1), B_NORMAL); + nscroll(searchKeyNum() * (LASTLINE - Currentbuf->rootY - 1), B_NORMAL); else #endif - nscroll(prec_num ? searchKeyNum() : searchKeyNum() * (LASTLINE - 1), + nscroll(prec_num ? searchKeyNum() : searchKeyNum() + * (LASTLINE - Currentbuf->rootY - 1), prec_num ? B_SCROLL : B_NORMAL); } @@ -1349,10 +1360,11 @@ pgBack(void) { #ifdef VI_PREC_NUM if (vi_prec_num) - nscroll(-searchKeyNum() * (LASTLINE - 1), B_NORMAL); + nscroll(-searchKeyNum() * (LASTLINE - Currentbuf->rootY - 1), B_NORMAL); else #endif - nscroll(-(prec_num ? searchKeyNum() : searchKeyNum() * (LASTLINE - 1)), + nscroll(-(prec_num ? searchKeyNum() : searchKeyNum() + * (LASTLINE - Currentbuf->rootY - 1)), prec_num ? B_SCROLL : B_NORMAL); } @@ -1377,7 +1389,7 @@ ctrCsrV(void) int offsety; if (Currentbuf->firstLine == NULL) return; - offsety = LASTLINE / 2 - Currentbuf->cursorY; + offsety = (LASTLINE - Currentbuf->rootY) / 2 - Currentbuf->cursorY; if (offsety != 0) { #if 0 Currentbuf->currentLine = lineSkip(Currentbuf, @@ -1971,7 +1983,7 @@ _movD(int n) void movD(void) { - _movD((LASTLINE + 1) / 2); + _movD((LASTLINE - Currentbuf->rootY + 1) / 2); } void @@ -1995,7 +2007,7 @@ _movU(int n) void movU(void) { - _movU((LASTLINE + 1) / 2); + _movU((LASTLINE - Currentbuf->rootY + 1) / 2); } void @@ -2285,8 +2297,8 @@ _goLine(char *l) } else if (*l == '$') { Currentbuf->topLine = - lineSkip(Currentbuf, Currentbuf->lastLine, -(LASTLINE + 1) / 2, - TRUE); + lineSkip(Currentbuf, Currentbuf->lastLine, + -(LASTLINE - Currentbuf->rootY + 1) / 2, TRUE); Currentbuf->currentLine = Currentbuf->lastLine; } else @@ -2441,7 +2453,8 @@ _mark(void) return; l = Currentbuf->currentLine; l->propBuf[Currentbuf->pos] ^= PE_MARK; - redrawLine(Currentbuf, l, l->linenumber - Currentbuf->topLine->linenumber); + redrawLine(Currentbuf, l, l->linenumber - Currentbuf->topLine->linenumber + + Currentbuf->rootY); } /* Go to next mark */ @@ -2766,6 +2779,21 @@ followA(void) if (map) url = Sprintf("%s?%d,%d", a->url, x, y)->ptr; #endif + + if (check_target && open_tab_blank && a->target && + (!strcasecmp(a->target, "_new") || !strcasecmp(a->target, "_blank"))) { + Buffer *buf; + + _newT(); + buf = Currentbuf; + loadLink(url, a->target, a->referer, NULL); + if (buf != Currentbuf) + delBuffer(buf); + else + deleteTab(CurrentTab); + displayBuffer(Currentbuf, B_NORMAL); + return; + } loadLink(url, a->target, a->referer, NULL); displayBuffer(Currentbuf, B_NORMAL); } @@ -3123,7 +3151,7 @@ _followForm(int submit) if (!formChooseOptionByMenu(fi, Currentbuf->cursorX - Currentbuf->pos + a->start.pos + Currentbuf->rootX, - Currentbuf->cursorY)) + Currentbuf->cursorY + Currentbuf->rootY)) break; formUpdateBuffer(a, Currentbuf, fi); if (fi->parent->nitems == 1) @@ -3241,12 +3269,12 @@ drawAnchorCursor0(Buffer *buf, int hseq, int prevhseq, int tline, int eline, } } if (active) - redrawLineRegion(buf, l, l->linenumber - tline, + redrawLineRegion(buf, l, l->linenumber - tline + buf->rootY, an->start.pos, an->end.pos); } else if (prevhseq >= 0 && an->hseq == prevhseq) { if (active) - redrawLineRegion(buf, l, l->linenumber - tline, + redrawLineRegion(buf, l, l->linenumber - tline + buf->rootY, an->start.pos, an->end.pos); } } @@ -3271,7 +3299,7 @@ drawAnchorCursor(Buffer *buf) else hseq = -1; tline = buf->topLine->linenumber; - eline = tline + LASTLINE; + eline = tline + LASTLINE - buf->rootY; prevhseq = buf->hmarklist->prevhseq; drawAnchorCursor0(buf, hseq, prevhseq, tline, eline, 1); @@ -3652,7 +3680,12 @@ backBf(void) Buffer *buf = Currentbuf->linkBuffer[LB_N_FRAME]; if (!checkBackBuffer(Currentbuf)) { - disp_message("Can't back...", TRUE); + if (close_tab_back && nTab >= 1) { + deleteTab(CurrentTab); + displayBuffer(Currentbuf, B_FORCE_REDRAW); + } + else + disp_message("Can't back...", TRUE); return; } @@ -3938,23 +3971,39 @@ void follow_map(struct parsed_tagarg *arg) { #ifdef MENU_MAP - Anchor *a; - char *url; - int x; + Anchor *an; + MapArea *a; + int x, y; ParsedURL p_url; - a = retrieveCurrentImg(Currentbuf); + an = retrieveCurrentImg(Currentbuf); x = Currentbuf->cursorX + Currentbuf->rootX; - url = follow_map_menu(Currentbuf, arg, a, x, Currentbuf->cursorY); - if (url == NULL || *url == '\0') + y = Currentbuf->cursorY + Currentbuf->rootY; + a = follow_map_menu(Currentbuf, arg, an, x, y); + if (a == NULL || a->url == NULL || *(a->url) == '\0') return; - if (*url == '#') { - gotoLabel(url + 1); + if (*(a->url) == '#') { + gotoLabel(a->url + 1); return; } - parseURL2(url, &p_url, baseURL(Currentbuf)); + parseURL2(a->url, &p_url, baseURL(Currentbuf)); pushHashHist(URLHist, parsedURL2Str(&p_url)->ptr); - cmd_loadURL(url, baseURL(Currentbuf), + if (check_target && open_tab_blank && a->target && + (!strcasecmp(a->target, "_new") || !strcasecmp(a->target, "_blank"))) { + Buffer *buf; + + _newT(); + buf = Currentbuf; + cmd_loadURL(a->url, baseURL(Currentbuf), + parsedURL2Str(&Currentbuf->currentURL)->ptr); + if (buf != Currentbuf) + delBuffer(buf); + else + deleteTab(CurrentTab); + displayBuffer(Currentbuf, B_NORMAL); + return; + } + cmd_loadURL(a->url, baseURL(Currentbuf), parsedURL2Str(&Currentbuf->currentURL)->ptr); #else Buffer *buf; @@ -4629,15 +4678,76 @@ stopI(void) #ifdef USE_MOUSE +static TabBuffer * +posTab(int x, int y) +{ + TabBuffer *t; + int i, n, col = COLS - 2; + + if (col <= 0) + return NULL; + n = x * N_TAB / col + y * N_TAB; + for (t = FirstTab, i = 0; t && i < n; t = t->nextTab, i++) + ; + return t; +} + static void process_mouse(int btn, int x, int y) { int delta_x, delta_y, i; static int press_btn = MOUSE_BTN_RESET, press_x, press_y; + TabBuffer *t; + int ny = 0; + if (nTab > 1) + ny = (nTab - 1) / N_TAB + 1; if (btn == MOUSE_BTN_UP) { switch (press_btn) { case MOUSE_BTN1_DOWN: + if (nTab > 1 && y < ny) { + if (press_y == y && press_x == x) { + if (y == 0 && x >= COLS - 2) { + deleteTab(CurrentTab); + displayBuffer(Currentbuf, B_NORMAL); + } + t = posTab(x, y); + if (t) + CurrentTab = t; + displayBuffer(Currentbuf, B_FORCE_REDRAW); + return; + } + else if (press_y < ny) { + moveTab(posTab(press_x, press_y), posTab(x, y), + (press_y == y) ? (press_x < x) : (press_y < y)); + return; + } + else if (press_x >= Currentbuf->rootX) { + Buffer *buf = Currentbuf; + int cx = Currentbuf->cursorX, cy = Currentbuf->cursorY; + + t = posTab(x, y); + if (t == NULL) + return; + cursorXY(Currentbuf, press_x - Currentbuf->rootX, + press_y - Currentbuf->rootY); + if (Currentbuf->cursorY == press_y - Currentbuf->rootY && + (Currentbuf->cursorX == press_x - Currentbuf->rootX +#ifdef JP_CHARSET + || (Currentbuf->currentLine != NULL && + (Currentbuf->currentLine->propBuf[Currentbuf->pos] + & PC_KANJI1) && Currentbuf->cursorX == press_x + - Currentbuf->rootX - 1) +#endif + )) { + onA(); + followTab(t); + } + if (buf == Currentbuf) + cursorXY(Currentbuf, cx, cy); + } + return; + } if (press_x != x || press_y != y) { delta_x = x - press_x; delta_y = y - press_y; @@ -4685,7 +4795,7 @@ process_mouse(int btn, int x, int y) } return; } - if (y == Currentbuf->cursorY && + if (y == Currentbuf->cursorY + Currentbuf->rootY && (x == Currentbuf->cursorX + Currentbuf->rootX #ifdef JP_CHARSET || (Currentbuf->currentLine != NULL && @@ -4698,18 +4808,30 @@ process_mouse(int btn, int x, int y) return; } if (x >= Currentbuf->rootX) - cursorXY(Currentbuf, x - Currentbuf->rootX, y); + cursorXY(Currentbuf, x - Currentbuf->rootX, + y - Currentbuf->rootY); displayBuffer(Currentbuf, B_NORMAL); } break; case MOUSE_BTN2_DOWN: + if (nTab > 1 && y < ny) { + if (press_y == y && press_x == x) { + t = posTab(x, y); + if (t) { + deleteTab(t); + displayBuffer(Currentbuf, B_FORCE_REDRAW); + } + } + return; + } backBf(); break; case MOUSE_BTN3_DOWN: #ifdef USE_MENU - if (x >= Currentbuf->rootX) - cursorXY(Currentbuf, x - Currentbuf->rootX, y); + if (x >= Currentbuf->rootX && y > ny) + cursorXY(Currentbuf, x - Currentbuf->rootX, + y - Currentbuf->rootY); onA(); mainMenu(x, y); #endif /* USE_MENU */ @@ -5023,10 +5145,13 @@ deleteFiles() { Buffer *buf; char *f; - while (Firstbuf && Firstbuf != NO_BUFFER) { - buf = Firstbuf->nextBuffer; - discardBuffer(Firstbuf); - Firstbuf = buf; + + for (CurrentTab = FirstTab; CurrentTab; CurrentTab = CurrentTab->nextTab) { + while (Firstbuf && Firstbuf != NO_BUFFER) { + buf = Firstbuf->nextBuffer; + discardBuffer(Firstbuf); + Firstbuf = buf; + } } while ((f = popText(fileToDelete)) != NULL) unlink(f); @@ -5257,3 +5382,316 @@ defKey(void) setKeymap(allocStr(data, -1), -1, TRUE); displayBuffer(Currentbuf, B_NORMAL); } + +TabBuffer * +newTab(void) +{ + TabBuffer *n; + + n = New(TabBuffer); + if (n == NULL) + return NULL; + n->nextTab = NULL; + n->currentBuffer = NULL; + n->firstBuffer = NULL; + return n; +} + +static void +_newT(void) +{ + TabBuffer *tag; + Buffer *buf; + int i; + + tag = newTab(); + if (! tag) + return; + + buf = newBuffer(Currentbuf->width); + copyBuffer(buf, Currentbuf); + buf->nextBuffer = NULL; + for (i = 0; i < MAX_LB; i++) + buf->linkBuffer[i] = NULL; + (*buf->clone)++; + tag->firstBuffer = tag->currentBuffer = buf; + + tag->nextTab = CurrentTab->nextTab; + tag->prevTab = CurrentTab; + if (CurrentTab->nextTab) + CurrentTab->nextTab->prevTab = tag; + else + LastTab = tag; + CurrentTab->nextTab = tag; + CurrentTab = tag; + nTab++; +} + +void +newT(void) +{ + _newT(); + displayBuffer(Currentbuf, B_FORCE_REDRAW); +} + +TabBuffer * +numTab(int n) +{ + TabBuffer *tab; + int i; + + if (n == 0) + return CurrentTab; + if (n == 1) + return FirstTab; + if (nTab <= 1) + return NULL; + for (tab = FirstTab, i = 1; tab && i < n; tab = tab->nextTab, i++) + ; + return tab; +} + +TabBuffer * +deleteTab(TabBuffer *tab) +{ + Buffer *buf, *next; + + if (nTab <= 1) + return FirstTab; + if (tab->prevTab) { + if (tab->nextTab) + tab->nextTab->prevTab = tab->prevTab; + else + LastTab = tab->prevTab; + tab->prevTab->nextTab = tab->nextTab; + if (tab == CurrentTab) + CurrentTab = tab->prevTab; + } + else { /* tab == FirstTab */ + tab->nextTab->prevTab = NULL; + FirstTab = tab->nextTab; + if (tab == CurrentTab) + CurrentTab = tab->nextTab; + } + nTab--; + buf = tab->firstBuffer; + while (buf && buf != NO_BUFFER) { + next = buf->nextBuffer; + discardBuffer(buf); + buf = next; + } + return FirstTab; +} + +void +closeT(void) +{ + TabBuffer *tab; + + if (nTab <= 1) + return; + if (prec_num) + tab = numTab(PREC_NUM); + else + tab = CurrentTab; + if (tab) + deleteTab(tab); + displayBuffer(Currentbuf, B_FORCE_REDRAW); +} + +void +nextT(void) +{ + int i; + + if (nTab <= 1) + return; + for (i = 0; i < PREC_NUM; i++) { + if (CurrentTab->nextTab) + CurrentTab = CurrentTab->nextTab; + else + CurrentTab = FirstTab; + } + displayBuffer(Currentbuf, B_FORCE_REDRAW); +} + +void +prevT(void) +{ + int i; + + if (nTab <= 1) + return; + for (i = 0; i < PREC_NUM; i++) { + if (CurrentTab->prevTab) + CurrentTab = CurrentTab->prevTab; + else + CurrentTab = LastTab; + } + displayBuffer(Currentbuf, B_FORCE_REDRAW); +} + +void +followTab(TabBuffer *tab) +{ + Buffer *buf; + Anchor *a; + +#ifdef USE_IMAGE + a = retrieveCurrentImg(Currentbuf); + if (! (a && a->image && a->image->map)) +#endif + a = retrieveCurrentAnchor(Currentbuf); + if (a == NULL) + return; + + if (tab == CurrentTab) { + check_target = FALSE; + followA(); + check_target = TRUE; + return; + } + _newT(); + buf = Currentbuf; + check_target = FALSE; + followA(); + check_target = TRUE; + if (tab == NULL) { + if (buf != Currentbuf) + delBuffer(buf); + else + deleteTab(CurrentTab); + } + else if (buf != Currentbuf) { + /* buf <- p <- ... <- Currentbuf = c */ + Buffer *c, *p; + + c = Currentbuf; + p = prevBuffer(c, buf); + p->nextBuffer = NULL; + Firstbuf = buf; + deleteTab(CurrentTab); + CurrentTab = tab; + for (buf = p; buf; buf = p) { + p = prevBuffer(c, buf); + pushBuffer(buf); + } + } + displayBuffer(Currentbuf, B_FORCE_REDRAW); +} + +void +tabA(void) +{ + followTab(prec_num ? numTab(PREC_NUM) : NULL); +} + +static void +tabURL0(TabBuffer *tab, char *prompt, int relative) +{ + Buffer *buf; + + if (tab == CurrentTab) { + goURL0(prompt, relative); + return; + } + _newT(); + buf = Currentbuf; + goURL0(prompt, relative); + if (tab == NULL) { + if (buf != Currentbuf) + delBuffer(buf); + else + deleteTab(CurrentTab); + } + else if (buf != Currentbuf) { + /* buf <- p <- ... <- Currentbuf = c */ + Buffer *c, *p; + + c = Currentbuf; + p = prevBuffer(c, buf); + p->nextBuffer = NULL; + Firstbuf = buf; + deleteTab(CurrentTab); + CurrentTab = tab; + for (buf = p; buf; buf = p) { + p = prevBuffer(c, buf); + pushBuffer(buf); + } + } + displayBuffer(Currentbuf, B_FORCE_REDRAW); +} + +void +tabURL(void) +{ + tabURL0(prec_num ? numTab(PREC_NUM) : NULL, + "Goto URL on new tab: ", FALSE); +} + +void +tabrURL(void) +{ + tabURL0(prec_num ? numTab(PREC_NUM) : NULL, + "Goto relative URL on new tab: ", TRUE); +} + +void +moveTab(TabBuffer *t, TabBuffer *t2, int right) +{ + if (!t || !t2 || t == t2) + return; + if (t->prevTab) { + if (t->nextTab) + t->nextTab->prevTab = t->prevTab; + else + LastTab = t->prevTab; + t->prevTab->nextTab = t->nextTab; + } + else { + t->nextTab->prevTab = NULL; + FirstTab = t->nextTab; + } + if (right) { + t->nextTab = t2->nextTab; + t->prevTab = t2; + if (t2->nextTab) + t2->nextTab->prevTab = t; + else + LastTab = t; + t2->nextTab = t; + } + else { + t->prevTab = t2->prevTab; + t->nextTab = t2; + if (t2->prevTab) + t2->prevTab->nextTab = t; + else + FirstTab = t; + t2->prevTab = t; + } + displayBuffer(Currentbuf, B_FORCE_REDRAW); +} + +void +tabR(void) +{ + TabBuffer *tab; + int i; + + for (tab = CurrentTab, i = 0; tab && i < PREC_NUM; tab = tab->nextTab, i++) + ; + moveTab(CurrentTab, tab ? tab : LastTab, TRUE); +} + +void +tabL(void) +{ + TabBuffer *tab; + int i; + + for (tab = CurrentTab, i = 0; tab && i < PREC_NUM; tab = tab->prevTab, i++) + ; + moveTab(CurrentTab, tab ? tab : FirstTab, FALSE); +} + -- cgit v1.2.3