dirbrowser.c

来自「A GTK sound font editor. Sound font file」· C语言 代码 · 共 373 行

C
373
字号
/*================================================================== * dirbrowser.c - Directory browser widget * * Smurf Sound Font Editor * Copyright (C) 1999-2001 Josh Green * * Modified source code from: * XMMS - Cross-platform multimedia player * Copyright (C) 1998-2000  Peter Alm, Mikael Alm, Olle Hallnas, * Thomas Nilsson and 4Front Technologies * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. * * To contact the author of this program: * Email: Josh Green <jgreen@users.sourceforge.net> * Smurf homepage: http://smurf.sourceforge.net *==================================================================*/#include <sys/types.h>#include <sys/stat.h>#include <dirent.h>#include <unistd.h>#include <string.h>#include <gtk/gtk.h>#include <stdio.h>#include "i18n.h"static char *folder[] = {  "16 16 8 1",  " 	c None",  ".	c #909000",  "+	c #000000",  "@	c #EFE8EF",  "#	c #FFF8CF",  "$	c #FFF890",  "%	c #CFC860",  "&	c #FFC890",  "                ",  "  .....+        ",  " .@##$$.+       ",  ".%%%%%%%......  ",  ".###########$%+ ",  ".#$$$$$$$$$$&%+ ",  ".#$$$$$$$&$&$%+ ",  ".#$$$$$$$$&$&%+ ",  ".#$$$$$&$&$&$%+ ",  ".#$$$$$$&$&$&%+ ",  ".#$$$&$&$&$&&%+ ",  ".#&$&$&$&$&&&%+ ",  ".%%%%%%%%%%%%%+ ",  " ++++++++++++++ ",  "                ",  "                "};/* XPM */static char *ofolder[] = {  "16 16 12 1",  " 	c None",  ".	c #808080",  "+	c #E0E0D0",  "@	c #4F484F",  "#	c #909000",  "$	c #FFF8EF",  "%	c #CFC860",  "&	c #003090",  "*	c #7F7800",  "=	c #FFC890",  "-	c #FFF890",  ";	c #2F3000",  "        .       ",  "       .+@      ",  "   ###.$$+@     ",  "  #%%.$$$$+@    ",  "  #%.$$$&$$+@** ",  "  #.+++&+&+++@* ",  "############++@ ",  "#$$$$$$$$$=%#++@",  "#$-------=-=#+; ",  " #---=--=-==%#; ",  " #-----=-=-==#; ",  " #-=--=-=-=-=#; ",  "  #=-=-=-=-==#; ",  "  ############; ",  "   ;;;;;;;;;;;  ",  "                "};static GdkPixmap *folder_pixmap = NULL, *ofolder_pixmap;static GdkBitmap *folder_mask, *ofolder_mask;typedef struct{  gboolean scanned;  gchar *path;}DirNode;static gbooleancheck_for_subdir (gchar * path){  DIR *dir;  struct dirent *dirent;  struct stat statbuf;  gchar *npath;  if ((dir = opendir (path)) != NULL)    {      while ((dirent = readdir (dir)) != NULL)	{	  if (dirent->d_name[0] != '.')	    {	      npath = g_strconcat (path, dirent->d_name, NULL);	      if (stat (npath, &statbuf) != -1 && S_ISDIR (statbuf.st_mode))		{		  g_free (npath);		  closedir (dir);		  return TRUE;		}	      g_free (npath);	    }	}      closedir (dir);    }  return FALSE;}static voiddestroy_cb (gpointer data){  DirNode *node = data;  g_free (node->path);  g_free (node);}static voidexpand_cb (GtkWidget * widget, GtkCTreeNode * parent_node){  DIR *dir;  struct dirent *dirent;  gchar *path, *text, *dummy = "dummy";  struct stat statbuf;  GtkCTreeNode *node, *sub_node;  DirNode *parent_dirnode, *dirnode;  gboolean has_subdir = FALSE;  parent_dirnode =    gtk_ctree_node_get_row_data (GTK_CTREE (widget), parent_node);  if (!parent_dirnode->scanned)    {      gtk_clist_freeze (GTK_CLIST (widget));      node =	gtk_ctree_find_by_row_data (GTK_CTREE (widget), parent_node, NULL);      gtk_ctree_remove_node (GTK_CTREE (widget), node);      if ((dir = opendir (parent_dirnode->path)) != NULL)	{	  while ((dirent = readdir (dir)) != NULL)	    {	      path = g_strconcat (parent_dirnode->path, dirent->d_name, NULL);	      if (stat (path, &statbuf) != -1 && S_ISDIR (statbuf.st_mode)		  && dirent->d_name[0] != '.')		{		  dirnode = g_malloc0 (sizeof (DirNode));		  dirnode->path = g_strconcat (path, G_DIR_SEPARATOR_S, NULL);		  text = dirent->d_name;		  if (check_for_subdir (dirnode->path))		    has_subdir = TRUE;		  else		    has_subdir = FALSE;		  node =		    gtk_ctree_insert_node (GTK_CTREE (widget), parent_node,					   NULL, &text, 4, folder_pixmap,					   folder_mask, ofolder_pixmap,					   ofolder_mask, !has_subdir, FALSE);		  gtk_ctree_node_set_row_data_full (GTK_CTREE (widget), node,						    dirnode, destroy_cb);		  if (has_subdir)		    sub_node =		      gtk_ctree_insert_node (GTK_CTREE (widget), node, NULL,					     &dummy, 4, NULL, NULL, NULL,					     NULL, FALSE, FALSE);		}	      g_free (path);	    }	  closedir (dir);	  gtk_ctree_sort_node (GTK_CTREE (widget), parent_node);	}      gtk_clist_thaw (GTK_CLIST (widget));      parent_dirnode->scanned = TRUE;    }}static voidok_clicked (GtkWidget * widget, GtkWidget * tree){  GtkCTreeNode *node;  DirNode *dirnode;  GList *list_node;  GtkWidget *window;  void (*handler) (gchar *);  window = gtk_object_get_user_data (GTK_OBJECT (widget));  gtk_widget_hide (window);  list_node = GTK_CLIST (tree)->selection;  while (list_node)    {      node = list_node->data;      dirnode = gtk_ctree_node_get_row_data (GTK_CTREE (tree), node);      handler =	(void (*)(gchar *)) gtk_object_get_user_data (GTK_OBJECT (tree));      if (handler)	handler (dirnode->path);      list_node = g_list_next (list_node);    }  gtk_widget_destroy (window);}static intfiletreeent_compare_func (const void *a, const void *b){  if (!a || !b || !((DirNode *) a)->path)    return -1;  return strcmp (((DirNode *) a)->path, (gchar *) b);}GtkWidget *dirbrowse_create (gchar * title, gchar * current_path,		  gtkselectionmode mode, void (*handler) (gchar *)){  GtkWidget *window, *scroll_win, *tree, *vbox, *bbox, *ok, *cancel, *sep;  gchar *root_text = G_DIR_SEPARATOR_S, *node_text = "dummy";  gchar *currentdir, *pos, *tpath, *tpathnew;  GtkCTreeNode *root_node, *node, *nextnode;  DirNode *dirnode;  gboolean leaf;  window = gtk_window_new (GTK_WINDOW_DIALOG);  gtk_window_set_title (GTK_WINDOW (window), title);  gtk_container_border_width (GTK_CONTAINER (window), 10);  vbox = gtk_vbox_new (FALSE, 10);  gtk_container_add (GTK_CONTAINER (window), vbox);  scroll_win = gtk_scrolled_window_new (NULL, NULL);  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll_win),				  GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);  gtk_widget_set_usize (scroll_win, 250, 200);  gtk_box_pack_start (GTK_BOX (vbox), scroll_win, TRUE, TRUE, 0);  gtk_widget_show (scroll_win);  gtk_widget_realize (window);  if (!folder_pixmap)    {      folder_pixmap =	gdk_pixmap_create_from_xpm_d (window->window, &folder_mask, NULL,				      folder);      ofolder_pixmap =	gdk_pixmap_create_from_xpm_d (window->window, &ofolder_mask, NULL,				      ofolder);    }  tree = gtk_ctree_new (1, 0);  gtk_clist_set_column_auto_resize (GTK_CLIST (tree), 0, TRUE);  gtk_clist_set_selection_mode (GTK_CLIST (tree), mode);  gtk_ctree_set_line_style (GTK_CTREE (tree), GTK_CTREE_LINES_DOTTED);  gtk_signal_connect (GTK_OBJECT (tree), "tree_expand",		      GTK_SIGNAL_FUNC (expand_cb), NULL);  gtk_container_add (GTK_CONTAINER (scroll_win), tree);  gtk_object_set_user_data (GTK_OBJECT (tree), (gpointer) handler);  root_node =    gtk_ctree_insert_node (GTK_CTREE (tree), NULL, NULL, &root_text, 4,			   folder_pixmap, folder_mask, ofolder_pixmap,			   ofolder_mask, FALSE, FALSE);  dirnode = g_malloc0 (sizeof (DirNode));  dirnode->path = g_strdup (G_DIR_SEPARATOR_S);  gtk_ctree_node_set_row_data_full (GTK_CTREE (tree), root_node, dirnode,				    destroy_cb);  node =    gtk_ctree_insert_node (GTK_CTREE (tree), root_node, NULL, &node_text, 4,			   NULL, NULL, NULL, NULL, TRUE, TRUE);  gtk_ctree_expand (GTK_CTREE (tree), root_node);  gtk_widget_show (tree);  sep = gtk_hseparator_new ();  gtk_box_pack_start (GTK_BOX (vbox), sep, FALSE, FALSE, 0);  gtk_widget_show (sep);  bbox = gtk_hbutton_box_new ();  gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_END);  gtk_button_box_set_spacing (GTK_BUTTON_BOX (bbox), 5);  ok = gtk_button_new_with_label (_("Ok"));  gtk_object_set_user_data (GTK_OBJECT (ok), window);  GTK_WIDGET_SET_FLAGS (ok, GTK_CAN_DEFAULT);  gtk_window_set_default (GTK_WINDOW (window), ok);  gtk_box_pack_start (GTK_BOX (bbox), ok, TRUE, TRUE, 0);  gtk_signal_connect (GTK_OBJECT (ok), "clicked",		      GTK_SIGNAL_FUNC (ok_clicked), tree);  gtk_widget_show (ok);  cancel = gtk_button_new_with_label (_("Cancel"));  GTK_WIDGET_SET_FLAGS (cancel, GTK_CAN_DEFAULT);  gtk_box_pack_start (GTK_BOX (bbox), cancel, TRUE, TRUE, 0);  gtk_signal_connect_object (GTK_OBJECT (cancel), "clicked",			     GTK_SIGNAL_FUNC (gtk_widget_destroy),			     GTK_OBJECT (window));  gtk_widget_show (cancel);  gtk_box_pack_start (GTK_BOX (vbox), bbox, FALSE, FALSE, 0);  gtk_widget_show (bbox);  gtk_widget_show (vbox);  if (current_path && *current_path)    {      currentdir = g_strdup (current_path);      tpath = g_strdup (G_DIR_SEPARATOR_S);      pos = strtok (currentdir, G_DIR_SEPARATOR_S);      node =	gtk_ctree_find_by_row_data_custom (GTK_CTREE (tree), NULL,					   G_DIR_SEPARATOR_S,					   filetreeent_compare_func);      do	{	  tpathnew = g_strconcat (tpath, pos, G_DIR_SEPARATOR_S, NULL);	  g_free (tpath);	  tpath = tpathnew;	  nextnode =	    gtk_ctree_find_by_row_data_custom (GTK_CTREE (tree), node, tpath,					       filetreeent_compare_func);	  if (!nextnode)	    break;	  node = nextnode;	  pos = strtok (NULL, G_DIR_SEPARATOR_S);	  gtk_ctree_get_node_info (GTK_CTREE (tree), node, NULL, NULL, NULL,				   NULL, NULL, NULL, &leaf, NULL);	  if (!leaf && pos)	    gtk_ctree_expand (GTK_CTREE (tree), node);	  else	    {	      gtk_ctree_select (GTK_CTREE (tree), node);	      break;	    }	}      while (pos);      g_free (tpath);      g_free (currentdir);    }  else    gtk_ctree_select (GTK_CTREE (tree), root_node);  return window;}

⌨️ 快捷键说明

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