⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fv.tree.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
		/* Insert existing child into sorted array ...*/		for (i = 0; i < nchild; i++)			if (strcmp(existing_child->name, child[i]->name)<0)			{				existing_child->sibling = child[i];				if (i)					child[i-1]->sibling = existing_child;				else					f_p->child = existing_child;				break;			}				if (i==nchild)		{			/* ...must belong at end */			child[i-1]->sibling = existing_child;			existing_child->sibling = NULL;		}		}		*new = TRUE;	}	else if (compare)	{		fv_destroy_tree(f_p->child);		f_p->child = NULL;		*new = TRUE;	}	return(SUCCESS);}/* Return -1, 0, 1 if less than, equal to, or greater than */staticcompare_name(f1, f2)	FV_TNODE **f1, **f2;{	return(strcmp((*f1)->name, (*f2)->name));}staticcompare_child(ff_p, fc_p, new)	FV_TNODE *ff_p, *fc_p;	BOOLEAN *new;{	register FV_TNODE *f_p, *c_p, *t_p;	long delete = 1;			/* Unlikely time (delete marker */	c_p = fc_p;	while (c_p)	{		/* Test current children against previous */		for (f_p = ff_p; f_p; f_p = f_p->sibling)			if (strcmp(c_p->name, f_p->name) == 0)				break;		/* Exists, mark for delete */		if (f_p)			c_p->mtime = delete;					c_p = c_p->sibling;	}	f_p = ff_p;	while (f_p)	{		/* Test previous against current */		for (c_p = fc_p; c_p; c_p = c_p->sibling)			if (strcmp(c_p->name, f_p->name) == 0)				break;		/* No longer exists, mark for delete */		if (!c_p)			f_p->mtime = delete;					f_p = f_p->sibling;	}	/* Remove deleted/moved folders */	for (f_p = ff_p, c_p = NULL; f_p;)		if (f_p->mtime == delete)		{			if (c_p)				c_p->sibling = f_p->sibling;			else				f_p->parent->child = f_p->sibling;			t_p = f_p->sibling;			f_p->sibling = NULL;			fv_destroy_tree(f_p);			*new = TRUE;			f_p = t_p;		}		else		{			c_p = f_p;			f_p = f_p->sibling;		}	f_p = c_p;	/* Add new folders */	for (c_p = fc_p; c_p; c_p = c_p->sibling)		if (c_p->mtime != delete)		{			/* Tack it on the end */			if (f_p)				f_p->sibling = c_p;			else				ff_p->child = c_p;			f_p = c_p;			*new = TRUE;		}		else		{			/* Delete it */			free(c_p->name);			free((char *)c_p);		}	if (f_p)		f_p->sibling = NULL;}fv_sort_children(t_p)			/* Sort node's children by name */	FV_TNODE *t_p;{	register FV_TNODE *c_p;	FV_TNODE *child[256];	register int cno;	if (t_p->child == NULL || t_p->child->sibling == NULL)		return;	for (c_p = t_p->child, cno=0; c_p && cno<256; c_p = c_p->sibling)		child[cno++] = c_p;	qsort((char *)child, cno, sizeof(FV_TNODE *), compare_name);			/* Fix sibling pointers */	child[cno] = NULL;	while (cno) {		child[cno-1]->sibling = child[cno];		cno--;	}	t_p->child = child[0];}/* Did we visit this node, does it have any children, etc? */fv_check_children(f_p, new)	register FV_TNODE *f_p;			/* Node */	BOOLEAN *new;				/* New children? */{	struct stat fstatus;			/* File status info */	*new = FALSE;	/* Get path */	if (fv_getpath(f_p, (char *)0) || chdir(Fv_path) == -1)	{		fv_putmsg(TRUE, sys_errlist[errno], 0, 0);		Fv_tselected = FALSE;		return;	}	if (f_p->mtime)	{		/* We're already seen this folder.  Compare the modification		 * date and rebuild this portion of the tree if necessary.		 */		if (stat(".", &fstatus))		{			fv_putmsg(TRUE, sys_errlist[errno], 0, 0);			return;		}		if (fstatus.st_mtime > f_p->mtime)		{			fv_add_children(f_p, new, (char *)0);			fv_putmsg(FALSE, Fv_message[MMODIFIED],				(int)f_p->name, 0);		}	}}static char *E_p;fv_expand_all_nodes(){	FV_TNODE *sibling;	fv_busy_cursor(TRUE);	sibling = Fv_tselected->sibling;	Fv_tselected->sibling = NULL;	E_p = Fv_path+strlen(Fv_path);	expand_all(Fv_tselected);	Fv_tselected->sibling = sibling;	fv_getpath(Fv_tselected, (char *)0);	fv_drawtree(TRUE);	fv_busy_cursor(FALSE);}staticexpand_all(f_p)	register FV_TNODE *f_p;{	BOOLEAN new;	register char *c_p;	while (f_p)	{		/* Unprune branches */		if (f_p->status & PRUNE)			f_p->status &= ~PRUNE;		if (f_p->mtime == 0)			fv_add_children(f_p, &new, Fv_path);		if (f_p->child)		{			c_p = f_p->child->name;			*E_p++ = '/';			while (*E_p++ = *c_p++)				;			E_p--;			expand_all(f_p->child);		}		if (f_p = f_p->sibling)		{			c_p = f_p->name;			while (*E_p != '/')				E_p--;			while (*(++E_p) = *c_p++)				;		}	}	while (*E_p != '/')		E_p--;	*E_p = NULL;}fv_expand_node(f_p, new)	register FV_TNODE *f_p;	BOOLEAN *new;				/* New children? */{	if ((fv_add_children(f_p, new, (char *)0) == SUCCESS) && 		*new == FALSE)	{		/* No children (but show that it has been explored) */		reverse(f_p);		pw_rop(Fv_tree.pw, f_p->x, f_p->y,			GLYPH_WIDTH, (TREE_GLYPH_HEIGHT>>2)-(TREE_GLYPH_HEIGHT>>4),			PIX_SRC, Fv_icon[FV_IFOLDER],			0, TREE_GLYPH_TOP);		reverse(f_p);	}}/* Free up memory allocated to (portion of) tree */fv_destroy_tree(f_p)	register FV_TNODE *f_p;{	for ( ; f_p; f_p = f_p->sibling)		if (f_p->child)			fv_destroy_tree(f_p->child);		else		{			free(f_p->name);			free((char *)f_p);		}}/* Get full path name from node in tree */fv_getpath(c_p, buf)	register FV_TNODE *c_p;		/* Node */	char *buf;			/* Local copy of path */{	FV_TNODE *level[32];	register int levelno;	register char *p_p, *s_p;	/* Get full path name; back up tree and copy it in fv_reverse	 * order.	 */	for ( levelno = 0; c_p; c_p = c_p->parent, levelno++ )	{		if ( levelno > 32 )		{			fv_putmsg(TRUE, "> 32 levels deep", 0, 0);			return(FAILURE);		}		level[levelno] = c_p;	}	if (!buf)		buf = Fv_path;	p_p = buf;	levelno -= 2;		/* Skip root */	while ( levelno >= 0 )	{		*p_p++ = '/';		s_p = level[levelno]->name;		while ( *s_p )			*p_p++ = *s_p++;		levelno--;	}	if ( p_p == buf )		*p_p++ = '/';	*p_p = NULL;	c_p = level[0];	return(SUCCESS);}/* Called by filer to request updating of tree */fv_updatetree(){	register FV_TNODE *f_p, *lf_p;	/* Current, last nodes */	register FV_TNODE *existing;	/* Existing child node */	FV_TNODE *first_p;		/* First created node */	register FV_FILE **file_p, **lfile_p;	/* Files array pointers */	lf_p = NULL;	existing = Fv_current->child;	for (file_p=Fv_file, lfile_p=Fv_file+Fv_nfiles;		file_p != lfile_p; file_p++)		if ((*file_p)->type == FV_IFOLDER)		{		/* Don't allocate existing children */		if (existing && strcmp(existing->name, (*file_p)->name) == 0)			continue;		if ((f_p = (FV_TNODE *)fv_malloc(sizeof(FV_TNODE))) == NULL ||		   (f_p->name = fv_malloc((unsigned)strlen((*file_p)->name)+1))==NULL)			return;		if (!lf_p)			first_p = f_p;		f_p->parent = Fv_current;		f_p->child = NULL;		(void)strcpy(f_p->name, (*file_p)->name);		f_p->mtime = 0;		f_p->status = 0;		if (lf_p)			lf_p->sibling = f_p;		lf_p = f_p;	}	if (lf_p)		lf_p->sibling = NULL;	else		return;	if (Fv_current->child)	{		/* Insert existing child in alphabetically correct spot.		 * (Names returned by fv_getnextdir() have been sorted.)		 */		for (lf_p = NULL, f_p = first_p; f_p;			lf_p = f_p, f_p = f_p->sibling )			if (strcmp(existing->name, f_p->name) < 0)			{				/* Existing child should appear here */				existing->sibling = f_p;				break;			}		if (lf_p)		{			/* Existing child is no longer first element */			lf_p->sibling = existing;			Fv_current->child = first_p;		}	}	else		Fv_current->child = first_p;}static FV_TNODE *mouse(x, y, f_p)			/* Are we over a folder? */	int x, y;	FV_TNODE *f_p;{	Chosen = NULL;	mouse_recursive(x, y, f_p);	return(Chosen);}staticmouse_recursive(x, y, f_p)	register int x, y;	register FV_TNODE *f_p;{	if (Chosen)		return;	for ( ; f_p; f_p = f_p->sibling )	{		if (f_p->sibling && f_p->sibling->stack)		{			/* The visible portion of a stacked folder should			 * be selectable; since the last stacked folder			 * is completely visible, work backwards...			 */			FV_TNODE *lf_p = f_p;			register int sno = 0;			/* Collect stacked folders... */			Mouse_stack[sno++] = f_p;			for (f_p = f_p->sibling; f_p && f_p->stack; f_p = f_p->sibling)				Mouse_stack[sno++] = f_p;			/* ... and compare them in reverse order */			while (sno--)				if ( ( x >= Mouse_stack[sno]->x && 				       x <= Mouse_stack[sno]->x+GLYPH_WIDTH ) &&				     ( y >= Mouse_stack[sno]->y && 				       y <= Mouse_stack[sno]->y+TREE_GLYPH_HEIGHT ) )				{					Chosen = Mouse_stack[sno];					return;				}			f_p = lf_p;		}				if ( ( x >= f_p->x && x <= f_p->x+GLYPH_WIDTH ) &&		   ( y >= f_p->y && y <= f_p->y+TREE_GLYPH_HEIGHT ) )		{			Chosen = f_p;			return;		}		if (f_p->child && !(f_p->status & PRUNE))			mouse_recursive(x, y, f_p->child);	}}FV_TNODE *fv_infolder(x, y)		/* Return folder name at coordinate */	int x, y;{	if (Fv_treeview)	{		/* Only the tree can scroll, adjust for scrolling... */		x += Fv_tree.r.r_left;		y += Fv_tree.r.r_top;		return(mouse(x, y, Fv_thead));	}	else return(path_chosen(x, y));}staticreverse(f_p)				/* Highlight folder */	register FV_TNODE *f_p;{	if (f_p)		pw_rop(Fv_tree.pw, f_p->x, f_p->y,			GLYPH_WIDTH, TREE_GLYPH_HEIGHT,			PIX_SRC ^ PIX_DST,			f_p==Fv_current?Fv_invert[FV_IOPENFOLDER]:				f_p->mtime && !(f_p->status&PRUNE) ?					     Fv_invert[FV_IFOLDER] :					     Fv_invert[FV_IUNEXPLFOLDER],			0, TREE_GLYPH_TOP);}fv_open_folder()			/* Open selected folder */{	int len;	char buf[MAXPATH];	BOOLEAN children;	fv_busy_cursor(TRUE);		/* Cursor wait */	/* Open reveals folder's children, if not currently visible */	if (Fv_tselected->mtime == 0)	{		fv_expand_node(Fv_tselected, &children);		if (children)			fv_drawtree(TRUE);	}	/* Open reveals hidden folder */	if (Fv_tselected->status & PRUNE)	{		Fv_tselected->status &= ~PRUNE;		fv_drawtree(TRUE);	}	/* Open a symbolically linked folder displays the link contents */	if (Fv_tselected->status & SYMLINK)	{		/* Symbolic link to directory; get reference's real name.		 * These names may be relative pathnames...		 */		char *b_p;		(void)strcpy(buf, Fv_path);		len = strlen(Fv_path);		b_p = buf+len;		while (*b_p != '/')		/* Back to parent */			b_p--;		b_p++;				/* Skip / */		if ((len=readlink(Fv_path, b_p, MAXPATH-1)) == -1)		{			fv_putmsg(TRUE, sys_errlist[errno], 0, 0);			fv_busy_cursor(FALSE);			return;		}		/* We've found where it's pointing to,		 * Either (a) absolute pathname		 *        (b) relative with no indirection		 *     or (c) relative with indirection		 */		b_p[len] = NULL;		fv_putmsg(FALSE, "%s linked to %s", 			(int)Fv_tselected->name, (int)b_p);		if (strncmp(b_p, "../", 3) == 0)	/* (c) */		{			register char *n_p;			n_p = b_p;			b_p -= 2;		/* Skip /. */			while (*b_p != '/')				b_p--;			n_p += 3;		/* Skip ../ */			b_p++;			while (*b_p++ = *n_p++)				;		}		/* Either (a) or (b) */		reverse(Fv_tselected);		Fv_tselected = NULL;		fv_openfile(*b_p=='/' ? b_p : buf, (char *)0, TRUE);	}	else	{		Fv_current = Fv_tselected;		/* Selected is now open */		reverse(Fv_tselected);			/* Turn reverse off */		fv_showopen();				/* Show open folder */		reverse(Fv_tselected);			/* Turn reverse back on */		(void)strcpy(Fv_openfolder_path, Fv_path);	/* Open path */		Fv_dont_paint = TRUE;		scrollbar_scroll_to(Fv_foldr.vsbar, 0);		Fv_dont_paint = FALSE;		fv_display_folder(FV_BUILD_FOLDER);	/* Open & paint directory */	}	fv_busy_cursor(FALSE);		/* Cursor normal */}fv_put_text_on_folder(f_p)			/* Place folder name on folder */	register FV_TNODE *f_p;			/* Tree node */{	int x, w, y, l;	/* Don't bother if not visible */	if (Fv_treeview &&	    (f_p->y >= Fv_tree.r.r_top + Fv_tree.r.r_height ||	     /*f_p->y-(TREE_GLYPH_HEIGHT>>1) < Fv_tree.r.r_top ||*/	     f_p->x >= Fv_tree.r.r_left + Fv_tree.r.r_width))		return;	/* Some portion must be visible... */	l = fv_strlen(f_p->name);	x = f_p->x;	w = GLYPH_WIDTH;	if (f_p == Fv_current)		w -= GLYPH_WIDTH>>4;	if (l < w)	{		y = f_p->y+(TREE_GLYPH_HEIGHT>>1);		pw_text(Fv_tree.pw, x+(w>>1)-(l/2), y,			PIX_SRC | PIX_DST, Fv_font, f_p->name);	}	else		wrap_text_on_folder(f_p, w, x);}staticwrap_text_on_folder(f_p, w, x)	/* Wrap overflow text onto two lines in folder */	register FV_TNODE *f_p;	int w, x;{	register char *s_p, *n_p;	char first[16];	char second[16];	register short width;	register BOOLEAN shadow;	/* Name too large to fit within folder: so wrap within two lines and 	 * truncate it if necessary.  (If displaying tree, don't bother with	 * second line if there's another folder stacked over it.)	 */	shadow = Fv_treeview && f_p->sibling && f_p->sibling->stack>0;	*second = NULL;	s_p = first;	n_p = f_p->name;	width = 0;	while (*n_p)	{		width += Fv_fontwidth[*n_p-' '];		if (width > w)			if (shadow)				break;			else if (*second)					break;				else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -