📄 transfer.cpp
字号:
/*************************************************** ** 文件名: transfer.cpp ** 建立日期: 2002年8月2日 ** 作者: 何林强 ** 描述: ****************************************************/#include "stdglo.h"extern Shftp_connect_info ftp_Connection_info[5];extern Shftp_pixmap filestyle[5];/**********************************************类Chftp_transfer部分************************/int Chftp_transfer::staterows=0; //底部状态栏从第零行开始添加.GtkWidget *Chftp_transfer::Filenotebook=NULL; //一个notebook对于共存的五个连接来说是共享的.Chftp_transfer::Chftp_transfer(GtkWidget *Filelist,Chftp_Filelist *p_Local, Chftp_Toolbar *hftp_Toolbar,Chftp_State *p_State, Chftp_Filedata *p_Localdata,gint index){ try{ GtkWidget *label; gint i; //成员变量初始化. if(!Filenotebook) Filenotebook=Filelist; Local=p_Local; StateBox=p_State; Localdata=p_Localdata; pageindex=index; sem_init(&bin_sem,0,0); mutitrans=-1; //传输一个文件夹时用于文件夹内文件的互斥量. conflict=NULL; timeout2=-1; for(i=0;i<5;i++){timeout3[i]=-1;} timeout4=-1; for(i=0;i<7;i++){ files[i]=new char[200]; if(!files[i]) throw Chftp_error("内存分配失败,请检查系统后,重启hFTP.");} filestree=NULL; currentfile=NULL; Remote_pop_menu_1=NULL; Remote_pop_menu_2=NULL; Local_pop_menu_1=NULL; Local_pop_menu_2=NULL; label=gtk_label_new(gtk_entry_get_text (GTK_ENTRY(GTK_COMBO(hftp_Toolbar->hftp_GetHostname())->entry))); if(!(Remote_Filelist=new Chftp_Filelist(Filelist,0,3,index))) throw Chftp_error("内存分配失败,请检查系统后,重启hFTP."); gtk_notebook_set_tab_label(GTK_NOTEBOOK(Filelist),gtk_notebook_get_nth_page (GTK_NOTEBOOK (Filelist), index), label); //为当前连接建立一新页. gtk_notebook_set_page(GTK_NOTEBOOK(Filelist),index); //把当前连接页置于最上层. if(!(Rfc959=new CRFC959(Remote_Filelist,hftp_Toolbar))) //建立一条ftp连接. throw Chftp_error("内存分配失败,请检查系统后,重启hFTP."); if(-2!=Rfc959->rfc959_list_files()) hftp_read_files(NULL,0); //列出服务器当前文件列表. else{ Remote_Filelist->hftp_AddStringToList("无法建立到达主机的连接,30秒后再试..."); timeout2=gtk_timeout_add(30000,Re_Connect,(gpointer)this); } mutex=1; //把这个初始化移往上面就会变为零,不知为何. gtk_signal_connect(GTK_OBJECT(GTK_COMBO(Remote_Filelist->hftp_GetCombo())->entry),"activate", GTK_SIGNAL_FUNC(hftp_getdir),(gpointer)this); gtk_signal_connect(GTK_OBJECT(Remote_Filelist->hftp_GetBackButton()),"clicked", GTK_SIGNAL_FUNC(hftp_backdir),(gpointer)this); gtk_signal_connect(GTK_OBJECT(Remote_Filelist->hftp_GetFreshButton()),"clicked", GTK_SIGNAL_FUNC(hftp_Refresh),(gpointer)this); gtk_signal_connect(GTK_OBJECT(Remote_Filelist->hftp_GetShutButton()),"clicked", GTK_SIGNAL_FUNC(hftp_shut_down),(gpointer)this); gtk_signal_connect(GTK_OBJECT(Local->hftp_GetClist()),"button_press_event", GTK_SIGNAL_FUNC(hftp_list_dbclick_local),(gpointer)this); gtk_signal_connect(GTK_OBJECT(Remote_Filelist->hftp_GetClist()),"button_press_event", GTK_SIGNAL_FUNC(hftp_list_dbclick_remote),(gpointer)this); gtk_signal_connect(GTK_OBJECT(Local->hftp_GetClist()), "drag_data_get", GTK_SIGNAL_FUNC (Locallistbox_drag), (gpointer)this); gtk_signal_connect(GTK_OBJECT(Remote_Filelist->hftp_GetClist()),"drag_data_get", GTK_SIGNAL_FUNC (Remotelistbox_drag),(gpointer)this); timeout1=gtk_timeout_add(30000,idle_function,(gpointer)this); //定时调用保活函数. } catch(Chftp_error& badalloc){ badalloc.messagebox(); }}Chftp_transfer::~Chftp_transfer(){ if(Remote_Filelist) delete Remote_Filelist; if(Remote_pop_menu_1) delete Remote_pop_menu_1; if(Remote_pop_menu_2) delete Remote_pop_menu_2; if(Local_pop_menu_1) delete Local_pop_menu_1; if(Local_pop_menu_2) delete Local_pop_menu_2; if(conflict) delete conflict; if(Rfc959) delete Rfc959; for(gint i=0;i<7;i++) if(files[i]) delete files[i];}/************************************************到主机的连接暂时不可到达,隔30秒再试.***********************************************/gint Chftp_transfer::Re_Connect(gpointer data){ if(((Chftp_transfer *)data)->Rfc959->login_dialog){ delete ((Chftp_transfer *)data)->Rfc959->login_dialog; ((Chftp_transfer *)data)->Rfc959->login_dialog=NULL;} for(gint i=0;i<5;i++) if(0!=ftp_Connection_info[i].state){ if(ftp_Connection_info[i].ftp_Connection) delete ftp_Connection_info[i].ftp_Connection; ftp_Connection_info[i].ftp_Connection=NULL; ftp_Connection_info[i].state=0; } if(((Chftp_transfer *)data)->Rfc959->rfc959_Connect()>=0){ if(-2!=((Chftp_transfer *)data)->Rfc959->rfc959_list_files()){ ((Chftp_transfer *)data)->hftp_read_files(NULL,0); return 0;} } ((Chftp_transfer *)data)->Rfc959->rfc959_disconnect(); ((Chftp_transfer *)data)->Remote_Filelist-> hftp_AddStringToList("无法建立到达主机的连接,30秒再试..."); return 1;}/************************************** ** 定时调用Rfc959中的保活函数。 *************************************/gint Chftp_transfer::idle_function(gpointer data){ if(0==(((Chftp_transfer *)data)->mutex)) return 1; if(NULL!=((Chftp_transfer *)data)->Rfc959->Connect_data->datafd) return 1; if(((Chftp_transfer *)data)->Rfc959->downnow==1) return 1; ((Chftp_transfer *)data)->mutex=0; ((Chftp_transfer *)data)->Rfc959->idle_function(); ((Chftp_transfer *)data)->mutex=1; return 1; }/*********************************************** **根据组合框中输入的路径,得到改路径的文件列表 ***********************************************/void Chftp_transfer::hftp_getdir(GtkWidget *TheWindow,gpointer data){ if(0==strcmp(((Chftp_transfer *)data)->Rfc959->Connect_data->directory, gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(((Chftp_transfer *)data) ->Remote_Filelist->hftp_GetCombo())->entry)))) return; //如果发现工作路径没有改变,则直接返回. strcpy(((Chftp_transfer *)data)->Rfc959->Connect_data->directory, gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(((Chftp_transfer *)data) ->Remote_Filelist->hftp_GetCombo())->entry))); if(-2!=(((Chftp_transfer *)data)->Rfc959->rfc959_chdir())){ if(-2!=(((Chftp_transfer *)data)->Rfc959->rfc959_list_files())) ((Chftp_transfer *)data)->hftp_read_files(NULL,0); } return;} /******************************************** **后退按钮的处理函数. *******************************************/void Chftp_transfer::hftp_backdir(GtkWidget *TheWindow,gpointer data){ if(0==(((Chftp_transfer *)data)->mutex)) return; ((Chftp_transfer *)data)->mutex=0; strcpy(((Chftp_transfer *)data)->Rfc959->Connect_data->directory,".."); if(-2!=((Chftp_transfer *)data)->Rfc959->rfc959_chdir()){ if(-2!=(((Chftp_transfer *)data)->Rfc959->rfc959_list_files())) ((Chftp_transfer *)data)->hftp_read_files(NULL,0); } ((Chftp_transfer *)data)->mutex=1; return;}/***************************************************** ** 刷新远程文件列表. ****************************************************/void Chftp_transfer::hftp_Refresh(GtkWidget *TheWindow,gpointer data){ if(0==(((Chftp_transfer *)data)->mutex)) return; ((Chftp_transfer *)data)->mutex=0; if(-2!=((Chftp_transfer *)data)->Rfc959->rfc959_chdir()){ if(-2!=(((Chftp_transfer *)data)->Rfc959->rfc959_list_files())) ((Chftp_transfer *)data)->hftp_read_files(NULL,0); } else{ Re_Connect(data); } ((Chftp_transfer *)data)->mutex=1; return;}/**************************************************** **关闭本连接 *************************************************/void Chftp_transfer::hftp_shut_down(GtkWidget *TheWindow,gpointer data){ gint i=gtk_notebook_current_page(GTK_NOTEBOOK(Filenotebook)); gtk_notebook_remove_page(GTK_NOTEBOOK(Filenotebook),i); ftp_Connection_info[((Chftp_transfer *)data)->pageindex].state=-1; gtk_timeout_remove(((Chftp_transfer *)data)->timeout1); if(((Chftp_transfer *)data)->timeout2>=0) gtk_timeout_remove(((Chftp_transfer *)data)->timeout2); for(gint i=0;i<5;i++){ if(((Chftp_transfer *)data)->timeout3[i]>=0) gtk_timeout_remove(((Chftp_transfer *)data)->timeout3[i]);} if(((Chftp_transfer *)data)->timeout4>=0) gtk_timeout_remove(((Chftp_transfer *)data)->timeout4);}/****************************************** **双击本地文件列表框中一个文件,则文件上传 ******************************************/void Chftp_transfer::hftp_list_dbclick_local(GtkWidget *widget, GdkEventButton *event,gpointer data){ if(((Chftp_transfer *)data)->pageindex!= gtk_notebook_current_page(GTK_NOTEBOOK(Filenotebook))) return; //本地文件的操作必须对应于当前活动页的远程连接. gint row,column; gchar filetype[6]; guint8 for_pix; if(GDK_2BUTTON_PRESS==event->type && 1==event->button){ //鼠标双击事件. if(0==(((Chftp_transfer *)data)->mutex)) return; //相当于互斥量,不能保证完全安全,但也是无奈之举. ((Chftp_transfer *)data)->mutex=0; gtk_clist_get_selection_info(GTK_CLIST(widget),(int)event->x,(int)event->y,&row,&column); if(0==gtk_clist_get_text(GTK_CLIST(widget),row,1,&(((Chftp_transfer *)data)->filename_text))){ ((Chftp_transfer *)data)->mutex=1; return; } if(0==strcmp(((Chftp_transfer *)data)->filename_text,"文件")){ //双击文件,则文件上传. ((Chftp_transfer *)data)->upload_a_file(widget,row); } else ((Chftp_transfer *)data)->mutex=1; } else if(GDK_BUTTON_PRESS==event->type && 1==event->button){//处理鼠标单击事件是为拖的操作作准备. if(0==(((Chftp_transfer *)data)->mutex)) return; gtk_clist_get_selection_info(GTK_CLIST(widget),(int)event->x,(int)event->y,&row,&column); ((Chftp_transfer *)data)->is_dir=3; if(0==gtk_clist_get_text(GTK_CLIST(widget),row,1,&(((Chftp_transfer *)data)->filename_text))) ((Chftp_transfer *)data)->is_dir=3; //当前没有选中一项,鼠标点在空白处. else{ if(0==strcmp(((Chftp_transfer *)data)->filename_text,"文件")) ((Chftp_transfer *)data)->is_dir=0; //当前选中的为文件. else if(0==strcmp(((Chftp_transfer *)data)->filename_text,"目录")) ((Chftp_transfer *)data)->is_dir=1; gtk_clist_get_pixtext(GTK_CLIST(widget),row,0,&(((Chftp_transfer *)data)->filename_text),&for_pix,NULL,NULL); } } else if(GDK_BUTTON_PRESS==event->type && 3==event->button){ if(0==(((Chftp_transfer *)data)->mutex)) return; gtk_clist_get_selection_info(GTK_CLIST(widget),(int)event->x,(int)event->y,&row,&column); if(0==gtk_clist_get_text(GTK_CLIST(widget),row,1,&(((Chftp_transfer *)data)->filename_text))){ if(((Chftp_transfer *)data)->Local_pop_menu_1){ delete ((Chftp_transfer *)data)->Local_pop_menu_1; ((Chftp_transfer *)data)->Local_pop_menu_1=NULL; } ((Chftp_transfer *)data)->Local_pop_menu_1=new Chftp_Local_menu_1(data); } else{ strcpy(filetype,((Chftp_transfer *)data)->filename_text); gtk_clist_get_pixtext(GTK_CLIST(widget),row,0,&(((Chftp_transfer *)data)->filename_text),&for_pix,NULL,NULL); if(((Chftp_transfer *)data)->Local_pop_menu_2){ delete ((Chftp_transfer *)data)->Local_pop_menu_2; ((Chftp_transfer *)data)->Local_pop_menu_2=NULL; } ((Chftp_transfer *)data)->Local_pop_menu_2=new Chftp_Local_menu_2(data,filetype); } }}/**************************************************************** **本地文件列表框里的拖放操作 ***************************************************************/void Chftp_transfer::Locallistbox_drag(GtkWidget *widget, GdkDragContext *context, GtkSelectionData *selection_data,guint info,guint32 clk_time, gpointer data){ try{ if(((Chftp_transfer *)data)->pageindex!= gtk_notebook_current_page(GTK_NOTEBOOK(Filenotebook))) return; //本地文件的操作必须对应于当前活动页的远程连接. if(0==(((Chftp_transfer *)data)->mutex)) return; if(3==((Chftp_transfer *)data)->is_dir) return; ((Chftp_transfer *)data)->mutex=0; if(0==((Chftp_transfer *)data)->is_dir){ //拖动的是一个文件. ((Chftp_transfer *)data)->upload_a_file(widget,-1); } else if(1==((Chftp_transfer *)data)->is_dir){ //拖动的是一个目录. ((Chftp_transfer *)data)->uploaddir=new char[350]; //用于记录目录下文件的绝对路径. strcpy(((Chftp_transfer *)data)->uploaddir,((Chftp_transfer *)data)->Localdata->hftp_GetCurrent_dir()); ((Chftp_transfer *)data)->mutitrans=1; //用于一个目录中各个文件之间的互斥量. ((Chftp_transfer *)data)->position=-1; ((Chftp_transfer *)data)->Rfc959->downnow=1; ((Chftp_transfer *)data)->tag=1; if(!(((Chftp_transfer *)data)->filestree=new Ctransfer_files)) //整个目录树结构. throw Chftp_error("内存分配失败,请检查系统后,重启hFTP."); ((Chftp_transfer *)data)->currentfile=((Chftp_transfer *)data)->filestree;//遍历指针. ((Chftp_transfer *)data)->Localdata->get_upload_dir (&(((Chftp_transfer *)data)->filestree),//获取要上传的整个目录树. ((Chftp_transfer *)data)->filename_text); ((Chftp_transfer *)data)->search_a_function(); //为当前多文件传输选择一个定时函数. } } catch(Chftp_error& badalloc){ badalloc.messagebox(); }}void Chftp_transfer::upload_a_file(GtkWidget *widget,gint row){ guint8 for_pix; if(row>0){ gtk_clist_get_pixtext(GTK_CLIST(widget),row,0,&filename_text,&for_pix,NULL,NULL); position=-1; //将在状态栏里为显示其状态新加一栏. } if(-1==row) position=-1; strcpy(fulldir,Localdata->hftp_GetCurrent_dir()); strcat(fulldir,"/"); strcat(fulldir,filename_text); donesize=0; //上传无续传功能. tag=1; //当前工作方式为上传. progress=0; //进度为零. create_transfer(filename_text,fulldir,0); return;}/******************************************************* 双击远程文件列表框中的文件,则下载*****************************************************/void Chftp_transfer::hftp_list_dbclick_remote(GtkWidget *widget, GdkEventButton *event, gpointer data){ gint row,column; gchar filetype[6]; guint8 for_pix=1; if(event->type == GDK_2BUTTON_PRESS && event->button == 1){ //鼠标双击事件. if(0==(((Chftp_transfer *)data)->mutex)) return; ((Chftp_transfer *)data)->mutex=0; gtk_clist_get_selection_info(GTK_CLIST(widget),(int)event->x,(int)event->y,&row,&column); if(0==gtk_clist_get_text(GTK_CLIST(widget),row,1,&(((Chftp_transfer *)data)->filename_text))){ ((Chftp_transfer *)data)->mutex=1; return;} if(0==strcmp(((Chftp_transfer *)data)->filename_text,"目录")){ //双击目录,则列出该目录下的所有文件。 gtk_clist_get_pixtext(GTK_CLIST(widget),row,0,&(((Chftp_transfer *)data)->filename_text),&for_pix,NULL,NULL); strcpy(((Chftp_transfer *)data)->Rfc959->Connect_data->directory,"./"); strcat(((Chftp_transfer *)data)->Rfc959->Connect_data->directory, ((Chftp_transfer *)data)->filename_text); if(-2!=((Chftp_transfer *)data)->Rfc959->rfc959_chdir()){ if(-2!=(((Chftp_transfer *)data)->Rfc959->rfc959_list_files())) ((Chftp_transfer *)data)->hftp_read_files(NULL,0); } ((Chftp_transfer *)data)->mutex=1; } else if(0==strcmp(((Chftp_transfer *)data)->filename_text,"文件")){ //双击文件,则开始传输该文件。 ((Chftp_transfer *)data)->tag=0; //当前工作方式为下载. gtk_clist_get_pixtext(GTK_CLIST(widget),row,0, &(((Chftp_transfer *)data)->filename_text),&for_pix,NULL,NULL); //获取文件名。 ((Chftp_transfer *)data)->position=-1; strcpy(((Chftp_transfer *)data)->fulldir,((Chftp_transfer *)data)->Localdata->hftp_GetCurrent_dir()); strcat(((Chftp_transfer *)data)->fulldir, "/"); strcat(((Chftp_transfer *)data)->fulldir,((Chftp_transfer *)data)->filename_text); if(-2!=(((Chftp_transfer *)data)->donesize=((Chftp_transfer *)data)-> //存在同名文件. Localdata->hftp_Getfilesize(((Chftp_transfer *)data)->fulldir))){ if(((Chftp_transfer *)data)->conflict) delete ((Chftp_transfer *)data)->conflict; ((Chftp_transfer *)data)->conflict=new Chftp_conflict_dialog(data);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -