📄 transport.cpp
字号:
uint32_t oldSize, downSize; struct timeval val1, val2; char *ptr1, *ptr2; float difftime; gint terminate; ssize_t size; if (offset == filesize) { gdk_threads_enter(); gtk_list_store_set(GTK_LIST_STORE(trans_model), iter, 7, 100, -1); gdk_threads_leave(); return filesize; } oldSize = downSize = offset; gettimeofday(&val1, NULL); do { size = (MAX_SOCKBUF < filesize - downSize) ? MAX_SOCKBUF : filesize - downSize; if ((size = Read(sock, buf, size)) == -1) return downSize; if (size > 0 && Write(fd, buf, size) == -1) return downSize; downSize += size; gettimeofday(&val2, NULL); difftime = difftimeval(val2, val1); if (difftime >= 1) { ptr1 = number_to_string(downSize); ptr2 = number_to_string((uint32_t) ((downSize - oldSize) / difftime), true); gdk_threads_enter(); gtk_list_store_set(GTK_LIST_STORE(trans_model), iter, 4, ptr1, 6, ptr2, 7, GINT(percent(downSize, filesize)), -1); gtk_tree_model_get(trans_model, iter, 8, &terminate, -1); gdk_threads_leave(); g_free(ptr1), g_free(ptr2); if (terminate == -1) return downSize; val1 = val2; oldSize = downSize; } } while (size && downSize < filesize); ptr1 = number_to_string(downSize); gdk_threads_enter(); gtk_list_store_set(GTK_LIST_STORE(trans_model), iter, 4, ptr1, 7, GINT(percent(downSize, filesize)), -1); gdk_threads_leave(); free(ptr1); return downSize;}void Transport::SendFileData(int sock, GtkTreeIter * iter){ gchar *filename, *pathname; char buf[MAX_SOCKBUF]; uint32_t filesize, size; my_file mf(false); int fd; gdk_threads_enter(); gtk_tree_model_get(trans_model, iter, 2, &filename, 11, &filesize, 13, &pathname, -1); gdk_threads_leave(); mf.chdir(pathname); fd = mf.open(filename, O_RDONLY | O_LARGEFILE); g_free(filename), g_free(pathname); if (fd == -1) { EndTransportData(-1, -1, iter, __TIP_DIR "/error.png"); return; } size = SendData(sock, fd, iter, filesize, buf); if (size >= filesize) EndTransportData(-1, fd, iter, __TIP_DIR "/finish.png"); else EndTransportData(-1, fd, iter, __TIP_DIR "/error.png");}void Transport::SendDirFiles(int sock, GtkTreeIter * iter){ gchar *dirname, *pathname, *filename; char buf[MAX_SOCKBUF], *ptr; my_file mf(false); gint terminate; GQueue *dir_stack; struct dirent *dirt, vdirt; struct stat64 st; uint32_t headsize; bool result; DIR *dir; Pal *pal; int fd; gdk_threads_enter(); gtk_tree_model_get(trans_model, iter, 2, &dirname, 13, &pathname, 14, &pal, -1); gdk_threads_leave(); mf.chdir(pathname), g_free(pathname); result = false, dir = NULL; strcpy(vdirt.d_name, dirname), dirt = &vdirt; dir_stack = g_queue_new(); goto start; while (!g_queue_is_empty(dir_stack)) { dir = (DIR *) g_queue_pop_head(dir_stack); while (dir && (dirt = readdir(dir))) { if (strcmp(dirt->d_name, ".") == 0 || strcmp(dirt->d_name, "..") == 0) continue; start: if (mf.stat(dirt->d_name, &st) == -1 || !S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode)) continue; ptr = number_to_string(st.st_size); gdk_threads_enter(); gtk_list_store_set(GTK_LIST_STORE(trans_model), iter, 2, dirt->d_name, 4, "0B", 5, ptr, 6, "0B/s", 7, 0, -1); gtk_tree_model_get(trans_model, iter, 8, &terminate, -1); gdk_threads_leave(); free(ptr); if (terminate == -1) goto end; pathname = transfer_encode(dirt->d_name, pal->encode, true); filename = ipmsg_set_filename_pal(pathname); snprintf(buf, MAX_SOCKBUF, "000:%s:%x:%x:", filename, (uint32_t) st.st_size, S_ISREG(st.st_mode) ? IPMSG_FILE_REGULAR : IPMSG_FILE_DIR); free(filename), free(pathname); headsize = strlen(buf); snprintf(buf, MAX_SOCKBUF, "%.3x", headsize); *(buf + strlen(buf)) = ':'; if (Write(sock, buf, headsize) == -1) goto end; if (S_ISREG(st.st_mode)) { if ((fd = mf.open(dirt->d_name, O_RDONLY | O_LARGEFILE)) == -1) goto end; headsize = SendData(sock, fd, iter, (uint32_t) st.st_size, buf); close(fd); if (headsize < st.st_size) goto end; } else if (S_ISDIR(st.st_mode)) { mf.chdir(dirt->d_name); if (dir) g_queue_push_head(dir_stack, dir); if (!(dir = mf.opendir())) goto end; } } closedir(dir), dir = NULL; snprintf(buf, MAX_SOCKBUF, "000:.:0:%x:", IPMSG_FILE_RETPARENT); headsize = strlen(buf); snprintf(buf, MAX_SOCKBUF, "%.3x", headsize); *(buf + strlen(buf)) = ':'; if (Write(sock, buf, headsize) == -1) goto end; mf.chdir(".."); } result = true; end: if (result) { EndTransportData(-1, -1, iter, __TIP_DIR "/finish.png"); EndTransportDirFiles(iter, dirname); } else { closedir(dir); g_queue_foreach(dir_stack, GFunc(closedir), NULL); g_queue_clear(dir_stack); EndTransportData(-1, -1, iter, __TIP_DIR "/error.png"); g_free(dirname); } g_queue_free(dir_stack);}uint32_t Transport::SendData(int sock, int fd, GtkTreeIter * iter, uint32_t filesize, char *buf){ uint32_t oldSize, sendSize; struct timeval val1, val2; char *ptr1, *ptr2; float difftime; gint terminate; ssize_t size; if (filesize == 0) { gdk_threads_enter(); gtk_list_store_set(GTK_LIST_STORE(trans_model), iter, 7, 100, -1); gdk_threads_leave(); return 0; } oldSize = sendSize = 0; gettimeofday(&val1, NULL); do { if ((size = Read(fd, buf, MAX_SOCKBUF)) == -1) return sendSize; if (size > 0 && Write(sock, buf, size) == -1) return sendSize; sendSize += size; gettimeofday(&val2, NULL); difftime = difftimeval(val2, val1); if (difftime >= 1) { ptr1 = number_to_string(sendSize); ptr2 = number_to_string((uint32_t) ((sendSize - oldSize) / difftime), true); gdk_threads_enter(); gtk_list_store_set(GTK_LIST_STORE(trans_model), iter, 4, ptr1, 6, ptr2, 7, GINT(percent(sendSize, filesize)), -1); gtk_tree_model_get(trans_model, iter, 8, &terminate, -1); gdk_threads_leave(); g_free(ptr1), g_free(ptr2); if (terminate == -1) return sendSize; val1 = val2; oldSize = sendSize; } } while (size); ptr1 = number_to_string(sendSize); gdk_threads_enter(); gtk_list_store_set(GTK_LIST_STORE(trans_model), iter, 4, ptr1, 7, GINT(percent(sendSize, filesize)), -1); gdk_threads_leave(); free(ptr1); return sendSize;}void Transport::EndTransportData(int sock, int fd, GtkTreeIter * iter, const char *pathname){ GdkPixbuf *pixbuf; close(sock), close(fd); gdk_threads_enter(); pixbuf = gdk_pixbuf_new_from_file(pathname, NULL); gtk_list_store_set(GTK_LIST_STORE(trans_model), iter, 0, pixbuf, 8, 1, -1); if (pixbuf) g_object_unref(pixbuf); gdk_threads_leave();}void Transport::EndTransportDirFiles(GtkTreeIter * iter, char *filename){ gdk_threads_enter(); gtk_list_store_set(GTK_LIST_STORE(trans_model), iter, 2, filename, 4, _("unknown"), 5, _("unknown"), -1); gtk_tree_view_columns_autosize(GTK_TREE_VIEW(trans_view)); gdk_threads_leave(); free(filename);}GtkWidget *Transport::CreatePopupMenu(gpointer data){ GtkWidget *menu, *menu_item; menu = gtk_menu_new(); gtk_widget_show(menu); menu_item = gtk_menu_item_new_with_label(_("Terminate Job")); g_signal_connect_swapped(menu_item, "activate", G_CALLBACK(StopTask), data); gtk_widget_show(menu_item); gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item); menu_item = gtk_menu_item_new_with_label(_("Terminate All")); g_signal_connect_swapped(menu_item, "activate", G_CALLBACK(StopAllTask), data); gtk_widget_show(menu_item); gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item); menu_item = gtk_menu_item_new_with_label(_("Clear Tasklist")); g_signal_connect_swapped(menu_item, "activate", G_CALLBACK(Transport::TidyTask), data); gtk_widget_show(menu_item); gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item); return menu;}void Transport::DestroyDialog(){ extern Transport trans; trans.transport = NULL; trans.trans_view = NULL;}gboolean Transport::PopupControlMenu(GtkWidget * view, GdkEventButton * event, gpointer data){ GtkTreePath *path; if (event->button != 3) return FALSE; if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(view), GINT(event->x), GINT(event->y), &path, NULL, NULL, NULL)) { ((Transport *) data)->flag = true; gtk_tree_model_get_iter(((Transport *) data)->trans_model, &((Transport *) data)->opt_iter, path); gtk_tree_path_free(path); } else ((Transport *) data)->flag = false; gtk_menu_popup(GTK_MENU(CreatePopupMenu(data)), NULL, NULL, NULL, NULL, event->button, event->time); return TRUE;}void Transport::StopTask(gpointer data){ if (!((Transport *) data)->flag) return; gtk_list_store_set(GTK_LIST_STORE(((Transport *) data)->trans_model), &((Transport *) data)->opt_iter, 8, -1, -1);}void Transport::StopAllTask(gpointer data){ GtkTreeIter iter; if (!gtk_tree_model_get_iter_first (((Transport *) data)->trans_model, &iter)) return; do { gtk_list_store_set(GTK_LIST_STORE (((Transport *) data)->trans_model), &iter, 8, -1, -1); } while (gtk_tree_model_iter_next (((Transport *) data)->trans_model, &iter));}void Transport::TidyTask(gpointer data){ gboolean result; gint terminate; GtkTreeIter iter; if (!gtk_tree_model_get_iter_first (((Transport *) data)->trans_model, &iter)) return; do { mark: gtk_tree_model_get(((Transport *) data)->trans_model, &iter, 8, &terminate, -1); if (terminate == 1) { result = gtk_list_store_remove(GTK_LIST_STORE (((Transport *) data)->trans_model), &iter); if (result) goto mark; break; } } while (gtk_tree_model_iter_next (((Transport *) data)->trans_model, &iter)); gtk_tree_view_columns_autosize(GTK_TREE_VIEW (((Transport *) data)->trans_view));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -