From 5182600179be574320accfebcc2bb5fd0d5f5e74 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 2 Aug 2010 20:55:11 +0000 Subject: [PATCH] (trunk) add drag-and-drop support to the "create new torrent" dialogs in the Qt and GTK+ clients --- gtk/makemeta-ui.c | 46 +++++++++++++++++++++++++++ qt/make-dialog.cc | 79 +++++++++++++++++++++++++++++++++++++---------- qt/make-dialog.h | 9 ++++++ 3 files changed, 117 insertions(+), 17 deletions(-) diff --git a/gtk/makemeta-ui.c b/gtk/makemeta-ui.c index a4ff53ff1..76afd05ec 100644 --- a/gtk/makemeta-ui.c +++ b/gtk/makemeta-ui.c @@ -32,7 +32,9 @@ typedef struct { char * target; guint progress_tag; + GtkWidget * file_radio; GtkWidget * file_chooser; + GtkWidget * folder_radio; GtkWidget * folder_chooser; GtkWidget * pieces_lb; GtkWidget * destination_chooser; @@ -377,6 +379,43 @@ getDefaultSavePath( void ) return path; } +static void +on_drag_data_received( GtkWidget * widget UNUSED, + GdkDragContext * drag_context UNUSED, + gint x UNUSED, + gint y UNUSED, + GtkSelectionData * selection_data, + guint info UNUSED, + guint time UNUSED, + gpointer user_data ) +{ + MakeMetaUI * ui = user_data; + char ** uris = gtk_selection_data_get_uris( selection_data ); + + if( uris && uris[0] ) + { + const char * uri = uris[ 0 ]; + gchar * filename = g_filename_from_uri( uri, NULL, NULL ); + + if( g_file_test( filename, G_FILE_TEST_IS_DIR ) ) + { + /* a directory was dragged onto the dialog... */ + gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( ui->folder_radio ), TRUE ); + gtk_file_chooser_set_current_folder( GTK_FILE_CHOOSER( ui->folder_chooser ), filename ); + } + else if( g_file_test( filename, G_FILE_TEST_IS_REGULAR ) ) + { + /* a file was dragged on to the dialog... */ + gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( ui->file_radio ), TRUE ); + gtk_file_chooser_set_filename( GTK_FILE_CHOOSER( ui->file_chooser ), filename ); + } + + g_free( filename ); + } + + g_strfreev( uris ); +} + GtkWidget* make_meta_ui( GtkWindow * parent, TrCore * core ) { @@ -415,6 +454,7 @@ make_meta_ui( GtkWindow * parent, TrCore * core ) g_signal_connect( l, "toggled", G_CALLBACK( onFolderToggled ), ui ); g_signal_connect( l, "toggled", G_CALLBACK( onSourceToggled ), w ); g_signal_connect( w, "selection-changed", G_CALLBACK( onChooserChosen ), ui ); + ui->folder_radio = l; ui->folder_chooser = w; gtk_widget_set_sensitive( GTK_WIDGET( w ), FALSE ); hig_workarea_add_row_w( t, &row, l, w, NULL ); @@ -426,6 +466,7 @@ make_meta_ui( GtkWindow * parent, TrCore * core ) g_signal_connect( l, "toggled", G_CALLBACK( onFileToggled ), ui ); g_signal_connect( l, "toggled", G_CALLBACK( onSourceToggled ), w ); g_signal_connect( w, "selection-changed", G_CALLBACK( onChooserChosen ), ui ); + ui->file_radio = l; ui->file_chooser = w; hig_workarea_add_row_w( t, &row, l, w, NULL ); @@ -474,5 +515,10 @@ make_meta_ui( GtkWindow * parent, TrCore * core ) hig_workarea_finish( t, &row ); gtk_box_pack_start( GTK_BOX( GTK_DIALOG( d )->vbox ), t, TRUE, TRUE, 0 ); + gtk_drag_dest_set( d, GTK_DEST_DEFAULT_ALL, NULL, 0, GDK_ACTION_COPY ); + gtk_drag_dest_add_uri_targets( d ); + gtk_drag_dest_add_text_targets( d ); + g_signal_connect( d, "drag-data-received", G_CALLBACK( on_drag_data_received ), ui ); + return d; } diff --git a/qt/make-dialog.cc b/qt/make-dialog.cc index 5a2fa3fe1..b4757a0ec 100644 --- a/qt/make-dialog.cc +++ b/qt/make-dialog.cc @@ -177,12 +177,15 @@ MakeDialog :: onFileClicked( ) void MakeDialog :: onFileSelected( const QStringList& list ) { - if( list.size() == 1 ) - { - myFile = list.first( ); - myFileButton->setText( QFileInfo(myFile).fileName() ); - onSourceChanged( ); - } + if( !list.empty( ) ) + onFileSelected( list.front( ) ); +} +void +MakeDialog :: onFileSelected( const QString& filename ) +{ + myFile = filename; + myFileButton->setText( QFileInfo(myFile).fileName() ); + onSourceChanged( ); } void @@ -197,12 +200,15 @@ MakeDialog :: onFolderClicked( ) void MakeDialog :: onFolderSelected( const QStringList& list ) { - if( list.size() == 1 ) - { - myFolder = list.first(); - myFolderButton->setText( QFileInfo(myFolder).fileName() ); - onSourceChanged( ); - } + if( !list.empty( ) ) + onFolderSelected( list.front( ) ); +} +void +MakeDialog :: onFolderSelected( const QString& filename ) +{ + myFolder = filename; + myFolderButton->setText( QFileInfo(myFolder).fileName() ); + onSourceChanged( ); } void @@ -217,11 +223,14 @@ MakeDialog :: onDestinationClicked( ) void MakeDialog :: onDestinationSelected( const QStringList& list ) { - if( list.size() == 1 ) - { - myDestination = list.first( ); - myDestinationButton->setText( QFileInfo(myDestination).fileName() ); - } + if( !list.empty( ) ) + onDestinationSelected( list.front() ); +} +void +MakeDialog :: onDestinationSelected( const QString& filename ) +{ + myDestination = filename; + myDestinationButton->setText( QFileInfo(myDestination).fileName() ); } void @@ -306,6 +315,8 @@ MakeDialog :: MakeDialog( Session & session, QWidget * parent ): mySession( session ), myBuilder( 0 ) { + setAcceptDrops( true ); + connect( &myTimer, SIGNAL(timeout()), this, SLOT(onProgress()) ); setWindowTitle( tr( "New Torrent" ) ); @@ -396,3 +407,37 @@ MakeDialog :: ~MakeDialog( ) if( myBuilder ) tr_metaInfoBuilderFree( myBuilder ); } + +/*** +**** +***/ + +void +MakeDialog :: dragEnterEvent( QDragEnterEvent * event ) +{ + const QMimeData * mime = event->mimeData( ); + + if( mime->urls().size() && QFile(mime->urls().front().path()).exists( ) ) + event->acceptProposedAction(); +} + +void +MakeDialog :: dropEvent( QDropEvent * event ) +{ + const QString filename = event->mimeData()->urls().front().path(); + const QFileInfo fileInfo( filename ); + + if( fileInfo.exists( ) ) + { + if( fileInfo.isDir( ) ) + { + myFolderRadio->setChecked( true ); + onFolderSelected( filename ); + } + else // it's a file + { + myFileRadio->setChecked( true ); + onFileSelected( filename ); + } + } +} diff --git a/qt/make-dialog.h b/qt/make-dialog.h index b06fc57e4..06eb616a5 100644 --- a/qt/make-dialog.h +++ b/qt/make-dialog.h @@ -44,10 +44,15 @@ class MakeDialog: public QDialog void onProgress( ); void onFolderClicked( ); + void onFolderSelected( const QString& ); void onFolderSelected( const QStringList& ); + void onFileClicked( ); + void onFileSelected( const QString& ); void onFileSelected( const QStringList& ); + void onDestinationClicked( ); + void onDestinationSelected( const QString& ); void onDestinationSelected( const QStringList& ); private: @@ -80,6 +85,10 @@ class MakeDialog: public QDialog QDialog * myNewDialog; struct tr_metainfo_builder * myBuilder; + protected: + virtual void dragEnterEvent( QDragEnterEvent * ); + virtual void dropEvent( QDropEvent * ); + public: MakeDialog( Session&, QWidget * parent = 0 ); ~MakeDialog( );