Changeset 5003
- Timestamp:
- Feb 10, 2008, 10:25:42 PM (14 years ago)
- Location:
- trunk/gtk
- Files:
-
- 2 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/gtk/Makefile.am
r4970 r5003 19 19 io.h \ 20 20 ipc.h \ 21 file-list.h \ 21 22 lock.h \ 22 23 logo.h \ … … 41 42 conf.c \ 42 43 dialogs.c \ 44 file-list.c \ 43 45 hig.c \ 44 46 io.c \ -
trunk/gtk/torrent-inspector.c
r4962 r5003 1 /****************************************************************************** 1 /* 2 * This file Copyright (C) 2007-2008 Charles Kerr <charles@rebelbase.com> 3 * 4 * This file is licensed by the GPL version 2. Works owned by the 5 * Transmission project are granted a special exemption to clause 2(b) 6 * so that the bulk of its code can remain under the MIT license. 7 * This exemption does not extend to derived works not owned by 8 * the Transmission project. 9 * 2 10 * $Id$ 3 * 4 * Copyright (c) 2005-2008 Transmission authors and contributors 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 * DEALINGS IN THE SOFTWARE. 23 *****************************************************************************/ 11 */ 24 12 25 13 #include <stddef.h> … … 32 20 33 21 #include "actions.h" 22 #include "file-list.h" 34 23 #include "tr_torrent.h" 35 24 #include "hig.h" … … 907 896 } 908 897 909 /****910 ***** FILES TAB911 ****/912 913 #define STRIPROOT( path ) \914 ( g_path_is_absolute( (path) ) ? g_path_skip_root( (path) ) : (path) )915 916 enum917 {918 FC_STOCK,919 FC_LABEL,920 FC_PROG,921 FC_KEY,922 FC_INDEX,923 FC_SIZE,924 FC_PRIORITY,925 FC_ENABLED,926 N_FILE_COLS927 };928 929 typedef struct930 {931 TrTorrent * gtor;932 GtkTreeModel * model; /* same object as store, but recast */933 GtkTreeStore * store; /* same object as model, but recast */934 }935 FileData;936 937 static const char*938 priorityToString( const int priority )939 {940 switch( priority ) {941 case TR_PRI_HIGH: return _("High");942 case TR_PRI_NORMAL: return _("Normal");943 case TR_PRI_LOW: return _("Low");944 default: return "BUG!";945 }946 }947 948 static tr_priority_t949 stringToPriority( const char* str )950 {951 if( !strcmp( str, _( "High" ) ) ) return TR_PRI_HIGH;952 if( !strcmp( str, _( "Low" ) ) ) return TR_PRI_LOW;953 return TR_PRI_NORMAL;954 }955 956 static void957 parsepath( const tr_torrent * tor,958 GtkTreeStore * store,959 GtkTreeIter * ret,960 const char * path,961 int index,962 uint64_t size )963 {964 GtkTreeModel * model;965 GtkTreeIter * parent, start, iter;966 char * file, * lower, * mykey, *escaped=0;967 const char * stock;968 int priority = 0;969 gboolean enabled = TRUE;970 971 model = GTK_TREE_MODEL( store );972 parent = NULL;973 file = g_path_get_basename( path );974 if( 0 != strcmp( file, path ) )975 {976 char * dir = g_path_get_dirname( path );977 parsepath( tor, store, &start, dir, index, size );978 parent = &start;979 g_free( dir );980 }981 982 lower = g_utf8_casefold( file, -1 );983 mykey = g_utf8_collate_key( lower, -1 );984 if( gtk_tree_model_iter_children( model, &iter, parent ) ) do985 {986 gboolean stop;987 char * modelkey;988 gtk_tree_model_get( model, &iter, FC_KEY, &modelkey, -1 );989 stop = (modelkey!=NULL) && !strcmp(mykey,modelkey);990 g_free (modelkey);991 if (stop) goto done;992 }993 while( gtk_tree_model_iter_next( model, &iter ) );994 995 gtk_tree_store_append( store, &iter, parent );996 if( NULL == ret )997 {998 stock = GTK_STOCK_FILE;999 }1000 else1001 {1002 stock = GTK_STOCK_DIRECTORY;1003 size = 0;1004 index = -1;1005 }1006 1007 if (index != -1) {1008 priority = tr_torrentGetFilePriority( tor, index );1009 enabled = tr_torrentGetFileDL( tor, index );1010 }1011 1012 escaped = g_markup_escape_text (file, -1);1013 gtk_tree_store_set( store, &iter, FC_INDEX, index,1014 FC_LABEL, escaped,1015 FC_KEY, mykey,1016 FC_STOCK, stock,1017 FC_PRIORITY, priorityToString(priority),1018 FC_ENABLED, enabled,1019 FC_SIZE, size, -1 );1020 done:1021 g_free( escaped );1022 g_free( mykey );1023 g_free( lower );1024 g_free( file );1025 if( NULL != ret )1026 *ret = iter;1027 }1028 1029 static uint64_t1030 getdirtotals( GtkTreeStore * store, GtkTreeIter * parent )1031 {1032 GtkTreeModel * model;1033 GtkTreeIter iter;1034 uint64_t mysize, subsize;1035 char * name, * label;1036 1037 model = GTK_TREE_MODEL( store );1038 mysize = 0;1039 if( gtk_tree_model_iter_children( model, &iter, parent ) ) do1040 {1041 char sizeStr[64];1042 if( gtk_tree_model_iter_has_child( model, &iter ) )1043 {1044 subsize = getdirtotals( store, &iter );1045 gtk_tree_store_set( store, &iter, FC_SIZE, subsize, -1 );1046 }1047 else1048 {1049 gtk_tree_model_get( model, &iter, FC_SIZE, &subsize, -1 );1050 }1051 gtk_tree_model_get( model, &iter, FC_LABEL, &name, -1 );1052 tr_strlsize( sizeStr, subsize, sizeof( sizeStr ) );1053 label = g_markup_printf_escaped( "<small>%s (%s)</small>",1054 name, sizeStr );1055 g_free( name );1056 gtk_tree_store_set( store, &iter, FC_LABEL, label, -1 );1057 g_free( label );1058 mysize += subsize;1059 }1060 while( gtk_tree_model_iter_next( model, &iter ) );1061 1062 return mysize;1063 }1064 1065 static void1066 updateprogress( GtkTreeModel * model,1067 GtkTreeStore * store,1068 GtkTreeIter * parent,1069 tr_file_stat * fileStats,1070 guint64 * setmeGotSize,1071 guint64 * setmeTotalSize)1072 {1073 GtkTreeIter iter;1074 guint64 gotSize=0, totalSize=0;1075 1076 if( gtk_tree_model_iter_children( model, &iter, parent ) ) do1077 {1078 int oldProg, newProg;1079 guint64 subGot, subTotal;1080 1081 if (gtk_tree_model_iter_has_child( model, &iter ) )1082 {1083 updateprogress( model, store, &iter, fileStats, &subGot, &subTotal);1084 }1085 else1086 {1087 int index, percent;1088 gtk_tree_model_get( model, &iter, FC_SIZE, &subTotal,1089 FC_INDEX, &index,1090 -1 );1091 g_assert( 0 <= index );1092 percent = (int)(fileStats[index].progress * 100.0); /* [0...100] */1093 subGot = (guint64)(subTotal * percent/100.0);1094 }1095 1096 if (!subTotal) subTotal = 1; /* avoid div by zero */1097 g_assert (subGot <= subTotal);1098 1099 /* why not just set it every time?1100 because that causes the "priorities" combobox to pop down */1101 gtk_tree_model_get (model, &iter, FC_PROG, &oldProg, -1);1102 newProg = (int)(100.0*subGot/subTotal);1103 if (oldProg != newProg)1104 gtk_tree_store_set (store, &iter,1105 FC_PROG, (int)(100.0*subGot/subTotal), -1);1106 1107 gotSize += subGot;1108 totalSize += subTotal;1109 }1110 while( gtk_tree_model_iter_next( model, &iter ) );1111 1112 *setmeGotSize = gotSize;1113 *setmeTotalSize = totalSize;1114 }1115 1116 static GtkTreeModel*1117 priority_model_new (void)1118 {1119 GtkTreeIter iter;1120 GtkListStore * store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT);1121 gtk_list_store_append (store, &iter);1122 gtk_list_store_set (store, &iter, 0, _("High"), 1, TR_PRI_HIGH, -1);1123 gtk_list_store_append (store, &iter);1124 gtk_list_store_set (store, &iter, 0, _("Normal"), 1, TR_PRI_NORMAL, -1);1125 gtk_list_store_append (store, &iter);1126 gtk_list_store_set (store, &iter, 0, _("Low"), 1, TR_PRI_LOW, -1);1127 return GTK_TREE_MODEL (store);1128 }1129 1130 static void1131 subtree_walk_dnd( GtkTreeStore * store,1132 GtkTreeIter * iter,1133 tr_torrent * tor,1134 gboolean enabled,1135 GArray * indices )1136 {1137 int index;1138 GtkTreeIter child;1139 1140 /* update this node */1141 gtk_tree_model_get( GTK_TREE_MODEL(store), iter, FC_INDEX, &index, -1 );1142 if (index >= 0)1143 g_array_append_val( indices, index );1144 gtk_tree_store_set( store, iter, FC_ENABLED, enabled, -1 );1145 1146 /* visit the children */1147 if( gtk_tree_model_iter_children( GTK_TREE_MODEL(store), &child, iter ) ) do1148 subtree_walk_dnd( store, &child, tor, enabled, indices );1149 while( gtk_tree_model_iter_next( GTK_TREE_MODEL(store), &child ) );1150 }1151 1152 static void1153 set_subtree_dnd( GtkTreeStore * store,1154 GtkTreeIter * iter,1155 tr_torrent * tor,1156 gboolean enabled )1157 {1158 GArray * indices = g_array_new( FALSE, FALSE, sizeof(int) );1159 subtree_walk_dnd( store, iter, tor, enabled, indices );1160 tr_torrentSetFileDLs( tor, (int*)indices->data, (int)indices->len, enabled );1161 g_array_free( indices, TRUE );1162 }1163 1164 static void1165 subtree_walk_priority( GtkTreeStore * store,1166 GtkTreeIter * iter,1167 tr_torrent * tor,1168 int priority,1169 GArray * indices )1170 {1171 int index;1172 GtkTreeIter child;1173 1174 /* update this node */1175 gtk_tree_model_get( GTK_TREE_MODEL(store), iter, FC_INDEX, &index, -1 );1176 if( index >= 0 )1177 g_array_append_val( indices, index );1178 gtk_tree_store_set( store, iter, FC_PRIORITY, priorityToString(priority), -1 );1179 1180 /* visit the children */1181 if( gtk_tree_model_iter_children( GTK_TREE_MODEL(store), &child, iter ) ) do1182 subtree_walk_priority( store, &child, tor, priority, indices );1183 while( gtk_tree_model_iter_next( GTK_TREE_MODEL(store), &child ) );1184 1185 }1186 1187 static void1188 set_subtree_priority( GtkTreeStore * store,1189 GtkTreeIter * iter,1190 tr_torrent * tor,1191 int priority )1192 {1193 GArray * indices = g_array_new( FALSE, FALSE, sizeof(int) );1194 subtree_walk_priority( store, iter, tor, priority, indices );1195 tr_torrentSetFilePriorities( tor, (int*)indices->data, (int)indices->len, priority );1196 g_array_free( indices, TRUE );1197 }1198 1199 static void1200 priority_changed_cb (GtkCellRendererText * cell UNUSED,1201 const gchar * path,1202 const gchar * value,1203 void * file_data)1204 {1205 GtkTreeIter iter;1206 FileData * d = file_data;1207 if (gtk_tree_model_get_iter_from_string (d->model, &iter, path))1208 {1209 tr_torrent * tor = tr_torrent_handle( d->gtor );1210 const tr_priority_t priority = stringToPriority( value );1211 set_subtree_priority( d->store, &iter, tor, priority );1212 }1213 }1214 1215 static void1216 enabled_toggled (GtkCellRendererToggle * cell UNUSED,1217 const gchar * path_str,1218 gpointer data_gpointer)1219 {1220 FileData * data = data_gpointer;1221 GtkTreePath * path = gtk_tree_path_new_from_string( path_str );1222 GtkTreeModel * model = data->model;1223 GtkTreeIter iter;1224 gboolean enabled;1225 1226 gtk_tree_model_get_iter( model, &iter, path );1227 gtk_tree_model_get( model, &iter, FC_ENABLED, &enabled, -1 );1228 enabled = !enabled;1229 set_subtree_dnd( GTK_TREE_STORE(model),1230 &iter,1231 tr_torrent_handle( data->gtor ),1232 enabled );1233 1234 gtk_tree_path_free( path );1235 }1236 1237 static GtkWidget *1238 file_page_new ( TrTorrent * gtor )1239 {1240 GtkWidget * ret;1241 FileData * data;1242 const tr_info * inf;1243 tr_torrent * tor;1244 GtkTreeStore * store;1245 int ii;1246 GtkWidget * view, * scroll;1247 GtkCellRenderer * rend;1248 GtkCellRenderer * priority_rend;1249 GtkCellRenderer * enabled_rend;1250 GtkTreeViewColumn * col;1251 GtkTreeSelection * sel;1252 GtkTreeModel * model;1253 1254 store = gtk_tree_store_new ( N_FILE_COLS,1255 G_TYPE_STRING, /* stock */1256 G_TYPE_STRING, /* label */1257 G_TYPE_INT, /* prog [0..100] */1258 G_TYPE_STRING, /* key */1259 G_TYPE_INT, /* index */1260 G_TYPE_UINT64, /* size */1261 G_TYPE_STRING, /* priority */1262 G_TYPE_BOOLEAN ); /* dl enabled */1263 1264 /* set up the model */1265 tor = tr_torrent_handle( gtor );1266 inf = tr_torrent_info( gtor );1267 for( ii = 0; ii < inf->fileCount; ii++ )1268 {1269 parsepath( tor, store, NULL, STRIPROOT( inf->files[ii].name ),1270 ii, inf->files[ii].length );1271 }1272 getdirtotals( store, NULL );1273 1274 /* create the view */1275 view = gtk_tree_view_new_with_model( GTK_TREE_MODEL( store ) );1276 gtk_container_set_border_width( GTK_CONTAINER( view ), GUI_PAD_BIG );1277 g_object_set_data (G_OBJECT(view), "torrent-handle", tor );1278 1279 /* add file column */1280 1281 col = GTK_TREE_VIEW_COLUMN (g_object_new (GTK_TYPE_TREE_VIEW_COLUMN,1282 "expand", TRUE,1283 /* Translators: this is a column header in Files tab, Details dialog;1284 Don't include the prefix "filedetails|" in the translation. */1285 "title", Q_("filedetails|File"),1286 NULL));1287 rend = gtk_cell_renderer_pixbuf_new();1288 gtk_tree_view_column_pack_start( col, rend, FALSE );1289 gtk_tree_view_column_add_attribute( col, rend, "stock-id", FC_STOCK );1290 /* add text renderer */1291 rend = gtk_cell_renderer_text_new();1292 g_object_set( rend, "ellipsize", PANGO_ELLIPSIZE_END, NULL );1293 gtk_tree_view_column_pack_start( col, rend, TRUE );1294 gtk_tree_view_column_add_attribute( col, rend, "markup", FC_LABEL );1295 gtk_tree_view_append_column( GTK_TREE_VIEW( view ), col );1296 /* add progress column */1297 rend = gtk_cell_renderer_progress_new();1298 /* Translators: this is a column header in Files tab, Details dialog;1299 Don't include the prefix "filedetails|" in the translation. */1300 col = gtk_tree_view_column_new_with_attributes (Q_("filedetails|Progress"),1301 rend,1302 "value", FC_PROG,1303 NULL);1304 gtk_tree_view_column_set_sort_column_id( col, FC_PROG );1305 gtk_tree_view_append_column( GTK_TREE_VIEW( view ), col );1306 /* set up view */1307 sel = gtk_tree_view_get_selection( GTK_TREE_VIEW( view ) );1308 gtk_tree_view_expand_all( GTK_TREE_VIEW( view ) );1309 gtk_tree_view_set_search_column( GTK_TREE_VIEW( view ), FC_LABEL );1310 1311 /* add "download" checkbox column */1312 col = gtk_tree_view_column_new ();1313 gtk_tree_view_column_set_sort_column_id( col, FC_ENABLED );1314 rend = enabled_rend = gtk_cell_renderer_toggle_new ();1315 /* Translators: this is a column header in Files tab, Details dialog;1316 Don't include the prefix "filedetails|" in the translation.1317 Please note the items for this column are checkboxes (yes/no) */1318 col = gtk_tree_view_column_new_with_attributes (Q_("filedetails|Download"),1319 rend,1320 "active", FC_ENABLED,1321 NULL);1322 gtk_tree_view_append_column( GTK_TREE_VIEW( view ), col );1323 1324 /* add priority column */1325 model = priority_model_new ();1326 col = gtk_tree_view_column_new ();1327 gtk_tree_view_column_set_sort_column_id( col, FC_PRIORITY );1328 /* Translators: this is a column header in Files tab, Details dialog;1329 Don't include the prefix "filedetails|" in the translation. */1330 gtk_tree_view_column_set_title (col, Q_("filedetails|Priority"));1331 rend = priority_rend = gtk_cell_renderer_combo_new ();1332 gtk_tree_view_column_pack_start (col, rend, TRUE);1333 g_object_set (G_OBJECT(rend), "model", model,1334 "editable", TRUE,1335 "has-entry", FALSE,1336 "text-column", 0,1337 NULL);1338 g_object_unref (G_OBJECT(model));1339 gtk_tree_view_column_add_attribute (col, rend, "text", FC_PRIORITY);1340 gtk_tree_view_append_column( GTK_TREE_VIEW( view ), col );1341 1342 /* create the scrolled window and stick the view in it */1343 scroll = gtk_scrolled_window_new( NULL, NULL );1344 gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( scroll ),1345 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC );1346 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(scroll),1347 GTK_SHADOW_IN);1348 gtk_container_add( GTK_CONTAINER( scroll ), view );1349 gtk_widget_set_size_request (scroll, 0u, 200u);1350 gtk_container_set_border_width (GTK_CONTAINER(scroll), GUI_PAD);1351 1352 ret = scroll;1353 data = g_new (FileData, 1);1354 data->gtor = gtor;1355 data->model = GTK_TREE_MODEL(store);1356 data->store = store;1357 g_object_set_data_full (G_OBJECT(ret), "file-data", data, g_free);1358 g_signal_connect (G_OBJECT(priority_rend), "edited", G_CALLBACK(priority_changed_cb), data);1359 g_signal_connect(enabled_rend, "toggled", G_CALLBACK(enabled_toggled), data );1360 return ret;1361 }1362 1363 static void1364 refresh_files (GtkWidget * top)1365 {1366 guint64 foo, bar;1367 int fileCount = 0;1368 FileData * data = g_object_get_data (G_OBJECT(top), "file-data");1369 tr_torrent * tor = tr_torrent_handle( data->gtor );1370 tr_file_stat * fileStats = tr_torrentFiles( tor, &fileCount );1371 updateprogress (data->model, data->store, NULL, fileStats, &foo, &bar);1372 tr_torrentFilesFree( fileStats, fileCount );1373 }1374 1375 898 1376 899 /**** … … 1558 1081 periodic_refresh (gpointer data) 1559 1082 { 1560 refresh_peers (g_object_get_data (G_OBJECT(data), "peers-top"));1561 refresh_activity (g_object_get_data (G_OBJECT(data), "activity-top"));1562 refresh_ files (g_object_get_data (G_OBJECT(data), "files-top"));1563 refresh_options (g_object_get_data (G_OBJECT(data), "options-top"));1083 refresh_peers (g_object_get_data (G_OBJECT(data), "peers-top")); 1084 refresh_activity (g_object_get_data (G_OBJECT(data), "activity-top")); 1085 refresh_options (g_object_get_data (G_OBJECT(data), "options-top")); 1086 file_list_refresh (g_object_get_data (G_OBJECT(data), "files-top")); 1564 1087 1565 1088 return TRUE; … … 1608 1131 gtk_label_new (_("Info"))); 1609 1132 1610 w = file_ page_new (gtor);1133 w = file_list_new( gtor ); 1611 1134 g_object_set_data (G_OBJECT(d), "files-top", w); 1612 1135 gtk_notebook_append_page (GTK_NOTEBOOK(n), w, -
trunk/gtk/torrent-inspector.h
r4816 r5003 1 /****************************************************************************** 1 /* 2 * This file Copyright (C) 2007-2008 Charles Kerr <charles@rebelbase.com> 3 * 4 * This file is licensed by the GPL version 2. Works owned by the 5 * Transmission project are granted a special exemption to clause 2(b) 6 * so that the bulk of its code can remain under the MIT license. 7 * This exemption does not extend to derived works not owned by 8 * the Transmission project. 9 * 2 10 * $Id$ 3 * 4 * Copyright (c) 2005-2007 Transmission authors and contributors 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 * DEALINGS IN THE SOFTWARE. 23 *****************************************************************************/ 11 */ 24 12 25 13 #ifndef GTK_TORRENT_INSPECTOR_H … … 29 17 #include "tr_torrent.h" 30 18 31 struct TrTorrent;32 33 19 GtkWidget* torrent_inspector_new ( GtkWindow * parent, TrTorrent * tor ); 34 20
Note: See TracChangeset
for help on using the changeset viewer.