Changeset 12656 for trunk/gtk/main.c
- Timestamp:
- Aug 9, 2011, 2:30:31 AM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/gtk/main.c
r12655 r12656 74 74 struct cbdata 75 75 { 76 char * config_dir; 77 gboolean start_paused; 76 78 gboolean is_iconified; 79 77 80 guint timer; 78 81 guint update_model_soon_tag; … … 349 352 ***/ 350 353 351 static void app_setup( TrWindow * wind, 352 GSList * torrent_files, 353 struct cbdata * cbdata, 354 gboolean paused, 355 gboolean minimized ); 354 static void app_setup( TrWindow * wind, struct cbdata * cbdata ); 356 355 357 356 static void main_window_setup( struct cbdata * cbdata, TrWindow * wind ); … … 561 560 } 562 561 563 static void564 setupsighandlers( void )565 {566 signal( SIGINT, signal_handler );567 signal( SIGKILL, signal_handler );568 }569 570 /***571 ****572 ***/573 574 static GSList *575 checkfilenames( int argc, char **argv )576 {577 int i;578 GSList * ret = NULL;579 char * pwd = g_get_current_dir( );580 581 for( i=0; i<argc; ++i )582 {583 const char * arg = argv[i];584 585 if( gtr_is_supported_url( arg ) || gtr_is_magnet_link( arg ) )586 {587 ret = g_slist_prepend( ret, g_strdup( arg ) );588 }589 else /* local file */590 {591 char * filename;592 593 if( g_path_is_absolute( arg ) )594 filename = g_strdup( arg );595 else {596 filename = g_filename_from_uri( arg, NULL, NULL );597 598 if( filename == NULL )599 filename = g_build_filename( pwd, arg, NULL );600 }601 602 if( g_file_test( filename, G_FILE_TEST_EXISTS ) )603 ret = g_slist_prepend( ret, filename );604 else {605 if( gtr_is_hex_hashcode( argv[i] ) )606 ret = g_slist_prepend( ret, g_strdup_printf( "magnet:?xt=urn:btih:%s", argv[i] ) );607 g_free( filename );608 }609 }610 }611 612 g_free( pwd );613 return g_slist_reverse( ret );614 }615 616 562 /**** 617 563 ***** … … 619 565 ****/ 620 566 567 static void 568 on_startup( GApplication * application, gpointer user_data ) 569 { 570 const char * str; 571 GtkWindow * win; 572 GtkUIManager * ui_manager; 573 tr_session * session; 574 struct cbdata * cbdata = user_data; 575 576 signal( SIGINT, signal_handler ); 577 signal( SIGKILL, signal_handler ); 578 579 sighandler_cbdata = cbdata; 580 581 /* ensure the directories are created */ 582 if(( str = gtr_pref_string_get( TR_PREFS_KEY_DOWNLOAD_DIR ))) 583 g_mkdir_with_parents( str, 0777 ); 584 if(( str = gtr_pref_string_get( TR_PREFS_KEY_INCOMPLETE_DIR ))) 585 g_mkdir_with_parents( str, 0777 ); 586 587 /* initialize the libtransmission session */ 588 session = tr_sessionInit( "gtk", cbdata->config_dir, TRUE, gtr_pref_get_all( ) ); 589 590 gtr_pref_flag_set( TR_PREFS_KEY_ALT_SPEED_ENABLED, tr_sessionUsesAltSpeed( session ) ); 591 gtr_pref_int_set( TR_PREFS_KEY_PEER_PORT, tr_sessionGetPeerPort( session ) ); 592 cbdata->core = gtr_core_new( session ); 593 594 /* init the ui manager */ 595 ui_manager = gtk_ui_manager_new ( ); 596 gtr_actions_init ( ui_manager, cbdata ); 597 gtk_ui_manager_add_ui_from_string ( ui_manager, fallback_ui_file, -1, NULL ); 598 gtk_ui_manager_ensure_update ( ui_manager ); 599 600 /* create main window now to be a parent to any error dialogs */ 601 win = GTK_WINDOW( gtr_window_new( ui_manager, cbdata->core ) ); 602 g_signal_connect( win, "size-allocate", G_CALLBACK( on_main_window_size_allocated ), cbdata ); 603 g_application_hold( application ); 604 g_object_weak_ref( G_OBJECT( win ), (GWeakNotify)g_application_release, application ); 605 app_setup( win, cbdata ); 606 tr_sessionSetRPCCallback( session, on_rpc_changed, cbdata ); 607 608 /* check & see if it's time to update the blocklist */ 609 if( gtr_pref_flag_get( TR_PREFS_KEY_BLOCKLIST_ENABLED ) ) { 610 if( gtr_pref_flag_get( PREF_KEY_BLOCKLIST_UPDATES_ENABLED ) ) { 611 const int64_t last_time = gtr_pref_int_get( "blocklist-date" ); 612 const int SECONDS_IN_A_WEEK = 7 * 24 * 60 * 60; 613 const time_t now = time( NULL ); 614 if( last_time + SECONDS_IN_A_WEEK < now ) 615 gtr_core_blocklist_update( cbdata->core ); 616 } 617 } 618 619 /* if there's no magnet link handler registered, register us */ 620 register_magnet_link_handler( ); 621 } 622 623 static void 624 on_activate( GApplication * app UNUSED, gpointer unused UNUSED ) 625 { 626 gtr_action_activate( "present-main-window" ); 627 } 628 629 static void 630 open_files( GSList * files, gpointer gdata ) 631 { 632 struct cbdata * cbdata = gdata; 633 const gboolean do_start = gtr_pref_flag_get( TR_PREFS_KEY_START ) && !cbdata->start_paused; 634 const gboolean do_prompt = gtr_pref_flag_get( PREF_KEY_OPTIONS_PROMPT ); 635 const gboolean do_notify = TRUE; 636 637 gtr_core_add_files( cbdata->core, files, do_start, do_prompt, do_notify ); 638 } 639 640 static void 641 on_open (GApplication * application UNUSED, 642 GFile ** f, 643 gint file_count, 644 gchar * hint UNUSED, 645 gpointer gdata ) 646 { 647 int i; 648 GSList * files = NULL; 649 650 for( i=0; i<file_count; ++i ) 651 files = g_slist_append( files, f[i] ); 652 653 open_files( files, gdata ); 654 655 g_slist_free( files ); 656 } 657 658 /*** 659 **** 660 ***/ 661 621 662 int 622 663 main( int argc, char ** argv ) 623 664 { 624 char * err = NULL; 625 GSList * argfiles; 626 GError * gerr; 627 gboolean didinit = FALSE; 628 gboolean didlock = FALSE; 629 gboolean showversion = FALSE; 630 gboolean startpaused = FALSE; 631 gboolean startminimized = FALSE; 632 const char * domain = MY_READABLE_NAME; 633 char * configDir = NULL; 634 gtr_lockfile_state_t tr_state; 635 636 GOptionEntry entries[] = { 637 { "paused", 'p', 0, G_OPTION_ARG_NONE, 638 &startpaused, _( "Start with all torrents paused" ), NULL }, 639 { "version", '\0', 0, G_OPTION_ARG_NONE, 640 &showversion, _( "Show version number and exit" ), NULL }, 641 { "minimized", 'm', 0, G_OPTION_ARG_NONE, 642 &startminimized, 643 _( "Start minimized in notification area" ), NULL }, 644 { "config-dir", 'g', 0, G_OPTION_ARG_FILENAME, &configDir, 645 _( "Where to look for configuration files" ), NULL }, 665 int ret; 666 struct stat sb; 667 char * application_id; 668 GApplication * app; 669 GOptionContext * option_context; 670 bool show_version = false; 671 GError * error = NULL; 672 struct cbdata cbdata; 673 674 GOptionEntry option_entries[] = { 675 { "config-dir", 'g', 0, G_OPTION_ARG_FILENAME, &cbdata.config_dir, _( "Where to look for configuration files" ), NULL }, 676 { "paused", 'p', 0, G_OPTION_ARG_NONE, &cbdata.start_paused, _( "Start with all torrents paused" ), NULL }, 677 { "minimized", 'm', 0, G_OPTION_ARG_NONE, &cbdata.is_iconified, _( "Start minimized in notification area" ), NULL }, 678 { "version", 'v', 0, G_OPTION_ARG_NONE, &show_version, _( "Show version number and exit" ), NULL }, 646 679 { NULL, 0, 0, 0, NULL, NULL, NULL } 647 680 }; 648 681 649 /* bind the gettext domain */ 682 /* default settings */ 683 memset( &cbdata, 0, sizeof( struct cbdata ) ); 684 cbdata.config_dir = (char*) tr_getDefaultConfigDir( MY_CONFIG_NAME ); 685 686 /* init i18n */ 650 687 setlocale( LC_ALL, "" ); 651 bindtextdomain( domain, TRANSMISSIONLOCALEDIR ); 652 bind_textdomain_codeset( domain, "UTF-8" ); 653 textdomain( domain ); 654 g_set_application_name( _( "Transmission" ) ); 688 bindtextdomain( MY_READABLE_NAME, TRANSMISSIONLOCALEDIR ); 689 bind_textdomain_codeset( MY_READABLE_NAME, "UTF-8" ); 690 textdomain( MY_READABLE_NAME ); 691 692 /* init glib/gtk */ 693 g_thread_init (NULL); 694 g_type_init (); 695 gtk_init (&argc, &argv); 696 g_set_application_name (_( "Transmission" )); 697 gtk_window_set_default_icon_name (MY_CONFIG_NAME); 698 699 700 /* parse the command line */ 701 option_context = g_option_context_new( _( "[torrent files or urls]" ) ); 702 g_option_context_add_main_entries( option_context, option_entries, GETTEXT_PACKAGE ); 703 g_option_context_set_translation_domain( option_context, GETTEXT_PACKAGE ); 704 if( !g_option_context_parse( option_context, &argc, &argv, &error ) ) { 705 g_print (_("%s\nRun '%s --help' to see a full list of available command line options.\n"), error->message, argv[0]); 706 g_error_free (error); 707 g_option_context_free (option_context); 708 return 1; 709 } 710 g_option_context_free (option_context); 711 712 /* handle the trivial "version" option */ 713 if( show_version ) { 714 fprintf( stderr, "%s %s\n", MY_READABLE_NAME, LONG_VERSION_STRING ); 715 return 0; 716 } 717 718 /* init the unit formatters */ 655 719 tr_formatter_mem_init( mem_K, _(mem_K_str), _(mem_M_str), _(mem_G_str), _(mem_T_str) ); 656 720 tr_formatter_size_init( disk_K, _(disk_K_str), _(disk_M_str), _(disk_G_str), _(disk_T_str) ); 657 721 tr_formatter_speed_init( speed_K, _(speed_K_str), _(speed_M_str), _(speed_G_str), _(speed_T_str) ); 658 722 659 /* initialize gtk */ 660 if( !g_thread_supported( ) ) 661 g_thread_init( NULL ); 662 663 gerr = NULL; 664 if( !gtk_init_with_args( &argc, &argv, (char*)_( "[torrent files or urls]" ), entries, 665 (char*)domain, &gerr ) ) 666 { 667 fprintf( stderr, "%s\n", gerr->message ); 668 g_clear_error( &gerr ); 669 return 0; 670 } 671 672 if( showversion ) 673 { 674 fprintf( stderr, "%s %s\n", MY_READABLE_NAME, LONG_VERSION_STRING ); 675 return 0; 676 } 677 678 if( configDir == NULL ) 679 configDir = (char*) tr_getDefaultConfigDir( MY_CONFIG_NAME ); 680 681 didinit = cf_init( configDir, NULL ); /* must come before actions_init */ 682 683 setupsighandlers( ); /* set up handlers for fatal signals */ 684 685 didlock = cf_lock( &tr_state, &err ); 686 argfiles = checkfilenames( argc - 1, argv + 1 ); 687 688 if( !didlock && argfiles ) 689 { 690 /* We have torrents to add but there's another copy of Transmsision 691 * running... chances are we've been invoked from a browser, etc. 692 * So send the files over to the "real" copy of Transmission, and 693 * if that goes well, then our work is done. */ 694 GSList * l; 695 gboolean delegated = FALSE; 696 const gboolean trash_originals = gtr_pref_flag_get( TR_PREFS_KEY_TRASH_ORIGINAL ); 697 698 for( l=argfiles; l!=NULL; l=l->next ) 699 { 700 const char * filename = l->data; 701 const gboolean added = gtr_dbus_add_torrent( filename ); 702 703 if( added && trash_originals ) 704 gtr_file_trash_or_remove( filename ); 705 706 delegated |= added; 707 } 708 709 if( delegated ) { 710 g_slist_foreach( argfiles, (GFunc)g_free, NULL ); 711 g_slist_free( argfiles ); 712 argfiles = NULL; 713 714 if( err ) { 715 g_free( err ); 716 err = NULL; 717 } 718 } 719 } 720 else if( ( !didlock ) && ( tr_state == GTR_LOCKFILE_ELOCK ) ) 721 { 722 /* There's already another copy of Transmission running, 723 * so tell it to present its window to the user */ 724 err = NULL; 725 if( !gtr_dbus_present_window( ) ) 726 err = g_strdup( _( "Transmission is already running, but is not responding. To start a new session, you must first close the existing Transmission process." ) ); 727 } 728 729 if( didlock && ( didinit || cf_init( configDir, &err ) ) ) 730 { 731 /* No other copy of Transmission running... 732 * so we're going to be the primary. */ 733 734 const char * str; 735 GtkWindow * win; 736 GtkUIManager * myUIManager; 737 tr_session * session; 738 struct cbdata * cbdata = g_new0( struct cbdata, 1 ); 739 740 sighandler_cbdata = cbdata; 741 742 /* ensure the directories are created */ 743 if(( str = gtr_pref_string_get( TR_PREFS_KEY_DOWNLOAD_DIR ))) 744 g_mkdir_with_parents( str, 0777 ); 745 if(( str = gtr_pref_string_get( TR_PREFS_KEY_INCOMPLETE_DIR ))) 746 g_mkdir_with_parents( str, 0777 ); 747 748 /* initialize the libtransmission session */ 749 session = tr_sessionInit( "gtk", configDir, TRUE, gtr_pref_get_all( ) ); 750 751 gtr_pref_flag_set( TR_PREFS_KEY_ALT_SPEED_ENABLED, tr_sessionUsesAltSpeed( session ) ); 752 gtr_pref_int_set( TR_PREFS_KEY_PEER_PORT, tr_sessionGetPeerPort( session ) ); 753 cbdata->core = gtr_core_new( session ); 754 755 /* init the ui manager */ 756 myUIManager = gtk_ui_manager_new ( ); 757 gtr_actions_init ( myUIManager, cbdata ); 758 gtk_ui_manager_add_ui_from_string ( myUIManager, fallback_ui_file, -1, NULL ); 759 gtk_ui_manager_ensure_update ( myUIManager ); 760 gtk_window_set_default_icon_name ( MY_CONFIG_NAME ); 761 762 /* create main window now to be a parent to any error dialogs */ 763 win = GTK_WINDOW( gtr_window_new( myUIManager, cbdata->core ) ); 764 g_signal_connect( win, "size-allocate", G_CALLBACK( on_main_window_size_allocated ), cbdata ); 765 766 app_setup( win, argfiles, cbdata, startpaused, startminimized ); 767 tr_sessionSetRPCCallback( session, on_rpc_changed, cbdata ); 768 769 /* on startup, check & see if it's time to update the blocklist */ 770 if( gtr_pref_flag_get( TR_PREFS_KEY_BLOCKLIST_ENABLED ) ) { 771 if( gtr_pref_flag_get( PREF_KEY_BLOCKLIST_UPDATES_ENABLED ) ) { 772 const int64_t last_time = gtr_pref_int_get( "blocklist-date" ); 773 const int SECONDS_IN_A_WEEK = 7 * 24 * 60 * 60; 774 const time_t now = time( NULL ); 775 if( last_time + SECONDS_IN_A_WEEK < now ) 776 gtr_core_blocklist_update( cbdata->core ); 777 } 778 } 779 780 /* if there's no magnet link handler registered, register us */ 781 register_magnet_link_handler( ); 782 783 gtk_main( ); 784 } 785 else if( err ) 786 { 787 const char * primary_text = _( "Transmission cannot be started." ); 788 GtkWidget * w = gtk_message_dialog_new( NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, primary_text, NULL ); 789 gtk_message_dialog_format_secondary_text( GTK_MESSAGE_DIALOG( w ), "%s", err ); 790 g_signal_connect( w, "response", G_CALLBACK(gtk_main_quit), NULL ); 791 gtk_widget_show( w ); 792 g_free( err ); 793 gtk_main( ); 794 } 795 796 return 0; 723 /* set up the config dir */ 724 gtr_pref_init( cbdata.config_dir ); 725 g_mkdir_with_parents( cbdata.config_dir, 0755 ); 726 727 /* init the application for the specified config dir */ 728 stat( cbdata.config_dir, &sb ); 729 application_id = g_strdup_printf( "com.transmissionbt.transmission_%lu_%lu", (unsigned long)sb.st_dev, (unsigned long)sb.st_ino ); 730 app = g_application_new( application_id, G_APPLICATION_HANDLES_OPEN ); 731 g_signal_connect( app, "open", G_CALLBACK(on_open), &cbdata ); 732 g_signal_connect( app, "startup", G_CALLBACK(on_startup), &cbdata ); 733 g_signal_connect( app, "activate", G_CALLBACK(on_activate), &cbdata ); 734 ret = g_application_run (app, argc, argv); 735 g_object_unref( app ); 736 return ret; 797 737 } 798 738 … … 804 744 805 745 static void 806 app_setup( TrWindow * wind, 807 GSList * files, 808 struct cbdata * cbdata, 809 gboolean pause_all, 810 gboolean is_iconified ) 811 { 812 const gboolean do_start = gtr_pref_flag_get( TR_PREFS_KEY_START ) && !pause_all; 813 const gboolean do_prompt = gtr_pref_flag_get( PREF_KEY_OPTIONS_PROMPT ); 814 const gboolean do_notify = TRUE; 815 816 cbdata->is_iconified = is_iconified; 817 818 if( is_iconified ) 746 app_setup( TrWindow * wind, struct cbdata * cbdata ) 747 { 748 if( cbdata->is_iconified ) 819 749 gtr_pref_flag_set( PREF_KEY_SHOW_TRAY_ICON, TRUE ); 820 750 … … 828 758 829 759 /* add torrents from command-line and saved state */ 830 gtr_core_load( cbdata->core, pause_all ); 831 gtr_core_add_list( cbdata->core, files, do_start, do_prompt, do_notify ); 832 files = NULL; 760 gtr_core_load( cbdata->core, cbdata->start_paused ); 833 761 gtr_core_torrents_added( cbdata->core ); 834 762 … … 844 772 845 773 /* either show the window or iconify it */ 846 if( ! is_iconified )774 if( !cbdata->is_iconified ) 847 775 gtk_widget_show( GTK_WIDGET( wind ) ); 848 776 else … … 955 883 gpointer gdata ) 956 884 { 957 int i; 958 gboolean success = FALSE; 885 guint i; 886 char ** uris = gtk_selection_data_get_uris( selection_data ); 887 const guint file_count = g_strv_length( uris ); 959 888 GSList * files = NULL; 960 struct cbdata * data = gdata; 961 char ** uris = gtk_selection_data_get_uris( selection_data ); 962 963 /* try to add the filename URIs... */ 964 for( i=0; uris && uris[i]; ++i ) 965 { 966 const char * uri = uris[i]; 967 char * filename = g_filename_from_uri( uri, NULL, NULL ); 968 969 if( filename && g_file_test( filename, G_FILE_TEST_EXISTS ) ) 970 { 971 files = g_slist_append( files, g_strdup( filename ) ); 972 success = TRUE; 973 } 974 else if( tr_urlIsValid( uri, -1 ) || gtr_is_magnet_link( uri ) ) 975 { 976 gtr_core_add_from_url( data->core, uri ); 977 success = TRUE; 978 } 979 980 g_free( filename ); 981 } 982 983 if( files ) 984 gtr_core_add_list_defaults( data->core, g_slist_reverse( files ), TRUE ); 985 986 gtr_core_torrents_added( data->core ); 987 gtk_drag_finish( drag_context, success, FALSE, time_ ); 889 890 for( i=0; i<file_count; ++i ) 891 files = g_slist_append( files, g_file_new_for_uri( uris[i] ) ); 892 893 open_files( files, gdata ); 988 894 989 895 /* cleanup */ 896 g_slist_foreach( files, (GFunc)g_object_unref, NULL ); 897 g_slist_free( files ); 990 898 g_strfreev( uris ); 899 900 gtk_drag_finish( drag_context, true, FALSE, time_ ); 991 901 } 992 902 … … 1038 948 g_slist_foreach( cbdata->duplicates_list, (GFunc)g_free, NULL ); 1039 949 g_slist_free( cbdata->duplicates_list ); 1040 g_free( cbdata );1041 1042 gtk_main_quit( );1043 950 1044 951 return FALSE;
Note: See TracChangeset
for help on using the changeset viewer.