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

📄 libpg_dirview.c

📁 The major functionality added in this release includes: - Rootless mode in X11 - Widget Templt
💻 C
📖 第 1 页 / 共 3 页
字号:
  /* Set up the default directory in it's own directory context */  pgEnterContext();  dirview_setdir(&dat);  /* If we have a field, focus it first */  if (dat.wFile)    pgFocus(dat.wFile);  for (;;) {    evt = *pgGetEvent();        /* Buttons... */    if (evt.from==wCancel)      break;    else if (evt.from==wOk) {      struct stat st;      /* Put together a full path for the final file name */      if (dat.wFile)	dat.sFileName = pgGetWidget(dat.wFile,PG_WP_TEXT);      dirview_fullpath(pgGetString(dat.sFileName));          /* Validate it */            if (stat(dirview_buf,&st) && (flags & (PG_FILE_MUSTEXIST | 						PG_FILE_MUSTREAD  |						PG_FILE_MUSTWRITE))) {	pgMessageDialog("Error","The selected file does not exist",0);	continue;      }      if (flags & PG_FILE_MUSTREAD) {	int file = open(dirview_buf,O_RDONLY);	if (file<0) {	  pgMessageDialogFmt("Error",0,"Error reading file:\n%s",			     strerror (errno));	  continue;	}	close(file);      }      if (flags & PG_FILE_MUSTWRITE) {	int file = open(dirview_buf,O_RDWR);	if (file<0) {	  pgMessageDialogFmt("Error",0,"Error writing file:\n%s",			     strerror (errno));	  continue;	}	close(file);      }      /* Good! We're all done */      break;    }    else if (evt.from==wUp) {      /* Go up one level: chop off the slash until we have only one */      p = strrchr(dirview_dir,'/');      if (p && p[1]) {	if (p==dirview_dir)	  p[1] = 0;	else	  p[0] = 0;	dirview_setdir(&dat);      }    }    else if (evt.from==dat.wDirectory && evt.type==PG_WE_PNTR_DOWN)#if 0      dirview_pathmenu(&dat);#else      ;#endif    /* 'Tis a file we hope? */    else if (pgGetPayload(evt.from)==FILETAG) {      /* File or directory? */      if (pgGetWidget(evt.from,PG_WP_FONT)==dat.fDirectory) {	/* Directory => Follow the directory */	dirview_fullpath(pgGetString(pgGetWidget(evt.from,PG_WP_TEXT)));	strcpy(dirview_dir,dirview_buf);	dirview_setdir(&dat);	/* No valid file */	dat.sFileName = 0;      }      else {	/* File => Select the file */		dat.sFileName = pgGetWidget(evt.from, PG_WP_TEXT);	if (dat.wFile)	  pgSetWidget(dat.wFile,PG_WP_TEXT,dat.sFileName,0);      }    }  }  /* Destroy the directory context and dialog context */  pgLeaveContext();  pgLeaveContext();  /* Don't have to return much, eh? */  if (evt.from==wCancel)    return NULL;    /* Return the assembled full path */  return dirview_buf;}/*****************************************************************************/typedef enum {  NONE, QUIT, RELOAD,} NextAction;/*****************************************************************************/static NextAction next_action = NONE;static intlocation_activate(struct pgEvent *evt){  ENTER("location_activate");  const char* str = pgGetString(pgGetWidget(evt->from,PG_WP_TEXT));  DPRINTF(">>> location is [%s]\n", str);  next_action = RELOAD;  LEAVE;  return 0;}/*****************************************************************************/#define FREE(var)          { if(var) free((void*)(var)); var=0; }#define REASSIGN(var, val) { FREE(var); var=val; }// TODO: pack these in instance variablesstatic const char*          this_url = 0;static const LpgdvProtocol* this_protocol = 0;static const char*          this_username = 0;static const char*          this_password = 0;static const char*          this_host = 0;static int                  this_port = 0;static const char*          this_dir = 0;static void *               this_pdata = 0;/*****************************************************************************/static voiddir_leave_old(void){  ENTER("dir_leave_old()");  if(this_protocol && this_dir) {    DPRINTF("leaving [%s]\n", this_dir);    this_protocol->dir_leave_f(this_pdata, this_dir);  }  FREE(this_dir);  LEAVE;}static voidsite_leave_old(void){  ENTER("site_leave_old()");  dir_leave_old();  if(this_protocol && this_host) {    DPRINTF("leaving [%s]:%d\n", this_host, this_port);    this_protocol->site_leave_f(this_pdata, this_host, this_port);  }  FREE(this_host);  this_port = 0;  FREE(this_username);  FREE(this_password);  LEAVE;}static voidprotocol_leave_old(void){  ENTER("protocol_leave_old()");  site_leave_old();  if(this_protocol) {    DPRINTF("leaving [%s]\n", this_protocol->name);    this_protocol->protocol_uninit_f(this_pdata);  }  this_protocol = 0;  LEAVE;}static intprotocol_enter_new(const LpgdvProtocol* protocol){  ENTER("protocol_enter_new()");  int res = 0;  if(protocol) {    DPRINTF("entering [%s]\n", protocol->name);    this_pdata = protocol->protocol_init_f();    this_protocol = 0;    FREE(this_username);    FREE(this_password);    FREE(this_host);    FREE(this_dir);    this_port = 0;    if(this_pdata) {      this_protocol = protocol;      res = 1;    }  }  LEAVE;  return res;}static intsite_enter_new(const char* site_name, int port,	       const char* username, const char* password){  ENTER("site_enter_new()");  int res = 0;  if(site_name && this_protocol) {    DPRINTF("entering [%s];%d\n", site_name, port);    DPRINTF("login: usr=[%s] pwd=[%s]\n", username?username:"<>",	    password?password:"<>");    res = this_protocol->site_enter_f(this_pdata, site_name, port,				      username, password);    FREE(this_username);    FREE(this_password);    FREE(this_host);    FREE(this_dir);    this_port = 0;    if(res) {      this_host = strdup(site_name);      this_port = port;      this_username = strdup(username);      this_password = strdup(password);    }  }  LEAVE;  return res;}static intdir_enter_new(const char* dir_name){  ENTER("dir_enter_new()");  int res = 0;  if(dir_name && this_protocol) {    DPRINTF("entering [%s]\n", dir_name);    res = this_protocol->dir_enter_f(this_pdata, dir_name);    this_dir = res ? strdup(dir_name) : 0;  }  LEAVE;  return res;}/*****************************************************************************/static LpgdvStatusreload(const char* url, char** corrected_url, Parameters* params){  ENTER("reload()");  LpgdvStatus status = LPGDV_OK;  char* url_copy = 0;  const char* protocol_name;  const char* address;  char* p;  const LpgdvProtocol *protocol;  LpgdvSplittedUrl su;  int ok;  const char* dir_name = 0;  const char* item_name = 0;  LpgdvMimeTypeId mt_id;  if(url==0 || strlen(url)==0) {    DPRINTF("empty url\n");    status = LPGDV_ERROR_INVALID_URL;    goto done;  }  /* check against previous url */  if(this_url && !strcmp(url, this_url)) {    DPRINTF("same url\n");    goto done;  }  /* remember this url */  REASSIGN(this_url, strdup(url));  DPRINTF("url = [%s]\n", url);  /* split url into protocol an address */  url_copy = strdup(url);  p = strchr(url_copy, ':');  if(p) {    *p = 0;    protocol_name = url_copy;    address = p+1;  }  else if(params->protocol_default){    protocol_name = params->protocol_default;    address = url_copy;  }  else {    protocol_name = 0;  }  protocol = lpgdv_protocol_find(protocol_name);  if(protocol==0) {    WARNF("libpgdirview: "__FILE__": warning: unknown protocol: %s\n",	  protocol_name);    status = LPGDV_ERROR_UNKNOWN_PROTOCOL;    goto done;  }  DPRINTF("protocol = [%s]\n", protocol->name);  DPRINTF("address = [%s]\n", address);  ok = lpgdv_protocol_split_url(address, protocol, &su);  if(!ok) {    WARNF("warning: lpgdv_protocol_split_url() failed\n");    status = LPGDV_ERROR_INVALID_URL;    goto done;  }  DPRINTF("URL[%s] splitted:\n", url);  DPRINTF("  username  = [%s]\n", su.username ? su.username : "<>");  DPRINTF("  password  = [%s]\n", su.password ? su.password : "<>");  DPRINTF("  host      = [%s]\n", su.host ? su.host : "<>");  DPRINTF("  port      = %d\n",   su.port);  DPRINTF("  path      = [%s]\n", su.path ? su.path : "<>");  DPRINTF("  arguments = [%s]\n", su.arguments ? su.arguments : "<>");  REASSIGN(dir_name, protocol->getdirname_f(su.path));  REASSIGN(item_name, protocol->getitemname_f(su.path));  DPRINTF("  dir       = [%s]\n", dir_name ? dir_name : "<>");  DPRINTF("  item      = [%s]\n", item_name ? item_name : "<>");  mt_id = lpgdv_mime_type_id_of(item_name, -1);  DPRINTF("object=[%s] id=%d mime-type=[%s]\n",	  item_name ? item_name : "<>",	  mt_id, lpgdv_mime_type_name_of(mt_id));  /* another protocol ? */  if(this_protocol==0 || this_protocol!=protocol) {    protocol_leave_old();    protocol_enter_new(protocol);  }  /* another host ? */  if(protocol->has_host) {    if(this_host==0 ||       !protocol->is_same_site_f(this_host, su.host) ||       this_port != su.port) {      site_leave_old();      site_enter_new(su.host, su.port, su.username, su.password);    }  }  /* another dir ? */  DPRINTF(":::[%s][%s]\n", this_dir, dir_name);  if(this_dir==0 || !protocol->is_same_dir_f(this_dir, dir_name)) {    dir_leave_old();    dir_enter_new(dir_name);  }    /* TODO:   - init protocol   - enter site   - enter dir   - call function that browse dir for each item   - leave dir   - leave site   - uninit protocol  */  //#warning todo ... done:  FREE(url_copy);  FREE(dir_name);  FREE(item_name);  LEAVE;  return status;}/*****************************************************************************//* Main function */const char *dirview(const char *view_name,		    const char *url,		    ...){  pghandle wTB, wOk, wCancel, wUp;  struct pgEvent evt;  struct filepickdata dat;  int w,h;  char *p;  Parameters* params = 0;  MenuItemParams* menu_item_params = 0;  ColumnParams* column_params = 0;  LpgdvStatus status;  {    va_list va;    va_start(va, url);    status = va_parse_params(&params,			     &menu_item_params,			     &column_params,			     va);    va_end(va);  }  dump_params(params);  dump_menuitemparams(params->menu_items_nb, menu_item_params);  dump_columnparams(params->columns_nb, column_params);  /********* Set up dialog box and top-level widgets */  pgEnterContext(); {    /* Size the dialog box ourselves */    pgEnterContext(); {      pgSizeText(&w,&h,pgNewFont(NULL,0,PG_FSTYLE_DEFAULT | PG_FSTYLE_FLUSH),		 pgNewString("a"));  /* A good metric */    } pgLeaveContext();    /* Special fonts for directories and links */    dat.fDirectory = pgNewFont(NULL,0,PG_FSTYLE_DEFAULT | PG_FSTYLE_BOLD);    dat.fLink      = pgNewFont(NULL,0,PG_FSTYLE_DEFAULT | PG_FSTYLE_ITALIC);    dat.fHeading   = pgNewFont(NULL,0,PG_FSTYLE_DEFAULT | PG_FSTYLE_BOLD |			       PG_FSTYLE_UNDERLINE);    /* Make containers for the directory and file. They are ok without     * containers, but it looks better putting them in toolbars.     */    if(params->location_visible) {      wTB = pgNewWidget(PG_WIDGET_TOOLBAR,0,0);      pgSetWidget(PGDEFAULT,		  PG_WP_SIDE,PG_S_BOTTOM,		  0);    }    dat.wDirectory = pgNewWidget(PG_WIDGET_TOOLBAR,0,0);    pgSetWidget(PGDEFAULT,		PG_WP_SIDE,PG_S_TOP,		0);    dat.wScroll = pgNewWidget(PG_WIDGET_SCROLL,0,0);    dat.wFileList = pgNewWidget(PG_WIDGET_BOX,0,0);    pgSetWidget(PGDEFAULT,		PG_WP_SIDE,PG_S_ALL,		0);    pgSetWidget(dat.wScroll,		PG_WP_BIND,dat.wFileList,		0);    /* Put the file and directory in their toolbars */    /*    if (flags & PG_FILE_FIELD) {      dat.wFile = pgNewWidget(PG_WIDGET_FIELD,PG_DERIVE_INSIDE,wTB);      pgSetWidget(PGDEFAULT,		  PG_WP_SIDE,PG_S_ALL,		  0);      if (deffile)	pgSetWidget(PGDEFAULT,PG_WP_TEXT,pgNewString(deffile),0);    }    */    if(!params->list_do_include_parent) {      /* [..] button */      wUp = pgNewWidget(PG_WIDGET_BUTTON,			PG_DERIVE_INSIDE,dat.wDirectory);      pgSetWidget(PGDEFAULT,		  PG_WP_TEXT,pgNewString(".."),		0);    }    /* Title bar */    if(params->title_is_visible) {      dat.wDirectory = params->list_do_include_parent	? pgNewWidget(PG_WIDGET_BUTTON, PG_DERIVE_INSIDE,dat.wDirectory)	: pgNewWidget(PG_WIDGET_BUTTON, 0,0);      pgSetWidget(PGDEFAULT,		  PG_WP_SIDE,PG_S_ALL,		  PG_WP_EXTDEVENTS,PG_EXEV_PNTR_DOWN,		  0);      if(params->title) {	pgSetWidget(PGDEFAULT,		    PG_WP_TEXT,pgNewString(params->title),		    0);      }    }    /* url */    if(params->location_visible) {      dat.wFile = pgNewWidget(params->location_visible==EDITABLE			      ? PG_WIDGET_FIELD : PG_WIDGET_LABEL,			      PG_DERIVE_INSIDE,wTB);      pgSetWidget(PGDEFAULT, PG_WP_SIDE, PG_S_ALL, 0);      if(params->location_visible==EDITABLE) {	pgBind(PGDEFAULT,PG_WE_ACTIVATE,&location_activate,NULL);      }      if(url) {	pgSetWidget(PGDEFAULT,PG_WP_TEXT,pgNewString(url),0);      }    }    //pgEventLoop();    next_action = RELOAD; /* initial load */    do {      switch(next_action) {      case NONE:	break;      case RELOAD:	{	  const char* loc = url;	  if(dat.wFile) loc = pgGetString(pgGetWidget(dat.wFile,PG_WP_TEXT));	  reload(loc, 0, params);	}	break;      }      pgDispatchEvent(pgGetEvent());    } while (next_action != QUIT);  } pgLeaveContext();  /* Store picker data */  return dirview_buf;}/* The End */// main lib function call args:// - instance_name// - user_data// - fd_handler(fd, user_data, lib_data)// - taglist//// additional function calls:// - int handle_fd(fd)//// functions handlers can call:// - reparse_taglist(this, taglist)//// app messages:// - set_location(str)// - select_item(num)// - unselect_item(num)// - select_all// - unselect_all// - click(num)// - quit

⌨️ 快捷键说明

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