diff --git a/NEWS.md b/NEWS.md index 43f70b80..14d005ab 100644 --- a/NEWS.md +++ b/NEWS.md @@ -4,6 +4,7 @@ * [#119] check the return code of `setsockopt`. * [#?] switch to GTK+3, and use `GtkApplication`. * [#125] fix crash on UdpData::SomeoneSendmsg. +* [#140] fix crash on TransWindow::TerminateTransTask. * [#132] fix file accepted when cancel the directory chooser dialog. ### refactor diff --git a/src/iptux/CMakeLists.txt b/src/iptux/CMakeLists.txt index 74aed42d..a52c0e03 100644 --- a/src/iptux/CMakeLists.txt +++ b/src/iptux/CMakeLists.txt @@ -42,7 +42,7 @@ add_library(iptux utils.cpp wrapper.cpp WindowConfig.cpp - TransWindow.cpp TransWindow.h TransFileModel.cpp TransFileModel.h TransAbstract.cpp TransAbstract.h UiUtils.cpp UiUtils.h) + TransWindow.cpp TransWindow.h TransFileModel.cpp TransFileModel.h TransAbstract.cpp TransAbstract.h UiUtils.cpp UiUtils.h UiModels.h UiModels.cpp) add_executable(libiptux_test diff --git a/src/iptux/MainWindow.cpp b/src/iptux/MainWindow.cpp index 69cb3945..b8480173 100644 --- a/src/iptux/MainWindow.cpp +++ b/src/iptux/MainWindow.cpp @@ -31,13 +31,12 @@ #include "iptux/output.h" #include "iptux/TransWindow.h" #include "iptux/UiUtils.h" +#include "iptux/UiModels.h" using namespace std; namespace iptux { -static const int TRANS_TREE_MAX = 14; - /** * 类构造函数. */ @@ -85,7 +84,7 @@ void MainWindow::CreateWindow() { /* 创建主窗口 */ window = CreateMainWindow(); g_object_set_data(G_OBJECT(window), "iptux-config", &config); - g_object_set_data_full(G_OBJECT(window), "trans-model", CreateTransModel(), + g_object_set_data_full(G_OBJECT(window), "trans-model", trans_model_new(), GDestroyNotify(g_object_unref)); gtk_container_add(GTK_CONTAINER(window), CreateAllArea()); @@ -430,7 +429,7 @@ void MainWindow::UpdateItemToTransTree(const TransFileModel& para) { bool found = false; if (gtk_tree_model_get_iter_first(model, &iter)) { do { - gtk_tree_model_get(model, &iter, TRANS_TREE_MAX, &data, -1); + gtk_tree_model_get(model, &iter, TransModelColumn::PARA, &data, -1); if (gpointer(¶) == data) { found = true; break; @@ -439,7 +438,7 @@ void MainWindow::UpdateItemToTransTree(const TransFileModel& para) { } if (!found) { gtk_list_store_append(GTK_LIST_STORE(model), &iter); - gtk_list_store_set(GTK_LIST_STORE(model), &iter, TRANS_TREE_MAX, ¶, -1); + gtk_list_store_set(GTK_LIST_STORE(model), &iter, TransModelColumn::PARA, ¶, -1); } /** @@ -447,7 +446,7 @@ void MainWindow::UpdateItemToTransTree(const TransFileModel& para) { * 时应该清空参数指针值,以防止其他后来项误认此项为自己的大本营. */ if (!para.getData()) { - gtk_list_store_set(GTK_LIST_STORE(model), &iter, TRANS_TREE_MAX, NULL, -1); + gtk_list_store_set(GTK_LIST_STORE(model), &iter, TransModelColumn::PARA, NULL, -1); } /* 重设数据 */ @@ -475,7 +474,7 @@ bool MainWindow::TransmissionActive() { model = GTK_TREE_MODEL(g_object_get_data(G_OBJECT(window), "trans-model")); if (gtk_tree_model_get_iter_first(model, &iter)) { do { - gtk_tree_model_get(model, &iter, TRANS_TREE_MAX, &data, -1); + gtk_tree_model_get(model, &iter, TransModelColumn::PARA, &data, -1); if (data) break; } while (gtk_tree_model_iter_next(model, &iter)); } @@ -749,28 +748,6 @@ GtkTreeModel *MainWindow::CreatePallistModel() { return GTK_TREE_MODEL(model); } -/** - * 文件传输树(trans-tree)底层数据结构. - * 14,0 status,1 task,2 peer,3 ip,4 filename,5 filelength,6 finishlength,7 - * progress, 8 pro-text,9 cost,10 remain,11 rate,12,pathname,13 data,14 para \n - * 任务状态;任务类型;任务对端;文件名(如果当前是文件夹,该项指正在传输的文件夹内单个文件, - * 整个文件夹传输完成后,该项指向当前是文件夹);文件长度;完成长度;完成进度; - * 进度串;已花费时间;任务剩余时间;传输速度;带路径文件名(不显示);文件传输类;参数指针值 - * \n - * @return trans-model - */ -GtkTreeModel *MainWindow::CreateTransModel() { - GtkListStore *model; - - model = gtk_list_store_new(15, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, - G_TYPE_STRING, G_TYPE_INT, G_TYPE_STRING, - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, - G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_POINTER); - - return GTK_TREE_MODEL(model); -} - /** * 创建好友树(paltree). * @param model paltree-model diff --git a/src/iptux/MainWindow.h b/src/iptux/MainWindow.h index 74844fc3..9c59a005 100644 --- a/src/iptux/MainWindow.h +++ b/src/iptux/MainWindow.h @@ -97,7 +97,6 @@ class MainWindow { GtkTreeModel *CreatePaltreeModel(); GtkTreeModel *CreatePallistModel(); - GtkTreeModel *CreateTransModel(); GtkWidget *CreatePaltreeTree(GtkTreeModel *model); GtkWidget *CreatePallistTree(GtkTreeModel *model); diff --git a/src/iptux/RecvFileData.cpp b/src/iptux/RecvFileData.cpp index 6cb4537e..1f303038 100644 --- a/src/iptux/RecvFileData.cpp +++ b/src/iptux/RecvFileData.cpp @@ -371,7 +371,7 @@ void RecvFileData::UpdateUIParaToOver() { .setRate(""); file->finishedsize = file->filesize; } - para.setData(nullptr); + para.finish(); } -} // namespace iptux \ No newline at end of file +} // namespace iptux diff --git a/src/iptux/SendFileData.cpp b/src/iptux/SendFileData.cpp index cb493065..1841f8cb 100644 --- a/src/iptux/SendFileData.cpp +++ b/src/iptux/SendFileData.cpp @@ -329,7 +329,7 @@ void SendFileData::UpdateUIParaToOver() { .setRemain("") .setRate(""); } - para.setData(nullptr); + para.finish(); } } // namespace iptux diff --git a/src/iptux/TransFileModel.cpp b/src/iptux/TransFileModel.cpp index 44001386..9ee92f81 100644 --- a/src/iptux/TransFileModel.cpp +++ b/src/iptux/TransFileModel.cpp @@ -4,6 +4,14 @@ #include namespace iptux { + +TransFileModel::TransFileModel() +: fileLength(0), + finishedLength(0), + finished(false), + data(nullptr) { +} + TransFileModel& TransFileModel::setStatus(const std::string& value) { status = value; return *this; @@ -60,10 +68,16 @@ TransFileModel& TransFileModel::setFilePath(const std::string& value) { } TransFileModel& TransFileModel::setData(TransAbstract* value) { + g_assert_nonnull(value); data = value; return *this; } +void TransFileModel::finish() { + finished = true; + data = nullptr; +} + const std::string& TransFileModel::getStatus() const { return status; } @@ -133,4 +147,8 @@ int64_t TransFileModel::getFileLength() const { return fileLength; } -} \ No newline at end of file +bool TransFileModel::isFinished() const { + return finished; +} + +} diff --git a/src/iptux/TransFileModel.h b/src/iptux/TransFileModel.h index 760ae856..f66a233b 100644 --- a/src/iptux/TransFileModel.h +++ b/src/iptux/TransFileModel.h @@ -9,6 +9,8 @@ class TransAbstract; class TransFileModel { public: + TransFileModel(); + TransFileModel &setStatus(const std::string &value); TransFileModel &setTask(const std::string &value); TransFileModel &setPeer(const std::string &value); @@ -20,7 +22,14 @@ class TransFileModel { TransFileModel &setRemain(const std::string &value); TransFileModel &setRate(const std::string &value); TransFileModel &setFilePath(const std::string &value); + + /** + * + * @param value not null + * @return + */ TransFileModel &setData(TransAbstract *value); + void finish(); const std::string &getStatus() const; const std::string &getTask() const; @@ -37,6 +46,7 @@ class TransFileModel { const std::string &getRate() const; const std::string &getFilePath() const; TransAbstract *getData() const; + bool isFinished() const; private: std::string status; std::string task; @@ -49,6 +59,7 @@ class TransFileModel { std::string remain; std::string rate; std::string filePath; + bool finished; TransAbstract *data; }; diff --git a/src/iptux/TransWindow.cpp b/src/iptux/TransWindow.cpp index afbecfe4..9c07710a 100644 --- a/src/iptux/TransWindow.cpp +++ b/src/iptux/TransWindow.cpp @@ -8,13 +8,13 @@ #include "iptux/deplib.h" #include "iptux/TransAbstract.h" #include "iptux/UiUtils.h" +#include "output.h" +#include "UiModels.h" #define IPTUX_PRIVATE "iptux-private" namespace iptux { -static const int TRANS_TREE_MAX = 14; - class TransWindowPrivate { public: GtkWidget* transTreeviewWidget; @@ -27,7 +27,7 @@ class TransWindowPrivate { static gboolean TWinConfigureEvent(GtkWindow *window); static GtkWidget * CreateTransArea(GtkWindow* window); -static GtkWidget* CreateTransTree(GtkTreeModel *model); +static GtkWidget* CreateTransTree(TransWindow *window); static GtkWidget *CreateTransPopupMenu(GtkTreeModel *model); static void OpenThisFile(GtkTreeModel *model); static void ClearTransTask(GtkTreeModel *model); @@ -133,8 +133,7 @@ GtkWidget * CreateTransArea(GtkWindow* window) { gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_ETCHED_IN); gtk_box_pack_start(GTK_BOX(box), sw, TRUE, TRUE, 0); - model = trans_window_get_trans_model(window); - widget = CreateTransTree(model); + widget = CreateTransTree(window); gtk_container_add(GTK_CONTAINER(sw), widget); getPriv(window).transTreeviewWidget = widget; @@ -193,12 +192,13 @@ static gboolean TransPopupMenu(GtkWidget *treeview, * @param model trans-model * @return 传输树 */ -GtkWidget* CreateTransTree(GtkTreeModel *model) { +GtkWidget* CreateTransTree(TransWindow *window) { GtkWidget *view; GtkTreeViewColumn *column; GtkCellRenderer *cell; GtkTreeSelection *selection; + auto model = trans_window_get_trans_model(window); view = gtk_tree_view_new_with_model(model); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view), TRUE); gtk_tree_view_set_rubber_banding(GTK_TREE_VIEW(view), TRUE); @@ -208,67 +208,79 @@ GtkWidget* CreateTransTree(GtkTreeModel *model) { NULL); cell = gtk_cell_renderer_pixbuf_new(); - column = gtk_tree_view_column_new_with_attributes(_("State"), cell, "icon-name", - 0, NULL); + column = gtk_tree_view_column_new_with_attributes(_("State"), cell, + "icon-name", TransModelColumn::STATUS, + NULL); gtk_tree_view_column_set_resizable(column, TRUE); gtk_tree_view_append_column(GTK_TREE_VIEW(view), column); cell = gtk_cell_renderer_text_new(); - column = gtk_tree_view_column_new_with_attributes(_("Task"), cell, "text", 1, + column = gtk_tree_view_column_new_with_attributes(_("Task"), cell, + "text", TransModelColumn::TASK, NULL); gtk_tree_view_column_set_resizable(column, TRUE); gtk_tree_view_append_column(GTK_TREE_VIEW(view), column); cell = gtk_cell_renderer_text_new(); - column = gtk_tree_view_column_new_with_attributes(_("Peer"), cell, "text", 2, + column = gtk_tree_view_column_new_with_attributes(_("Peer"), cell, + "text", TransModelColumn::PEER, NULL); gtk_tree_view_column_set_resizable(column, TRUE); gtk_tree_view_append_column(GTK_TREE_VIEW(view), column); cell = gtk_cell_renderer_text_new(); - column = gtk_tree_view_column_new_with_attributes(_("IPv4"), cell, "text", 3, + column = gtk_tree_view_column_new_with_attributes(_("IPv4"), cell, + "text", TransModelColumn::IP, NULL); gtk_tree_view_column_set_resizable(column, TRUE); gtk_tree_view_append_column(GTK_TREE_VIEW(view), column); cell = gtk_cell_renderer_text_new(); - column = gtk_tree_view_column_new_with_attributes(_("Filename"), cell, "text", - 4, NULL); + column = gtk_tree_view_column_new_with_attributes(_("Filename"), cell, + "text", TransModelColumn::FILENAME, + NULL); gtk_tree_view_column_set_resizable(column, TRUE); gtk_tree_view_append_column(GTK_TREE_VIEW(view), column); cell = gtk_cell_renderer_text_new(); - column = gtk_tree_view_column_new_with_attributes(_("Size"), cell, "text", 5, + column = gtk_tree_view_column_new_with_attributes(_("Size"), cell, + "text", TransModelColumn::FILE_LENGTH_TEXT, NULL); gtk_tree_view_column_set_resizable(column, TRUE); gtk_tree_view_append_column(GTK_TREE_VIEW(view), column); cell = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes(_("Completed"), cell, - "text", 6, NULL); + "text", TransModelColumn::FINISHED_LENGTH_TEXT, + NULL); gtk_tree_view_column_set_resizable(column, TRUE); gtk_tree_view_append_column(GTK_TREE_VIEW(view), column); cell = gtk_cell_renderer_progress_new(); - column = gtk_tree_view_column_new_with_attributes( - _("Progress"), cell, "value", 7, "text", 8, NULL); + column = gtk_tree_view_column_new_with_attributes(_("Progress"), cell, + "value", TransModelColumn::PROGRESS, + "text", TransModelColumn::PROGRESS_TEXT, + NULL); gtk_tree_view_column_set_resizable(column, TRUE); gtk_tree_view_append_column(GTK_TREE_VIEW(view), column); cell = gtk_cell_renderer_text_new(); - column = gtk_tree_view_column_new_with_attributes(_("Cost"), cell, "text", 9, + column = gtk_tree_view_column_new_with_attributes(_("Cost"), cell, + "text", TransModelColumn::COST, NULL); gtk_tree_view_column_set_resizable(column, TRUE); gtk_tree_view_append_column(GTK_TREE_VIEW(view), column); cell = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes(_("Remaining"), cell, - "text", 10, NULL); + "text", TransModelColumn::REMAIN, + NULL); gtk_tree_view_column_set_resizable(column, TRUE); gtk_tree_view_append_column(GTK_TREE_VIEW(view), column); cell = gtk_cell_renderer_text_new(); - column = gtk_tree_view_column_new_with_attributes(_("Rate"), cell, "text", 11, + column = gtk_tree_view_column_new_with_attributes(_("Rate"), cell, + "text", TransModelColumn::RATE, NULL); gtk_tree_view_column_set_resizable(column, TRUE); gtk_tree_view_append_column(GTK_TREE_VIEW(view), column); @@ -288,7 +300,7 @@ static void OpenContainingFolder(GtkTreeModel *model) { "selected-path")))) return; gtk_tree_model_get_iter(model, &iter, path); - gtk_tree_model_get(model, &iter, 12, &filename, -1); + gtk_tree_model_get(model, &iter, TransModelColumn::FILE_PATH, &filename, -1); if (filename) { name = ipmsg_get_filename_me(filename, &filepath); if (!g_file_test(filepath, G_FILE_TEST_EXISTS)) { @@ -314,13 +326,26 @@ static void TerminateTransTask(GtkTreeModel *model) { GtkTreePath *path; GtkTreeIter iter; TransAbstract *trans; + gboolean finished; if (!(path = (GtkTreePath *)(g_object_get_data(G_OBJECT(model), "selected-path")))) return; gtk_tree_model_get_iter(model, &iter, path); - gtk_tree_model_get(model, &iter, 12, &trans, -1); - if (trans) trans->TerminateTrans(); + gtk_tree_model_get(model, &iter, + TransModelColumn ::DATA, &trans, + TransModelColumn ::FINISHED, &finished, + -1); + if(finished) { + return; + } + + if(!trans) { + LOG_WARN("task not finished but trans is not null"); + return; + } + + trans->TerminateTrans(); } @@ -334,7 +359,7 @@ static void TerminateAllTransTask(GtkTreeModel *model) { if (!gtk_tree_model_get_iter_first(model, &iter)) return; do { - gtk_tree_model_get(model, &iter, 12, &trans, -1); + gtk_tree_model_get(model, &iter, TransModelColumn ::DATA, &trans, -1); if (trans) trans->TerminateTrans(); } while (gtk_tree_model_iter_next(model, &iter)); } @@ -350,7 +375,7 @@ void ClearTransTask(GtkTreeModel *model) { if (!gtk_tree_model_get_iter_first(model, &iter)) return; do { mark: - gtk_tree_model_get(model, &iter, 12, &data, -1); + gtk_tree_model_get(model, &iter, TransModelColumn ::DATA, &data, -1); if (!data) { if (gtk_list_store_remove(GTK_LIST_STORE(model), &iter)) goto mark; break; @@ -369,16 +394,13 @@ GtkWidget *CreateTransPopupMenu(GtkTreeModel *model) { GtkTreePath *path; GtkTreeIter iter; - gchar *remaining; - gboolean sensitive = TRUE; + bool finished; if (!(path = (GtkTreePath *)(g_object_get_data(G_OBJECT(model), "selected-path")))) return NULL; gtk_tree_model_get_iter(model, &iter, path); - gtk_tree_model_get(model, &iter, 10, &remaining, -1); - - if (g_strcmp0(remaining, "")) sensitive = FALSE; + gtk_tree_model_get(model, &iter, TransModelColumn ::FINISHED, &finished, -1); menu = gtk_menu_new(); @@ -386,18 +408,19 @@ GtkWidget *CreateTransPopupMenu(GtkTreeModel *model) { gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); g_signal_connect_swapped(menuitem, "activate", G_CALLBACK(OpenThisFile), model); - gtk_widget_set_sensitive(GTK_WIDGET(menuitem), sensitive); + gtk_widget_set_sensitive(GTK_WIDGET(menuitem), finished); menuitem = gtk_menu_item_new_with_label(_("Open Containing Folder")); gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); g_signal_connect_swapped(menuitem, "activate", G_CALLBACK(OpenContainingFolder), model); - gtk_widget_set_sensitive(GTK_WIDGET(menuitem), sensitive); + gtk_widget_set_sensitive(GTK_WIDGET(menuitem), finished); menuitem = gtk_menu_item_new_with_label(_("Terminate Task")); gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); g_signal_connect_swapped(menuitem, "activate", G_CALLBACK(TerminateTransTask), model); + gtk_widget_set_sensitive(GTK_WIDGET(menuitem), !finished); menuitem = gtk_menu_item_new_with_label(_("Terminate All")); gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); @@ -425,7 +448,7 @@ void OpenThisFile(GtkTreeModel *model) { "selected-path")))) return; gtk_tree_model_get_iter(model, &iter, path); - gtk_tree_model_get(model, &iter, 12, &filename, -1); + gtk_tree_model_get(model, &iter, TransModelColumn ::FILE_PATH, &filename, -1); if (filename) { if (!g_file_test(filename, G_FILE_TEST_EXISTS)) { GtkWidget *dialog = gtk_message_dialog_new( @@ -458,7 +481,7 @@ gboolean UpdateTransUI(GtkWindow *window) { /* 更新UI */ do { - gtk_tree_model_get(model, &iter, TRANS_TREE_MAX - 1, &trans, -1); + gtk_tree_model_get(model, &iter, TransModelColumn ::DATA, &trans, -1); if (trans) { //当文件传输类存在时才能更新 const TransFileModel& transFileModel = trans->getTransFileModel(); //获取参数 UiUtils::applyTransFileModel2GtkListStore(transFileModel, GTK_LIST_STORE(model), &iter); diff --git a/src/iptux/UiModels.cpp b/src/iptux/UiModels.cpp new file mode 100644 index 00000000..0f9bc279 --- /dev/null +++ b/src/iptux/UiModels.cpp @@ -0,0 +1,29 @@ +#include "UiModels.h" + +namespace iptux { + +/** + * 文件传输树(trans-tree)底层数据结构. + * 14,0 status,1 task,2 peer,3 ip,4 filename,5 filelength,6 finishlength,7 + * progress, 8 pro-text,9 cost,10 remain,11 rate,12,pathname,13 data,14 para, 15 finished + * + * 任务状态;任务类型;任务对端;文件名(如果当前是文件夹,该项指正在传输的文件夹内单个文件, + * 整个文件夹传输完成后,该项指向当前是文件夹);文件长度;完成长度;完成进度; + * 进度串;已花费时间;任务剩余时间;传输速度;带路径文件名(不显示);文件传输类;参数指针值 + * + * @return trans-model + */ +TransModel* trans_model_new() { + GtkListStore *model; + + model = gtk_list_store_new(int(TransModelColumn::N_COLUMNS), + G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_STRING, G_TYPE_INT, G_TYPE_STRING, + G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_POINTER, + G_TYPE_BOOLEAN); + return GTK_TREE_MODEL(model); +} + +} diff --git a/src/iptux/UiModels.h b/src/iptux/UiModels.h new file mode 100644 index 00000000..5471f243 --- /dev/null +++ b/src/iptux/UiModels.h @@ -0,0 +1,23 @@ +#ifndef IPTUX_UIMODELS_H +#define IPTUX_UIMODELS_H + +#include + +namespace iptux { + +typedef GtkTreeModel TransModel; +TransModel* trans_model_new(); +enum class TransModelColumn { + STATUS, TASK, PEER, IP, FILENAME, + FILE_LENGTH_TEXT, FINISHED_LENGTH_TEXT, PROGRESS, PROGRESS_TEXT, COST, + REMAIN, RATE, FILE_PATH, DATA, PARA, + FINISHED, + N_COLUMNS +}; + + + + +} + +#endif //IPTUX_UIMODELS_H diff --git a/src/iptux/UiUtils.cpp b/src/iptux/UiUtils.cpp index 39bafe5c..0e08b6ba 100644 --- a/src/iptux/UiUtils.cpp +++ b/src/iptux/UiUtils.cpp @@ -1,5 +1,7 @@ #include "UiUtils.h" +#include "iptux/UiModels.h" + namespace iptux { void UiUtils::applyTransFileModel2GtkListStore( @@ -8,20 +10,21 @@ void UiUtils::applyTransFileModel2GtkListStore( GtkTreeIter *iter) { gtk_list_store_set( list_store, iter, - 0, para.getStatus().c_str(), - 1, para.getTask().c_str(), - 2, para.getPeer().c_str(), - 3, para.getIp().c_str(), - 4, para.getFilename().c_str(), - 5, para.getFileLengthText().c_str(), - 6, para.getFinishedLengthText().c_str(), - 7, int(para.getProgress()), - 8, g_strdup(para.getProgressText().c_str()), - 9, para.getCost().c_str(), - 10, para.getRemain().c_str(), - 11, para.getRate().c_str(), - 12, para.getFilePath().c_str(), - 13, para.getData(), + TransModelColumn::STATUS, para.getStatus().c_str(), + TransModelColumn::TASK, para.getTask().c_str(), + TransModelColumn::PEER, para.getPeer().c_str(), + TransModelColumn::IP, para.getIp().c_str(), + TransModelColumn::FILENAME, para.getFilename().c_str(), + TransModelColumn::FILE_LENGTH_TEXT, para.getFileLengthText().c_str(), + TransModelColumn::FINISHED_LENGTH_TEXT, para.getFinishedLengthText().c_str(), + TransModelColumn::PROGRESS, int(para.getProgress()), + TransModelColumn::PROGRESS_TEXT, g_strdup(para.getProgressText().c_str()), + TransModelColumn::COST, para.getCost().c_str(), + TransModelColumn::REMAIN, para.getRemain().c_str(), + TransModelColumn::RATE, para.getRate().c_str(), + TransModelColumn::FILE_PATH, para.getFilePath().c_str(), + TransModelColumn::DATA, para.getData(), + TransModelColumn::FINISHED, para.isFinished(), -1); } }