Changeset 6795 for trunk/gtk/msgwin.c
- Timestamp:
- Sep 23, 2008, 7:11:04 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/gtk/msgwin.c
r6402 r6795 4 4 * This file is licensed by the GPL version 2. Works owned by the 5 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. 6 * so that the bulk of its code can remain under the MIT license. 7 7 * This exemption does not extend to derived works not owned by 8 8 * the Transmission project. 9 * 9 * 10 10 * $Id$ 11 11 */ … … 38 38 struct MsgData 39 39 { 40 TrCore * core;41 GtkTreeView * view;42 GtkListStore * store;43 GtkTreeModel * filter;44 GtkTreeModel * sort;45 int maxLevel;46 gboolean isPaused;47 guint refresh_tag;40 TrCore * core; 41 GtkTreeView * view; 42 GtkListStore * store; 43 GtkTreeModel * filter; 44 GtkTreeModel * sort; 45 int maxLevel; 46 gboolean isPaused; 47 guint refresh_tag; 48 48 }; 49 49 … … 56 56 57 57 static void 58 level_combo_changed_cb( GtkWidget * w, gpointer gdata ) 58 level_combo_changed_cb( GtkWidget * w, 59 gpointer gdata ) 59 60 { 60 61 struct MsgData * data = gdata; 61 GtkTreeIter iter; 62 if( gtk_combo_box_get_active_iter( GTK_COMBO_BOX(w), &iter ) ) 63 { 64 int level = 0; 62 GtkTreeIter iter; 63 64 if( gtk_combo_box_get_active_iter( GTK_COMBO_BOX( w ), &iter ) ) 65 { 66 int level = 0; 65 67 GtkTreeModel * m = gtk_combo_box_get_model( GTK_COMBO_BOX( w ) ); 66 68 gtk_tree_model_get( m, &iter, 1, &level, -1 ); … … 74 76 75 77 static void 76 doSave( GtkWindow *parent,78 doSave( GtkWindow * parent, 77 79 struct MsgData * data, 78 const char *filename )80 const char * filename ) 79 81 { 80 82 FILE * fp = fopen( filename, "w+" ); 83 81 84 if( !fp ) 82 85 { 83 86 errmsg( parent, 84 _("Couldn't save file \"%1$s\": %2$s"),85 87 _( "Couldn't save file \"%1$s\": %2$s" ), 88 filename, g_strerror( errno ) ); 86 89 } 87 90 else 88 91 { 89 GtkTreeIter iter;92 GtkTreeIter iter; 90 93 GtkTreeModel * model = GTK_TREE_MODEL( data->sort ); 91 94 if( gtk_tree_model_iter_children( model, &iter, NULL ) ) do 92 { 93 char * date; 94 const char * levelStr; 95 const struct tr_msg_list * node; 96 97 gtk_tree_model_get( model, &iter, 98 COL_TR_MSG, &node, 99 -1 ); 100 date = gtr_localtime( node->when ); 101 switch( node->level ) { 102 case TR_MSG_DBG: levelStr = "debug"; break; 103 case TR_MSG_ERR: levelStr = "error"; break; 104 default: levelStr = " "; break; 95 { 96 char * date; 97 const char * levelStr; 98 const struct tr_msg_list * node; 99 100 gtk_tree_model_get( model, &iter, 101 COL_TR_MSG, &node, 102 -1 ); 103 date = gtr_localtime( node->when ); 104 switch( node->level ) 105 { 106 case TR_MSG_DBG: 107 levelStr = "debug"; break; 108 109 case TR_MSG_ERR: 110 levelStr = "error"; break; 111 112 default: 113 levelStr = " "; break; 114 } 115 fprintf( fp, "%s\t%s\t%s\t%s\n", date, levelStr, 116 ( node->name ? node->name : "" ), 117 ( node->message ? node->message : "" ) ); 118 119 g_free( date ); 105 120 } 106 fprintf( fp, "%s\t%s\t%s\t%s\n", date, levelStr, 107 ( node->name ? node->name : "" ), 108 ( node->message ? node->message : "" ) ); 109 110 g_free( date ); 111 } 112 while( gtk_tree_model_iter_next( model, &iter ) ); 121 while( gtk_tree_model_iter_next( model, &iter ) ); 122 113 123 fclose( fp ); 114 124 } … … 116 126 117 127 static void 118 onSaveDialogResponse( GtkWidget * d, int response, gpointer data ) 119 { 120 if( response == GTK_RESPONSE_ACCEPT ) 121 { 122 char * filename = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER( d ) ); 123 doSave( GTK_WINDOW( d ), data, filename ); 124 g_free( filename ); 125 } 126 127 gtk_widget_destroy( d ); 128 } 129 130 static void 131 onSaveRequest( GtkWidget * w, gpointer data ) 132 { 133 GtkWindow * window = GTK_WINDOW( gtk_widget_get_toplevel( w ) ); 134 GtkWidget * d = gtk_file_chooser_dialog_new( _("Save Log"), window, 135 GTK_FILE_CHOOSER_ACTION_SAVE, 136 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, 137 GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, 138 NULL ); 139 gtk_dialog_set_alternative_button_order( GTK_DIALOG( d ), 140 GTK_RESPONSE_ACCEPT, 141 GTK_RESPONSE_CANCEL, 142 -1 ); 143 g_signal_connect( d, "response", 144 G_CALLBACK( onSaveDialogResponse ), data ); 145 gtk_widget_show( d ); 146 } 147 148 static void 149 onClearRequest( GtkWidget * w UNUSED, gpointer gdata ) 128 onSaveDialogResponse( GtkWidget * d, 129 int response, 130 gpointer data ) 131 { 132 if( response == GTK_RESPONSE_ACCEPT ) 133 { 134 char * filename = 135 gtk_file_chooser_get_filename( GTK_FILE_CHOOSER( d ) ); 136 doSave( GTK_WINDOW( d ), data, filename ); 137 g_free( filename ); 138 } 139 140 gtk_widget_destroy( d ); 141 } 142 143 static void 144 onSaveRequest( GtkWidget * w, 145 gpointer data ) 146 { 147 GtkWindow * window = GTK_WINDOW( gtk_widget_get_toplevel( w ) ); 148 GtkWidget * d = gtk_file_chooser_dialog_new( _( 149 "Save Log" ), window, 150 GTK_FILE_CHOOSER_ACTION_SAVE, 151 GTK_STOCK_CANCEL, 152 GTK_RESPONSE_CANCEL, 153 GTK_STOCK_SAVE, 154 GTK_RESPONSE_ACCEPT, 155 NULL ); 156 157 gtk_dialog_set_alternative_button_order( GTK_DIALOG( d ), 158 GTK_RESPONSE_ACCEPT, 159 GTK_RESPONSE_CANCEL, 160 -1 ); 161 g_signal_connect( d, "response", 162 G_CALLBACK( onSaveDialogResponse ), data ); 163 gtk_widget_show( d ); 164 } 165 166 static void 167 onClearRequest( GtkWidget * w UNUSED, 168 gpointer gdata ) 150 169 { 151 170 struct MsgData * data = gdata; 171 152 172 gtk_list_store_clear( data->store ); 153 173 tr_freeMessageList( myHead ); … … 156 176 157 177 static void 158 onPauseToggled( GtkToggleToolButton * w, gpointer gdata ) 178 onPauseToggled( GtkToggleToolButton * w, 179 gpointer gdata ) 159 180 { 160 181 struct MsgData * data = gdata; 182 161 183 data->isPaused = gtk_toggle_tool_button_get_active( w ); 162 184 } 163 185 164 static struct { 165 const char * label; 166 const char * pref; 167 int id; 186 static struct 187 { 188 const char * label; 189 const char * pref; 190 int id; 168 191 } trLevels[] = { 169 { N_("Error"), "error", TR_MSG_ERR},170 { N_("Information"), "info", TR_MSG_INF},171 { N_("Debug"), "debug", TR_MSG_DBG},192 { N_( "Error" ), "error", TR_MSG_ERR }, 193 { N_( "Information" ), "info", TR_MSG_INF }, 194 { N_( "Debug" ), "debug", TR_MSG_DBG }, 172 195 }; 173 196 … … 176 199 { 177 200 const char * foreground; 178 switch( msgLevel ) { 179 case TR_MSG_DBG: foreground = "gray"; break; 180 case TR_MSG_INF: foreground = "black"; break; 181 case TR_MSG_ERR: foreground = "red"; break; 182 default: g_assert_not_reached( ); 201 202 switch( msgLevel ) 203 { 204 case TR_MSG_DBG: 205 foreground = "gray"; break; 206 207 case TR_MSG_INF: 208 foreground = "black"; break; 209 210 case TR_MSG_ERR: 211 foreground = "red"; break; 212 213 default: 214 g_assert_not_reached( ); 183 215 } 184 216 return foreground; … … 187 219 static void 188 220 renderText( GtkTreeViewColumn * column UNUSED, 189 GtkCellRenderer *renderer,190 GtkTreeModel *tree_model,191 GtkTreeIter *iter,192 gpointer gcol )193 { 194 const int col = GPOINTER_TO_INT( gcol );195 char * str = NULL;221 GtkCellRenderer * renderer, 222 GtkTreeModel * tree_model, 223 GtkTreeIter * iter, 224 gpointer gcol ) 225 { 226 const int col = GPOINTER_TO_INT( gcol ); 227 char * str = NULL; 196 228 const struct tr_msg_list * node; 229 197 230 gtk_tree_model_get( tree_model, iter, col, &str, COL_TR_MSG, &node, -1 ); 198 231 g_object_set( renderer, "text", str, 199 200 201 232 "foreground", getForegroundColor( node->level ), 233 "ellipsize", PANGO_ELLIPSIZE_END, 234 NULL ); 202 235 } 203 236 204 237 static void 205 238 renderTime( GtkTreeViewColumn * column UNUSED, 206 GtkCellRenderer *renderer,207 GtkTreeModel *tree_model,208 GtkTreeIter *iter,209 gpointer data UNUSED )210 { 211 struct tm tm;212 char buf[16];239 GtkCellRenderer * renderer, 240 GtkTreeModel * tree_model, 241 GtkTreeIter * iter, 242 gpointer data UNUSED ) 243 { 244 struct tm tm; 245 char buf[16]; 213 246 const struct tr_msg_list * node; 214 247 215 gtk_tree_model_get( tree_model, iter, COL_TR_MSG, &node, -1 );248 gtk_tree_model_get( tree_model, iter, COL_TR_MSG, &node, -1 ); 216 249 tm = *localtime( &node->when ); 217 g_snprintf( buf, sizeof( buf ), "%02d:%02d:%02d", tm.tm_hour, tm.tm_min, tm.tm_sec ); 218 g_object_set (renderer, "text", buf, 219 "foreground", getForegroundColor( node->level ), 220 NULL ); 221 } 222 223 static void 224 appendColumn( GtkTreeView * view, int col ) 225 { 226 GtkCellRenderer * r; 250 g_snprintf( buf, sizeof( buf ), "%02d:%02d:%02d", tm.tm_hour, tm.tm_min, 251 tm.tm_sec ); 252 g_object_set ( renderer, "text", buf, 253 "foreground", getForegroundColor( node->level ), 254 NULL ); 255 } 256 257 static void 258 appendColumn( GtkTreeView * view, 259 int col ) 260 { 261 GtkCellRenderer * r; 227 262 GtkTreeViewColumn * c; 228 const char * title = NULL; 229 230 switch( col ) { 231 case COL_SEQUENCE: title = _( "Time" ); break; 263 const char * title = NULL; 264 265 switch( col ) 266 { 267 case COL_SEQUENCE: 268 title = _( "Time" ); break; 269 232 270 /* noun. column title for a list */ 233 case COL_NAME: title = _( "Name"); break; 271 case COL_NAME: 272 title = _( "Name" ); break; 273 234 274 /* noun. column title for a list */ 235 case COL_MESSAGE: title = _( "Message" ); break; 236 default: g_assert_not_reached( ); 275 case COL_MESSAGE: 276 title = _( "Message" ); break; 277 278 default: 279 g_assert_not_reached( ); 237 280 } 238 281 … … 242 285 r = gtk_cell_renderer_text_new( ); 243 286 c = gtk_tree_view_column_new_with_attributes( title, r, NULL ); 244 gtk_tree_view_column_set_cell_data_func( c, r, renderText, GINT_TO_POINTER(col), NULL ); 287 gtk_tree_view_column_set_cell_data_func( c, r, renderText, 288 GINT_TO_POINTER( 289 col ), NULL ); 245 290 gtk_tree_view_column_set_sizing( c, GTK_TREE_VIEW_COLUMN_FIXED ); 246 291 gtk_tree_view_column_set_fixed_width( c, 200 ); … … 251 296 r = gtk_cell_renderer_text_new( ); 252 297 c = gtk_tree_view_column_new_with_attributes( title, r, NULL ); 253 gtk_tree_view_column_set_cell_data_func( c, r, renderText, GINT_TO_POINTER(col), NULL ); 298 gtk_tree_view_column_set_cell_data_func( c, r, renderText, 299 GINT_TO_POINTER( 300 col ), NULL ); 254 301 gtk_tree_view_column_set_sizing( c, GTK_TREE_VIEW_COLUMN_FIXED ); 255 302 gtk_tree_view_column_set_fixed_width( c, 500 ); … … 260 307 r = gtk_cell_renderer_text_new( ); 261 308 c = gtk_tree_view_column_new_with_attributes( title, r, NULL ); 262 gtk_tree_view_column_set_cell_data_func( c, r, renderTime, NULL, NULL ); 309 gtk_tree_view_column_set_cell_data_func( c, r, renderTime, NULL, 310 NULL ); 263 311 gtk_tree_view_column_set_resizable( c, TRUE ); 264 312 break; … … 274 322 275 323 static gboolean 276 isRowVisible( GtkTreeModel * model, GtkTreeIter * iter, gpointer gdata ) 277 { 278 const struct MsgData * data = gdata; 324 isRowVisible( GtkTreeModel * model, 325 GtkTreeIter * iter, 326 gpointer gdata ) 327 { 328 const struct MsgData * data = gdata; 279 329 const struct tr_msg_list * node; 330 280 331 gtk_tree_model_get( model, iter, COL_TR_MSG, &node, -1 ); 281 332 return node->level <= data->maxLevel; … … 283 334 284 335 static void 285 onWindowDestroyed( gpointer gdata, GObject * deadWindow UNUSED ) 336 onWindowDestroyed( gpointer gdata, 337 GObject * deadWindow UNUSED ) 286 338 { 287 339 struct MsgData * data = gdata; 340 288 341 g_source_remove( data->refresh_tag ); 289 342 g_free( data ); … … 291 344 292 345 static tr_msg_list * 293 addMessages( GtkListStore * store, struct tr_msg_list * head ) 294 { 295 const char * default_name = g_get_application_name( ); 346 addMessages( GtkListStore * store, 347 struct tr_msg_list * head ) 348 { 349 const char * default_name = g_get_application_name( ); 296 350 static unsigned int sequence = 1; 297 tr_msg_list * i;298 299 for( i =head; i; i=i->next )351 tr_msg_list * i; 352 353 for( i = head; i; i = i->next ) 300 354 { 301 355 GtkTreeIter unused; … … 303 357 gtk_list_store_insert_with_values( store, &unused, 0, 304 358 COL_TR_MSG, i, 305 COL_NAME, ( i->name ? i->name : default_name ), 359 COL_NAME, 360 ( i->name ? i->name : 361 default_name ), 306 362 COL_MESSAGE, i->message, 307 363 COL_SEQUENCE, sequence++, 308 364 -1 ); 309 365 310 311 366 if( !i->next ) 367 break; 312 368 } 313 369 … … 319 375 { 320 376 struct MsgData * data = gdata; 377 321 378 if( !data->isPaused ) 322 379 { … … 340 397 debug_level_combo_new( void ) 341 398 { 342 unsigned int i;343 int ii;344 int curlevel;345 GtkWidget * levels;346 GtkListStore * store;399 unsigned int i; 400 int ii; 401 int curlevel; 402 GtkWidget * levels; 403 GtkListStore * store; 347 404 GtkCellRenderer * renderer; 348 405 349 store = gtk_list_store_new ( 2, G_TYPE_STRING, G_TYPE_INT);406 store = gtk_list_store_new ( 2, G_TYPE_STRING, G_TYPE_INT ); 350 407 351 408 curlevel = pref_int_get( PREF_KEY_MSGLEVEL ); 352 for( i=ii=0; i<G_N_ELEMENTS(trLevels); ++i ) { 409 for( i = ii = 0; i < G_N_ELEMENTS( trLevels ); ++i ) 410 { 353 411 GtkTreeIter iter; 354 gtk_list_store_append ( store, &iter);355 gtk_list_store_set ( store, &iter, 0, _(trLevels[i].label),356 357 -1);412 gtk_list_store_append ( store, &iter ); 413 gtk_list_store_set ( store, &iter, 0, _( trLevels[i].label ), 414 1, trLevels[i].id, 415 -1 ); 358 416 if( trLevels[i].id == curlevel ) 359 417 ii = i; 360 418 } 361 levels = gtk_combo_box_new_with_model ( GTK_TREE_MODEL(store));419 levels = gtk_combo_box_new_with_model ( GTK_TREE_MODEL( store ) ); 362 420 g_object_unref( G_OBJECT( store ) ); 363 421 store = NULL; 364 422 365 renderer = gtk_cell_renderer_text_new ( );366 gtk_cell_layout_pack_start( GTK_CELL_LAYOUT( levels), renderer, TRUE );367 gtk_cell_layout_set_attributes( GTK_CELL_LAYOUT( levels), renderer,423 renderer = gtk_cell_renderer_text_new ( ); 424 gtk_cell_layout_pack_start( GTK_CELL_LAYOUT( levels ), renderer, TRUE ); 425 gtk_cell_layout_set_attributes( GTK_CELL_LAYOUT( levels ), renderer, 368 426 "text", 0, 369 427 NULL ); … … 373 431 } 374 432 375 376 433 /** 377 434 *** Public Functions … … 381 438 msgwin_new( TrCore * core ) 382 439 { 383 GtkWidget * win;384 GtkWidget * vbox;385 GtkWidget * toolbar;386 GtkWidget * w;387 GtkWidget * view;388 GtkToolItem * item;440 GtkWidget * win; 441 GtkWidget * vbox; 442 GtkWidget * toolbar; 443 GtkWidget * w; 444 GtkWidget * view; 445 GtkToolItem * item; 389 446 struct MsgData * data; 390 447 … … 403 460 404 461 toolbar = gtk_toolbar_new( ); 405 gtk_toolbar_set_orientation( GTK_TOOLBAR( toolbar ), GTK_ORIENTATION_HORIZONTAL ); 462 gtk_toolbar_set_orientation( GTK_TOOLBAR( 463 toolbar ), GTK_ORIENTATION_HORIZONTAL ); 406 464 gtk_toolbar_set_style( GTK_TOOLBAR( toolbar ), GTK_TOOLBAR_BOTH_HORIZ ); 407 465 408 409 410 g_signal_connect( item, "clicked", G_CALLBACK(onSaveRequest), data );411 412 413 414 415 g_signal_connect( item, "clicked", G_CALLBACK(onClearRequest), data );416 466 item = gtk_tool_button_new_from_stock( GTK_STOCK_SAVE ); 467 g_object_set( G_OBJECT( item ), "is-important", TRUE, NULL ); 468 g_signal_connect( item, "clicked", G_CALLBACK( onSaveRequest ), data ); 469 gtk_toolbar_insert( GTK_TOOLBAR( toolbar ), item, -1 ); 470 471 item = gtk_tool_button_new_from_stock( GTK_STOCK_CLEAR ); 472 g_object_set( G_OBJECT( item ), "is-important", TRUE, NULL ); 473 g_signal_connect( item, "clicked", G_CALLBACK( onClearRequest ), data ); 474 gtk_toolbar_insert( GTK_TOOLBAR( toolbar ), item, -1 ); 417 475 418 476 item = gtk_separator_tool_item_new( ); 419 477 gtk_toolbar_insert( GTK_TOOLBAR( toolbar ), item, -1 ); 420 478 421 422 423 g_signal_connect( item, "toggled", G_CALLBACK(onPauseToggled), data );424 479 item = gtk_toggle_tool_button_new_from_stock( GTK_STOCK_MEDIA_PAUSE ); 480 g_object_set( G_OBJECT( item ), "is-important", TRUE, NULL ); 481 g_signal_connect( item, "toggled", G_CALLBACK( onPauseToggled ), data ); 482 gtk_toolbar_insert( GTK_TOOLBAR( toolbar ), item, -1 ); 425 483 426 484 item = gtk_separator_tool_item_new( ); 427 485 gtk_toolbar_insert( GTK_TOOLBAR( toolbar ), item, -1 ); 428 486 429 w = gtk_label_new( _( "Level" ) ); 430 gtk_misc_set_padding( GTK_MISC( w ), GUI_PAD, 0 ); 431 item = gtk_tool_item_new( ); 432 gtk_container_add( GTK_CONTAINER( item ), w ); 433 gtk_toolbar_insert( GTK_TOOLBAR( toolbar ), item, -1 ); 434 435 w = debug_level_combo_new( ); 436 g_signal_connect( w, "changed", G_CALLBACK(level_combo_changed_cb), data ); 437 item = gtk_tool_item_new( ); 438 gtk_container_add( GTK_CONTAINER( item ), w ); 439 gtk_toolbar_insert( GTK_TOOLBAR( toolbar ), item, -1 ); 487 w = gtk_label_new( _( "Level" ) ); 488 gtk_misc_set_padding( GTK_MISC( w ), GUI_PAD, 0 ); 489 item = gtk_tool_item_new( ); 490 gtk_container_add( GTK_CONTAINER( item ), w ); 491 gtk_toolbar_insert( GTK_TOOLBAR( toolbar ), item, -1 ); 492 493 w = debug_level_combo_new( ); 494 g_signal_connect( w, "changed", G_CALLBACK( 495 level_combo_changed_cb ), data ); 496 item = gtk_tool_item_new( ); 497 gtk_container_add( GTK_CONTAINER( item ), w ); 498 gtk_toolbar_insert( GTK_TOOLBAR( toolbar ), item, -1 ); 440 499 441 500 gtk_box_pack_start( GTK_BOX( vbox ), toolbar, FALSE, FALSE, 0 ); … … 449 508 G_TYPE_POINTER, /* category */ 450 509 G_TYPE_POINTER, /* message */ 451 G_TYPE_POINTER); /* struct tr_msg_list */ 510 G_TYPE_POINTER ); /* struct tr_msg_list 511 */ 452 512 453 513 addMessages( data->store, myHead ); 454 514 onRefresh( data ); /* much faster to populate *before* it has listeners */ 455 515 456 data->filter = gtk_tree_model_filter_new( GTK_TREE_MODEL( data->store ), NULL ); 516 data->filter = gtk_tree_model_filter_new( GTK_TREE_MODEL( 517 data->store ), NULL ); 457 518 data->sort = gtk_tree_model_sort_new_with_model( data->filter ); 458 519 gtk_tree_sortable_set_sort_column_id( GTK_TREE_SORTABLE( data->sort ), … … 460 521 GTK_SORT_ASCENDING ); 461 522 data->maxLevel = pref_int_get( PREF_KEY_MSGLEVEL ); 462 gtk_tree_model_filter_set_visible_func( GTK_TREE_MODEL_FILTER( data->filter ), 523 gtk_tree_model_filter_set_visible_func( GTK_TREE_MODEL_FILTER( data-> 524 filter ), 463 525 isRowVisible, data, NULL ); 464 526 … … 475 537 GTK_POLICY_AUTOMATIC ); 476 538 gtk_scrolled_window_set_shadow_type( GTK_SCROLLED_WINDOW( w ), 477 GTK_SHADOW_IN );539 GTK_SHADOW_IN ); 478 540 gtk_container_add( GTK_CONTAINER( w ), view ); 479 541 gtk_box_pack_start( GTK_BOX( vbox ), w, TRUE, TRUE, 0 ); … … 486 548 return win; 487 549 } 550
Note: See TracChangeset
for help on using the changeset viewer.