📄 look-next.c
字号:
path_tail = buffer + strlen (buffer); sprintf (path_tail, "/%s/%s", dir->name, dir->list[item].name); return buffer;}static char *commit (NeXTDirTree * tree, NeXTDir * dir){ /* when user presses Enter on selected item or dobleclicks */ if (tree) { if (dir) { if (dir->list && dir->cursor >= 0) { if (is_directory (dir->list, dir->cursor)) change_dir (tree, dir, dir->cursor); else return get_full_filename (tree, dir, dir->cursor); } } } return NULL;}/******************************************************************//* NeXT Browser widget stuff *//******************************************************************/#define FILEBROWSER_PANES 2#define STANDALONE_FILEBROWSER_PANES 3static char *mime_majors[3] ={"url", "text", 0};typedef struct NeXTFileBrowser { int numpanes; int focused;#define MAX_PARTIAL_NAME 32 char partial_name[MAX_PARTIAL_NAME]; int partial_end; char **labels; char **lists; char *hscroll; char *fileattr; char *name; char *filter; NeXTDirTree *tree;} NeXTFileBrowser;static void clear_partial_buffer (NeXTFileBrowser * browser){ if (browser) { browser->partial_end = 0; }}extern void CSetFilelistPosition (const char *identifier, long current, long cursor, long firstline);static void dir_save_position (NeXTDir * dir, long cursor, long current, long firstline){ dir->cursor = cursor; dir->current = current; dir->firstline = firstline;}static void destroy_next_filebrowser (CWidget * w){ if (w->hook) { NeXTFileBrowser *browser = (NeXTFileBrowser *) w->hook; int i; destroy_dir_tree (&(browser->tree)); if (browser->labels) { for (i = 0; i < browser->numpanes; i++) if (browser->labels[i]) free (browser->labels[i]); free (browser->labels); } if (browser->lists) { for (i = 0; i < browser->numpanes; i++) if (browser->lists[i]) free (browser->lists[i]); free (browser->lists); } if (browser->fileattr) free (browser->fileattr); if (browser->name) free (browser->name); if (browser->filter) free (browser->filter); /* just in case */ memset (browser, 0x00, sizeof (NeXTFileBrowser)); free (browser); w->hook = 0; }}static NeXTDir *get_dir_by_num (NeXTDirTree * tree, int num){ NeXTDir *dir = NULL; register int i; if (tree) dir = tree->first; for (i = 0; dir && i < num; i++) dir = dir->next; return dir;}static void update_filter (NeXTFileBrowser * browser, NeXTDir * dir);static void link_browser_to_data (NeXTFileBrowser * browser, int start){ NeXTDir *dir; char *path = NULL, *path_tail = 0; int i, todo = browser->numpanes; if (browser == NULL) return; if (start < 0 || start >= browser->numpanes) start = 0; if (start == 0) browser->tree->dirty = 0; if (browser->tree) { todo -= start; start += browser->tree->pos; dir = get_dir_by_num (browser->tree, start); } else dir = NULL; if (dir) { path = malloc (browser->tree->path_length + 1); get_dir_path (browser->tree, dir, path); path_tail = path + strlen (path); } for (i = 0; i < todo; i++) { if (!dir) { CRedrawDynText (browser->labels[i], ""); CRedrawFilelist (browser->lists[i], 0, 0); } else { if (dir->name) { *(path_tail++) = '/'; strcpy (path_tail, dir->name); path_tail += strlen (dir->name); CRedrawDynText (browser->labels[i], "%s/%s", dir->name, dir->filter); } else CRedrawDynText (browser->labels[i], "/%s", dir->filter); /* root */ if (dir->list == NULL) read_dir_filelist (dir, path); CRedrawFilelist (browser->lists[i], dir->list, 0); CSetFilelistPosition (browser->lists[i], dir->current, dir->cursor, dir->firstline); dir = dir->next; } }}static void update_scrollbar (CWidget * scrollbar, NeXTFileBrowser * browser, int redraw){ scrollbar->firstline = (double) 65535.0 *browser->tree->pos / (browser->tree->numdirs ? browser->tree->numdirs : 1); scrollbar->numlines = (double) 65535.0 *browser->numpanes / (browser->tree->numdirs ? browser->tree->numdirs : 1); if (redraw) render_scrollbar (scrollbar);}static void link_scrollbar_to_NeXT_browser (CWidget * scrollbar, CWidget * w, XEvent * xevent, CEvent * cwevent, int whichscrbutton){ /* fix me : add stuf */ int redraw = 0; int new_first = w->firstline; NeXTFileBrowser *browser;#if 0 static int r = 0; NeXTDir *dir;#endif if (w->hook == NULL) return; browser = (NeXTFileBrowser *) (w->hook); new_first = browser->tree->pos; if ((xevent->type == ButtonRelease || xevent->type == MotionNotify) && whichscrbutton == 3) { new_first = (double) scrollbar->firstline * browser->tree->numdirs / 65535.0; } else if (xevent->type == ButtonPress && (cwevent->button == Button1 || cwevent->button == Button2)) { switch (whichscrbutton) { case 1: new_first -= browser->numpanes - 1; break; case 2: new_first--; break; case 5: new_first++; break; case 4: new_first += browser->numpanes - 1; break; } } if (new_first > browser->tree->numdirs - browser->numpanes) new_first = browser->tree->numdirs - browser->numpanes; if (new_first < 0) new_first = 0; redraw = (new_first != browser->tree->pos); browser->tree->pos = new_first; if (xevent->type == ButtonRelease || (redraw && !CCheckWindowEvent (xevent->xany.window, ButtonReleaseMask | ButtonMotionMask, 0))) link_browser_to_data (browser, 0); update_scrollbar (w->hori_scrollbar, browser, 0);}static void update_input (NeXTFileBrowser * browser, NeXTDir * dir){ char *text = NULL; CWidget *inp_w = CIdent (browser->name); clear_partial_buffer (browser); text = get_full_filename (browser->tree, dir, dir->cursor); CDrawTextInput (browser->name, inp_w->parentid, inp_w->x, inp_w->y, inp_w->width, inp_w->height, 256, text); if (text) free (text);}static void filter_changed (NeXTFileBrowser * browser, NeXTDir * dir){ CWidget *inp_w = CIdent (browser->filter); char *new_filter = "*"; if (inp_w->text) new_filter = inp_w->text; if (strcmp (dir->filter, new_filter)) { struct file_entry *list; if (dir->filter) free (dir->filter); dir->filter = (char *) strdup (new_filter); list = dir->list; dir->list = NULL; link_browser_to_data (browser, browser->focused - browser->tree->pos); /* now after all filelists has updated its information we no longer need old data */ if (list) free (list); }}static void update_filter (NeXTFileBrowser * browser, NeXTDir * dir){ CWidget *inp_w = CIdent (browser->filter); if (strcmp (dir->filter, inp_w->text) == 0) return; if (strlen (inp_w->text)) CAddToTextInputHistory (browser->name, inp_w->text); CDrawTextInput (browser->filter, inp_w->parentid, inp_w->x, inp_w->y, inp_w->width, inp_w->height, 256, dir->filter);}/* returns 0 on fail */static int goto_partial_file_name (NeXTFileBrowser * browser, NeXTDir * dir, int new_char){ int success = 0; if (browser && dir && dir->list && browser->partial_end < MAX_PARTIAL_NAME - 1) { register int i; if (new_char != 0) { browser->partial_name[browser->partial_end] = (char) new_char; browser->partial_end++; } else if (browser->partial_end <= 0) return success; else browser->partial_end--; for (i = 0; !(dir->list[i].options & FILELIST_LAST_ENTRY); i++) if (strncmp (dir->list[i].name, browser->partial_name, browser->partial_end) == 0) { dir->cursor = i; dir->firstline = dir->cursor; CSetFilelistPosition (browser->lists[browser->focused], dir->current, dir->cursor, dir->firstline); success++; break; } if (!success) browser->partial_end--; } return success;}static Window draw_file_browser (const char *identifier, Window parent, int x, int y, const char *directory, const char *file, const char *label){ CWidget *w, *tmp = 0; int y2, x2, x3, btn_width, btn_height; int text_w1, text_w2; Window win; NeXTFileBrowser *browser; int i; char *ident, *ctrl_name; int panes = FILEBROWSER_PANES; if (strcmp (identifier, "browser") == 0) panes = STANDALONE_FILEBROWSER_PANES; if (parent == CRoot) win = CDrawMainWindow (identifier, label); else win = CDrawHeadedDialog (identifier, parent, x, y, label); w = CIdent (identifier); w->options |= WINDOW_ALWAYS_RAISED; CHourGlass (CFirstWindow);/* allocating, initializing and storing our data */ browser = (NeXTFileBrowser *) calloc (sizeof (NeXTFileBrowser), 1); w->hook = browser; w->destroy = destroy_next_filebrowser; browser->tree = create_dir_tree (directory, panes); browser->numpanes = 0; CUnHourGlass (CFirstWindow); if (browser->tree->numdirs == 0) { CErrorDialog (parent, 20, 20, _ (" File browser "), _ (" Unable to read directory ")); CDestroyWidget (identifier); return None; } browser->labels = (char **) calloc (sizeof (char *), panes); browser->lists = (char **) calloc (sizeof (char *), panes); browser->numpanes = panes; CGetHintPos (&x, &y); x += WINDOW_EXTRA_SPACING; y += WINDOW_EXTRA_SPACING;#define FILE_BOX_WIDTH (FONT_MEAN_WIDTH * 32 + 7) /* we'll use it to construct our widget names */ ident = malloc (strlen (identifier) + 20); strcpy (ident, identifier); ctrl_name = ident + strlen (identifier); y2 = 0; for (i = 0; i < browser->numpanes; i++) { CGetHintPos (&x2, 0); x2 += WINDOW_EXTRA_SPACING; sprintf (ctrl_name, ".label%3.3d", i); browser->labels[i] = (char *) strdup (ident); tmp = CDrawDynText (ident, win, x2, y, FILE_BOX_WIDTH, 1, ""); tmp->options |= TEXT_CENTRED; /* only first time */ if (y2 == 0) { CGetHintPos (0, &y2); /* y2+=WINDOW_EXTRA_SPACING ; */ } sprintf (ctrl_name, ".flist%3.3d", i); browser->lists[i] = (char *) strdup (ident); tmp = CDrawFilelist (ident, win, x2, y2, FILE_BOX_WIDTH, FONT_PIX_PER_LINE * 10, 0, 0, NULL, TEXTBOX_FILE_LIST); tmp->position |= POSITION_HEIGHT; xdnd_set_type_list (CDndClass, tmp->winid, xdnd_typelist_send[DndFiles]); /* Toolhint */ CSetToolHint (ident, _ ("Double click to enter dir or open file.")); } /* we want to automagically resize rightmost filelist */ tmp->position |= POSITION_WIDTH; if (tmp->vert_scrollbar) tmp->vert_scrollbar->position |= POSITION_RIGHT; tmp = CIdent (browser->labels[browser->numpanes - 1]); tmp->position |= POSITION_WIDTH; /* the right end of dialog */ CGetHintPos (&x3, &y2); strcpy (ctrl_name, ".hsc"); i = (double) 65535.0 *browser->tree->numpanes / (browser->tree->numdirs ? browser->tree->numdirs : 1); w->hori_scrollbar = CDrawHorizontalScrollbar (ident, win, x, y2 + WINDOW_EXTRA_SPACING, x3 - x, AUTO_HEIGHT, i, i); CSetScrollbarCallback (ident, w->ident, link_scrollbar_to_NeXT_browser); w->hori_scrollbar->position = POSITION_BOTTOM | POSITION_WIDTH; update_scrollbar (w->hori_scrollbar, browser, 1); CPushFont ("widget", 0); CGetHintPos (0, &y2); strcpy (ctrl_name, ".fileattr"); browser->fileattr = (char *) strdup (ident); tmp = CDrawDynText (ident, win, x, y2 + WINDOW_EXTRA_SPACING, x3 - x, 3, ""); tmp->position |= POSITION_FILL | POSITION_BOTTOM; CTextSize (&text_w1, 0, "Name : "); CTextSize (&text_w2, 0, "Filter : ");/* filename input stuff: */ CGetHintPos (0, &y2); y2 += WINDOW_EXTRA_SPACING; /* label */ strcpy (ctrl_name, ".namex"); x2 = x; if (text_w1 < text_w2) x2 += text_w2 - text_w1; tmp = CDrawText (ident, win, x2, y2, _ ("Name : ")); tmp->position |= POSITION_BOTTOM; /* we want filter and name inputs to be right underneath of each other */ x2 += text_w1 + WINDOW_EXTRA_SPACING; /* input */ strcpy (ctrl_name, ".finp"); browser->name = (char *) strdup (ident); tmp = CDrawTextInput (ident, win, x2, y2, AUTO_WIDTH, AUTO_HEIGHT, 256, file); tmp->position |= POSITION_FILL | POSITION_BOTTOM; /* Toolhint */ CSetToolHint (ident, _ ("Filename of the file to load.")); /* DnD stuff */ xdnd_set_type_list (CDndClass, tmp->winid, xdnd_typelist_send[DndFile]); tmp->funcs->types = DndFile; tmp->funcs->mime_majors = mime_majors;/* file filter input stuff */ CGetHintPos (0, &y2); y2 += WINDOW_EXTRA_SPACING; /* label */ x2 = x; if (text_w2 < text_w1) x2 += text_w1 - text_w2; strcpy (ctrl_name, ".filtx"); (CDrawText (ident, win, x2, y2, _ ("Filter :")))->position |= POSITION_BOTTOM; x2 += text_w2 + WINDOW_EXTRA_SPACING; /* input (we already know where to place it - right under filename input ) */ strcpy (ctrl_name, ".filtinp"); browser->filter = (char *) strdup (ident); tmp = CDrawTextInput (ident, win, x2, y2, AUTO_WIDTH, AUTO_HEIGHT, 256, TEXTINPUT_LAST_INPUT); tmp->position |= POSITION_FILL | POSITION_BOTTOM; /* Toolhint */ CSetToolHint (ident, _ ("List only files matching this shell filter"));/* buttons stuff */ CGetHintPos (0, &y2); y2 += WINDOW_EXTRA_SPACING * 2; /* determining buttons size */ CTextSize (&btn_width, &btn_height, " Cancel "); btn_height += 5 + BUTTON_RELIEF * 2; btn_width += 4 + BUTTON_RELIEF * 2; /* cancel button */ x2 = x3 - (btn_width + WINDOW_EXTRA_SPACING) * 2 - WINDOW_EXTRA_SPACING; strcpy (ctrl_name, ".cancel"); tmp = CDrawButton (ident, win, x2, y2, btn_width, btn_height, " Cancel "); tmp->position |= POSITION_RIGHT | POSITION_BOTTOM; CSetToolHint (ident, _ ("Abort this dialog, Escape")); /* ok button */ x2 += btn_width + WINDOW_EXTRA_SPACING * 2; strcpy (ctrl_name, ".ok"); tmp = CDrawButton (ident, win, x2, y2, btn_width, btn_height, " Ok "); tmp->position |= POSITION_RIGHT | POSITION_BOTTOM; CSetToolHint (ident, _ ("Accept, Enter")); CPopFont ();/* all done - no longer need that : */ free (ident);/* make us real ! */ link_browser_to_data (browser, 0); /* that will be our width/height : */ y2 += btn_height + WINDOW_EXTRA_SPACING * 2; reset_hint_pos (x3, y2); CSetSizeHintPos (identifier); /* map us */ CMapDialog (identifier); /* enable resizing */ CSetWindowResizable (identifier, FONT_MEAN_WIDTH * 40, min (FONT_PIX_PER_LINE * 5 + 230, w->height), 1600, 1200); /* minimum and maximum sizes */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -