mirror of
https://github.com/transmission/transmission
synced 2024-12-26 01:27:28 +00:00
879a2afcbd
The Berne Convention says that the copyright year is moot, so instead of adding another year to each file as in previous years, I've removed the year altogether from the source code comments in libtransmission, gtk, qt, utils, daemon, and cli. Juliusz's copyright notice in tr-dht and Johannes' copyright notice in tr-lpd have been left alone; it didn't seem appropriate to modify them.
526 lines
18 KiB
C
526 lines
18 KiB
C
/*
|
|
* This file Copyright (C) Mnemosyne LLC
|
|
*
|
|
* This file is licensed by the GPL version 2. Works owned by the
|
|
* Transmission project are granted a special exemption to clause 2(b)
|
|
* so that the bulk of its code can remain under the MIT license.
|
|
* This exemption does not extend to derived works not owned by
|
|
* the Transmission project.
|
|
*
|
|
* $Id$
|
|
*/
|
|
|
|
#include <string.h>
|
|
|
|
#include <glib/gi18n.h>
|
|
#include <gtk/gtk.h>
|
|
|
|
#include <libtransmission/transmission.h>
|
|
#include <libtransmission/makemeta.h>
|
|
#include <libtransmission/utils.h> /* tr_formatter_mem_B() */
|
|
|
|
#include "conf.h"
|
|
#include "hig.h"
|
|
#include "makemeta-ui.h"
|
|
#include "tr-core.h"
|
|
#include "tr-prefs.h"
|
|
#include "util.h"
|
|
|
|
#define FILE_CHOSEN_KEY "file-is-chosen"
|
|
|
|
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;
|
|
GtkWidget * comment_check;
|
|
GtkWidget * comment_entry;
|
|
GtkWidget * private_check;
|
|
GtkWidget * progress_label;
|
|
GtkWidget * progress_bar;
|
|
GtkWidget * progress_dialog;
|
|
GtkWidget * dialog;
|
|
GtkTextBuffer * announce_text_buffer;
|
|
TrCore * core;
|
|
tr_metainfo_builder * builder;
|
|
}
|
|
MakeMetaUI;
|
|
|
|
static void
|
|
freeMetaUI( gpointer p )
|
|
{
|
|
MakeMetaUI * ui = p;
|
|
|
|
tr_metaInfoBuilderFree( ui->builder );
|
|
g_free( ui->target );
|
|
memset( ui, ~0, sizeof( MakeMetaUI ) );
|
|
g_free( ui );
|
|
}
|
|
|
|
static gboolean
|
|
onProgressDialogRefresh( gpointer data )
|
|
{
|
|
char * str = NULL;
|
|
MakeMetaUI * ui = data;
|
|
const tr_metainfo_builder * b = ui->builder;
|
|
GtkDialog * d = GTK_DIALOG( ui->progress_dialog );
|
|
GtkProgressBar * p = GTK_PROGRESS_BAR( ui->progress_bar );
|
|
const double fraction = b->pieceCount ? ((double)b->pieceIndex / b->pieceCount) : 0;
|
|
char * base = g_path_get_basename( b->top );
|
|
|
|
/* progress label */
|
|
if( !b->isDone )
|
|
str = g_strdup_printf( _( "Creating \"%s\"" ), base );
|
|
else if( b->result == TR_MAKEMETA_OK )
|
|
str = g_strdup_printf( _( "Created \"%s\"!" ), base );
|
|
else if( b->result == TR_MAKEMETA_URL )
|
|
str = g_strdup_printf( _( "Error: invalid announce URL \"%s\"" ), b->errfile );
|
|
else if( b->result == TR_MAKEMETA_CANCELLED )
|
|
str = g_strdup_printf( _( "Cancelled" ) );
|
|
else if( b->result == TR_MAKEMETA_IO_READ )
|
|
str = g_strdup_printf( _( "Error reading \"%s\": %s" ), b->errfile, g_strerror( b->my_errno ) );
|
|
else if( b->result == TR_MAKEMETA_IO_WRITE )
|
|
str = g_strdup_printf( _( "Error writing \"%s\": %s" ), b->errfile, g_strerror( b->my_errno ) );
|
|
else
|
|
g_assert_not_reached( );
|
|
|
|
if( str != NULL ) {
|
|
gtk_label_set_text( GTK_LABEL( ui->progress_label ), str );
|
|
g_free( str );
|
|
}
|
|
|
|
/* progress bar */
|
|
if( !b->pieceIndex )
|
|
str = g_strdup( "" );
|
|
else {
|
|
char sizebuf[128];
|
|
tr_strlsize( sizebuf, (uint64_t)b->pieceIndex *
|
|
(uint64_t)b->pieceSize, sizeof( sizebuf ) );
|
|
/* how much data we've scanned through to generate checksums */
|
|
str = g_strdup_printf( _( "Scanned %s" ), sizebuf );
|
|
}
|
|
gtk_progress_bar_set_fraction( p, fraction );
|
|
gtk_progress_bar_set_text( p, str );
|
|
g_free( str );
|
|
|
|
/* buttons */
|
|
gtk_dialog_set_response_sensitive( d, GTK_RESPONSE_CANCEL, !b->isDone );
|
|
gtk_dialog_set_response_sensitive( d, GTK_RESPONSE_CLOSE, b->isDone );
|
|
gtk_dialog_set_response_sensitive( d, GTK_RESPONSE_ACCEPT, b->isDone && !b->result );
|
|
|
|
g_free( base );
|
|
return TRUE;
|
|
}
|
|
|
|
static void
|
|
onProgressDialogDestroyed( gpointer data, GObject * dead UNUSED )
|
|
{
|
|
MakeMetaUI * ui = data;
|
|
g_source_remove( ui->progress_tag );
|
|
}
|
|
|
|
static void
|
|
addTorrent( MakeMetaUI * ui )
|
|
{
|
|
char * path;
|
|
const tr_metainfo_builder * b = ui->builder;
|
|
tr_ctor * ctor = tr_ctorNew( tr_core_session( ui->core ) );
|
|
|
|
tr_ctorSetMetainfoFromFile( ctor, ui->target );
|
|
|
|
path = g_path_get_dirname( b->top );
|
|
tr_ctorSetDownloadDir( ctor, TR_FORCE, path );
|
|
g_free( path );
|
|
|
|
tr_core_add_ctor( ui->core, ctor );
|
|
}
|
|
|
|
static void
|
|
onProgressDialogResponse( GtkDialog * d, int response, gpointer data )
|
|
{
|
|
MakeMetaUI * ui = data;
|
|
|
|
switch( response )
|
|
{
|
|
case GTK_RESPONSE_CANCEL:
|
|
ui->builder->abortFlag = TRUE;
|
|
gtk_widget_destroy( GTK_WIDGET( d ) );
|
|
break;
|
|
case GTK_RESPONSE_ACCEPT:
|
|
addTorrent( ui );
|
|
/* fall-through */
|
|
case GTK_RESPONSE_CLOSE:
|
|
gtk_widget_destroy( ui->builder->result ? GTK_WIDGET( d ) : ui->dialog );
|
|
break;
|
|
default:
|
|
g_assert( 0 && "unhandled response" );
|
|
}
|
|
}
|
|
|
|
static void
|
|
makeProgressDialog( GtkWidget * parent, MakeMetaUI * ui )
|
|
{
|
|
GtkWidget *d, *l, *w, *v, *fr;
|
|
|
|
d = gtk_dialog_new_with_buttons( _( "New Torrent" ),
|
|
GTK_WINDOW( parent ),
|
|
GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
|
|
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
|
GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
|
|
GTK_STOCK_ADD, GTK_RESPONSE_ACCEPT,
|
|
NULL );
|
|
ui->progress_dialog = d;
|
|
g_signal_connect( d, "response", G_CALLBACK( onProgressDialogResponse ), ui );
|
|
|
|
fr = gtk_frame_new( NULL );
|
|
gtk_container_set_border_width( GTK_CONTAINER( fr ), GUI_PAD_BIG );
|
|
gtk_frame_set_shadow_type( GTK_FRAME( fr ), GTK_SHADOW_NONE );
|
|
v = gtk_vbox_new( TRUE, GUI_PAD );
|
|
gtk_container_add( GTK_CONTAINER( fr ), v );
|
|
|
|
l = gtk_label_new( _( "Creating torrent..." ) );
|
|
gtk_misc_set_alignment( GTK_MISC( l ), 0.0, 0.5 );
|
|
gtk_label_set_justify( GTK_LABEL( l ), GTK_JUSTIFY_LEFT );
|
|
ui->progress_label = l;
|
|
gtk_box_pack_start( GTK_BOX( v ), l, FALSE, FALSE, 0 );
|
|
|
|
w = gtk_progress_bar_new( );
|
|
ui->progress_bar = w;
|
|
gtk_box_pack_start( GTK_BOX( v ), w, FALSE, FALSE, 0 );
|
|
|
|
ui->progress_tag = gtr_timeout_add_seconds( SECONDARY_WINDOW_REFRESH_INTERVAL_SECONDS, onProgressDialogRefresh, ui );
|
|
g_object_weak_ref( G_OBJECT( d ), onProgressDialogDestroyed, ui );
|
|
onProgressDialogRefresh( ui );
|
|
|
|
gtr_dialog_set_content( GTK_DIALOG( d ), fr );
|
|
gtk_widget_show( d );
|
|
}
|
|
|
|
static void
|
|
onResponse( GtkDialog* d, int response, gpointer user_data )
|
|
{
|
|
MakeMetaUI * ui = user_data;
|
|
|
|
if( response == GTK_RESPONSE_ACCEPT )
|
|
{
|
|
if( ui->builder != NULL )
|
|
{
|
|
int i;
|
|
int n;
|
|
int tier;
|
|
GtkTextIter start, end;
|
|
char * dir;
|
|
char * base;
|
|
char * tracker_text;
|
|
char ** tracker_strings;
|
|
GtkEntry * c_entry = GTK_ENTRY( ui->comment_entry );
|
|
GtkToggleButton * p_check = GTK_TOGGLE_BUTTON( ui->private_check );
|
|
GtkToggleButton * c_check = GTK_TOGGLE_BUTTON( ui->comment_check );
|
|
const char * comment = gtk_entry_get_text( c_entry );
|
|
const gboolean isPrivate = gtk_toggle_button_get_active( p_check );
|
|
const gboolean useComment = gtk_toggle_button_get_active( c_check );
|
|
tr_tracker_info * trackers;
|
|
|
|
/* destination file */
|
|
dir = gtk_file_chooser_get_filename(
|
|
GTK_FILE_CHOOSER( ui->destination_chooser ) );
|
|
base = g_path_get_basename( ui->builder->top );
|
|
g_free( ui->target );
|
|
ui->target = g_strdup_printf( "%s/%s.torrent", dir, base );
|
|
|
|
/* build the array of trackers */
|
|
gtk_text_buffer_get_bounds( ui->announce_text_buffer, &start, &end );
|
|
tracker_text = gtk_text_buffer_get_text( ui->announce_text_buffer,
|
|
&start, &end, FALSE );
|
|
tracker_strings = g_strsplit( tracker_text, "\n", 0 );
|
|
for( i=0; tracker_strings[i]; )
|
|
++i;
|
|
trackers = g_new0( tr_tracker_info, i );
|
|
for( i=n=tier=0; tracker_strings[i]; ++i ) {
|
|
const char * str = tracker_strings[i];
|
|
if( !*str )
|
|
++tier;
|
|
else {
|
|
trackers[n].tier = tier;
|
|
trackers[n].announce = tracker_strings[i];
|
|
++n;
|
|
}
|
|
}
|
|
|
|
/* build the .torrent */
|
|
makeProgressDialog( GTK_WIDGET( d ), ui );
|
|
tr_makeMetaInfo( ui->builder, ui->target, trackers, n,
|
|
useComment ? comment : NULL, isPrivate );
|
|
|
|
/* cleanup */
|
|
g_free( trackers );
|
|
g_strfreev( tracker_strings );
|
|
g_free( tracker_text );
|
|
g_free( base );
|
|
g_free( dir );
|
|
}
|
|
}
|
|
else if( response == GTK_RESPONSE_CLOSE )
|
|
{
|
|
gtk_widget_destroy( GTK_WIDGET( d ) );
|
|
}
|
|
}
|
|
|
|
/***
|
|
****
|
|
***/
|
|
|
|
static void
|
|
onSourceToggled( GtkToggleButton * tb, gpointer user_data )
|
|
{
|
|
gtk_widget_set_sensitive( GTK_WIDGET( user_data ),
|
|
gtk_toggle_button_get_active( tb ) );
|
|
}
|
|
|
|
static void
|
|
updatePiecesLabel( MakeMetaUI * ui )
|
|
{
|
|
const tr_metainfo_builder * builder = ui->builder;
|
|
const char * filename = builder ? builder->top : NULL;
|
|
GString * gstr = g_string_new( NULL );
|
|
|
|
g_string_append( gstr, "<i>" );
|
|
if( !filename )
|
|
{
|
|
g_string_append( gstr, _( "No source selected" ) );
|
|
}
|
|
else
|
|
{
|
|
char buf[128];
|
|
tr_strlsize( buf, builder->totalSize, sizeof( buf ) );
|
|
g_string_append_printf( gstr, gtr_ngettext( "%1$s; %2$'d File",
|
|
"%1$s; %2$'d Files",
|
|
builder->fileCount ),
|
|
buf, builder->fileCount );
|
|
g_string_append( gstr, "; " );
|
|
|
|
tr_formatter_mem_B( buf, builder->pieceSize, sizeof( buf ) );
|
|
g_string_append_printf( gstr, gtr_ngettext( "%1$'d Piece @ %2$s",
|
|
"%1$'d Pieces @ %2$s",
|
|
builder->pieceCount ),
|
|
builder->pieceCount, buf );
|
|
}
|
|
g_string_append( gstr, "</i>" );
|
|
gtk_label_set_markup ( GTK_LABEL( ui->pieces_lb ), gstr->str );
|
|
g_string_free( gstr, TRUE );
|
|
}
|
|
|
|
static void
|
|
setFilename( MakeMetaUI * ui, const char * filename )
|
|
{
|
|
if( ui->builder ) {
|
|
tr_metaInfoBuilderFree( ui->builder );
|
|
ui->builder = NULL;
|
|
}
|
|
|
|
if( filename )
|
|
ui->builder = tr_metaInfoBuilderCreate( filename );
|
|
|
|
updatePiecesLabel( ui );
|
|
}
|
|
|
|
static void
|
|
onChooserChosen( GtkFileChooser * chooser, gpointer user_data )
|
|
{
|
|
char * filename;
|
|
MakeMetaUI * ui = user_data;
|
|
|
|
g_object_set_data( G_OBJECT( chooser ), FILE_CHOSEN_KEY,
|
|
GINT_TO_POINTER( TRUE ) );
|
|
|
|
filename = gtk_file_chooser_get_filename( chooser );
|
|
setFilename( ui, filename );
|
|
g_free( filename );
|
|
}
|
|
|
|
static void
|
|
onSourceToggled2( GtkToggleButton * tb, GtkWidget * chooser, MakeMetaUI * ui )
|
|
{
|
|
if( gtk_toggle_button_get_active( tb ) )
|
|
{
|
|
if( g_object_get_data( G_OBJECT( chooser ), FILE_CHOSEN_KEY ) != NULL )
|
|
onChooserChosen( GTK_FILE_CHOOSER( chooser ), ui );
|
|
else
|
|
setFilename( ui, NULL );
|
|
}
|
|
}
|
|
static void
|
|
onFolderToggled( GtkToggleButton * tb, gpointer data )
|
|
{
|
|
MakeMetaUI * ui = data;
|
|
onSourceToggled2( tb, ui->folder_chooser, ui );
|
|
}
|
|
static void
|
|
onFileToggled( GtkToggleButton * tb, gpointer data )
|
|
{
|
|
MakeMetaUI * ui = data;
|
|
onSourceToggled2( tb, ui->file_chooser, ui );
|
|
}
|
|
|
|
static const char *
|
|
getDefaultSavePath( void )
|
|
{
|
|
const char * path;
|
|
#if GLIB_CHECK_VERSION( 2,14,0 )
|
|
path = g_get_user_special_dir( G_USER_DIRECTORY_DESKTOP );
|
|
#else
|
|
path = g_get_home_dir( );
|
|
#endif
|
|
return path;
|
|
}
|
|
|
|
static void
|
|
on_drag_data_received( GtkWidget * widget UNUSED,
|
|
GdkDragContext * drag_context,
|
|
gint x UNUSED,
|
|
gint y UNUSED,
|
|
GtkSelectionData * selection_data,
|
|
guint info UNUSED,
|
|
guint time_,
|
|
gpointer user_data )
|
|
{
|
|
gboolean success = FALSE;
|
|
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 );
|
|
success = TRUE;
|
|
}
|
|
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 );
|
|
success = TRUE;
|
|
}
|
|
|
|
g_free( filename );
|
|
}
|
|
|
|
g_strfreev( uris );
|
|
gtk_drag_finish( drag_context, success, FALSE, time_ );
|
|
}
|
|
|
|
GtkWidget*
|
|
gtr_torrent_creation_dialog_new( GtkWindow * parent, TrCore * core )
|
|
{
|
|
int row = 0;
|
|
const char * str;
|
|
GtkWidget * d, *t, *w, *l, *fr, *sw, *v;
|
|
GSList * slist;
|
|
MakeMetaUI * ui = g_new0 ( MakeMetaUI, 1 );
|
|
|
|
ui->core = core;
|
|
|
|
d = gtk_dialog_new_with_buttons( _( "New Torrent" ),
|
|
parent,
|
|
GTK_DIALOG_DESTROY_WITH_PARENT,
|
|
GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
|
|
GTK_STOCK_NEW, GTK_RESPONSE_ACCEPT,
|
|
NULL );
|
|
ui->dialog = d;
|
|
g_signal_connect( d, "response", G_CALLBACK( onResponse ), ui );
|
|
g_object_set_data_full( G_OBJECT( d ), "ui", ui, freeMetaUI );
|
|
|
|
t = hig_workarea_create ( );
|
|
|
|
hig_workarea_add_section_title ( t, &row, _( "Files" ) );
|
|
|
|
str = _( "Sa_ve to:" );
|
|
w = gtk_file_chooser_button_new( NULL, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER );
|
|
gtk_file_chooser_set_current_folder( GTK_FILE_CHOOSER( w ), getDefaultSavePath( ) );
|
|
ui->destination_chooser = w;
|
|
hig_workarea_add_row( t, &row, str, w, NULL );
|
|
|
|
l = gtk_radio_button_new_with_mnemonic( NULL, _( "Source F_older:" ) );
|
|
gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( l ), FALSE );
|
|
w = gtk_file_chooser_button_new( NULL, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER );
|
|
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 );
|
|
|
|
slist = gtk_radio_button_get_group( GTK_RADIO_BUTTON( l ) ),
|
|
l = gtk_radio_button_new_with_mnemonic( slist, _( "Source _File:" ) );
|
|
gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( l ), TRUE );
|
|
w = gtk_file_chooser_button_new( NULL, GTK_FILE_CHOOSER_ACTION_OPEN );
|
|
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 );
|
|
|
|
w = gtk_label_new( NULL );
|
|
ui->pieces_lb = w;
|
|
gtk_label_set_markup( GTK_LABEL( w ), _( "<i>No source selected</i>" ) );
|
|
hig_workarea_add_row( t, &row, NULL, w, NULL );
|
|
|
|
hig_workarea_add_section_divider( t, &row );
|
|
hig_workarea_add_section_title ( t, &row, _( "Properties" ) );
|
|
|
|
str = _( "_Trackers:" );
|
|
v = gtk_vbox_new( FALSE, GUI_PAD_SMALL );
|
|
ui->announce_text_buffer = gtk_text_buffer_new( NULL );
|
|
w = gtk_text_view_new_with_buffer( ui->announce_text_buffer );
|
|
gtk_widget_set_size_request( w, -1, 80 );
|
|
sw = gtk_scrolled_window_new( NULL, NULL );
|
|
gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( sw ),
|
|
GTK_POLICY_AUTOMATIC,
|
|
GTK_POLICY_AUTOMATIC );
|
|
gtk_container_add( GTK_CONTAINER( sw ), w );
|
|
fr = gtk_frame_new( NULL );
|
|
gtk_frame_set_shadow_type( GTK_FRAME( fr ), GTK_SHADOW_IN );
|
|
gtk_container_add( GTK_CONTAINER( fr ), sw );
|
|
gtk_box_pack_start( GTK_BOX( v ), fr, TRUE, TRUE, 0 );
|
|
l = gtk_label_new( NULL );
|
|
gtk_label_set_markup( GTK_LABEL( l ), _( "To add a backup URL, add it on the line after the primary URL.\n"
|
|
"To add another primary URL, add it after a blank line." ) );
|
|
gtk_label_set_justify( GTK_LABEL( l ), GTK_JUSTIFY_LEFT );
|
|
gtk_misc_set_alignment( GTK_MISC( l ), 0.0, 0.5 );
|
|
gtk_box_pack_start( GTK_BOX( v ), l, FALSE, FALSE, 0 );
|
|
hig_workarea_add_tall_row( t, &row, str, v, NULL );
|
|
|
|
l = gtk_check_button_new_with_mnemonic( _( "Co_mment:" ) );
|
|
ui->comment_check = l;
|
|
gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( l ), FALSE );
|
|
w = gtk_entry_new( );
|
|
ui->comment_entry = w;
|
|
gtk_widget_set_sensitive( GTK_WIDGET( w ), FALSE );
|
|
g_signal_connect( l, "toggled", G_CALLBACK( onSourceToggled ), w );
|
|
hig_workarea_add_row_w( t, &row, l, w, NULL );
|
|
|
|
w = hig_workarea_add_wide_checkbutton( t, &row, _( "_Private torrent" ), FALSE );
|
|
ui->private_check = w;
|
|
|
|
hig_workarea_finish( t, &row );
|
|
gtr_dialog_set_content( GTK_DIALOG( d ), t );
|
|
|
|
gtk_drag_dest_set( d, GTK_DEST_DEFAULT_ALL, NULL, 0, GDK_ACTION_COPY );
|
|
gtk_drag_dest_add_uri_targets( d );
|
|
g_signal_connect( d, "drag-data-received", G_CALLBACK( on_drag_data_received ), ui );
|
|
|
|
return d;
|
|
}
|