35
38
#include "make-dialog.h"
36
#include "squeezelabel.h"
37
#include "qticonloader.h"
40
MakeDialog :: MakeDialog( Session & mySession, QWidget * parent ):
41
QDialog( parent, Qt::Dialog ),
45
Q_UNUSED( mySession );
46
connect( &myTimer, SIGNAL(timeout()), this, SLOT(onProgress()) );
48
setWindowTitle( tr( "New Torrent" ) );
49
QVBoxLayout * top = new QVBoxLayout( this );
50
top->setSpacing( HIG :: PAD );
53
hig->setContentsMargins( 0, 0, 0, 0 );
54
hig->addSectionTitle( tr( "Source" ) );
55
hig->addWideControl( mySourceEdit = new QLineEdit );
56
connect( mySourceEdit, SIGNAL(textChanged(const QString&)), this, SLOT(refresh()));
57
connect( mySourceEdit, SIGNAL(editingFinished()), this, SLOT(onSourceChanged()));
58
QHBoxLayout * h = new QHBoxLayout;
59
h->setContentsMargins( 0, 0, 0, 0 );
60
h->addWidget( mySourceLabel = new QLabel( tr( "<i>No source selected</i>" ) ) );
61
mySourceLabel->setMinimumWidth( fontMetrics().size( 0, "420 KB in 412 Files; 402 Pieces @ 42 KB each" ).width( ) );
63
h->setSpacing( HIG :: PAD );
64
QPushButton * b = new QPushButton( style()->standardIcon( QStyle::SP_DirIcon ), tr( "F&older" ) );
65
connect( b, SIGNAL(clicked(bool)), this, SLOT(onFolderButtonPressed()));
67
b = new QPushButton( style()->standardIcon( QStyle::SP_FileIcon ), tr( "&File" ) );
68
connect( b, SIGNAL(clicked(bool)), this, SLOT(onFileButtonPressed()));
70
hig->addWideControl( h );
71
hig->addSectionDivider( );
72
hig->addSectionTitle( tr( "Trackers" ) );
73
hig->addWideControl( myTrackerEdit = new QPlainTextEdit );
74
connect( myTrackerEdit, SIGNAL(textChanged()), this, SLOT(refresh()) );
75
const int height = fontMetrics().size( 0, "\n\n\n\n" ).height( );
76
myTrackerEdit->setMinimumHeight( height );
77
myTrackerEdit->setMaximumHeight( height );
78
hig->addWideControl( new QLabel( tr( "Separate tiers with an empty line" ) ) );
79
hig->addSectionDivider( );
80
hig->addSectionTitle( tr( "Options" ) );
81
hig->addRow( tr( "Commen&t:" ), myCommentEdit = new QLineEdit );
82
hig->addWideControl( myPrivateCheck = new QCheckBox( "&Private torrent" ) );
83
hig->addSectionDivider( );
84
hig->addSectionDivider( );
85
hig->addSectionTitle( tr( "Progress" ) );
86
QProgressBar * p = myProgressBar = new QProgressBar;
87
p->setTextVisible( false );
91
hig->addWideControl( p );
92
hig->addWideControl( myProgressLabel = new QLabel( "<i>No source selected</i>" ) );
94
top->addWidget( hig, 1 );
96
//QFrame * f = new QFrame;
97
//f->setFrameShape( QFrame :: HLine );
98
//top->addWidget( f );
102
QDialogButtonBox * buttons = new QDialogButtonBox( this );
104
icon = style()->standardIcon( QStyle::SP_FileDialogNewFolder );
105
icon = QtIconLoader :: icon( "document-new", icon );
106
b = myMakeButton = new QPushButton( icon, tr( "&New Torrent" ) );
107
buttons->addButton( b, QDialogButtonBox::ActionRole );
109
icon = style()->standardIcon( QStyle::SP_DialogCancelButton );
110
icon = QtIconLoader :: icon( "process-stop", icon );
111
b = myStopButton = new QPushButton( icon, tr( "&Stop" ) );
112
buttons->addButton( b, QDialogButtonBox::RejectRole );
114
icon = style()->standardIcon( QStyle::SP_DialogCloseButton );
115
icon = QtIconLoader :: icon( "window-close", icon );
116
b = myCloseButton = new QPushButton( icon, tr( "&Close" ) );
117
buttons->addButton( b, QDialogButtonBox::AcceptRole );
119
connect( buttons, SIGNAL(clicked(QAbstractButton*)),
120
this, SLOT(onButtonBoxClicked(QAbstractButton*)) );
122
top->addWidget( buttons );
126
MakeDialog :: ~MakeDialog( )
129
tr_metaInfoBuilderFree( myBuilder );
137
MakeDialog :: getResult( ) const
47
MakeDialog :: onNewDialogDestroyed( QObject * o )
55
MakeDialog :: onNewButtonBoxClicked( QAbstractButton * button )
57
switch( myNewButtonBox->standardButton( button ) )
59
case QDialogButtonBox::Open:
60
std::cerr << "calling mySession.addTorrent( " << qPrintable(myTarget) << ", " << qPrintable(QFileInfo(myBuilder->top).dir().path()) << ')' << std::endl;
61
mySession.addTorrent( myTarget, QFileInfo(myBuilder->top).dir().path() );
63
case QDialogButtonBox::Abort:
64
myBuilder->abortFlag = true;
66
default: // QDialogButtonBox::Ok:
70
myNewDialog->deleteLater( );
74
MakeDialog :: onProgress( )
77
const tr_metainfo_builder * b = myBuilder;
78
const double denom = b->pieceCount ? b->pieceCount : 1;
79
myNewProgress->setValue( (int) ((100.0 * b->pieceIndex) / denom ) );
82
const QString base( QFileInfo(b->top).baseName() );
141
switch( myBuilder->result )
144
str = tr( "%1.torrent created!" ).arg( myBuilder->top );
147
case TR_MAKEMETA_URL:
148
str = tr( "Error: Invalid URL" );
151
case TR_MAKEMETA_CANCELLED:
152
str = tr( "Torrent creation cancelled" );
155
case TR_MAKEMETA_IO_READ:
156
str = tr( "Error: Couldn't read \"%1\": %2" )
157
.arg( myBuilder->errfile )
158
.arg( tr_strerror( myBuilder->my_errno ) );
161
case TR_MAKEMETA_IO_WRITE:
162
str = tr( "Error: Couldn't create \"%1\": %2" )
163
.arg( myBuilder->errfile )
164
.arg( tr_strerror( myBuilder->my_errno ) );
172
MakeDialog :: refresh( )
174
QString progressText;
175
bool canBuild = true;
178
progressText = tr( "Creating %1.torrent" ).arg( myBuilder->top );
180
} else if( mySourceEdit->text().trimmed().isEmpty() ) {
181
progressText = tr( "<i>No source selected<i>" );
183
} else if( myTrackerEdit->toPlainText().isEmpty() ) {
184
progressText = tr( "<i>No tracker announce URLs listed</i>" );
186
} else if( myBuilder && myBuilder->isDone ) {
187
progressText = getResult( );
191
myProgressLabel->setText( progressText );
192
myMakeButton->setEnabled( canBuild && myBuilder );
193
myCloseButton->setEnabled( !myIsBuilding );
194
myStopButton->setEnabled( myIsBuilding );
198
MakeDialog :: setIsBuilding( bool isBuilding )
200
myIsBuilding = isBuilding;
203
myBuilder->result = TR_MAKEMETA_OK;
206
myProgressBar->setValue( 0 );
209
myTimer.start( 100 );
217
MakeDialog :: onProgress( )
219
const double denom = myBuilder->pieceCount ? myBuilder->pieceCount : 1;
220
myProgressBar->setValue( (int) ((100.0 * myBuilder->pieceIndex) / denom ) );
224
if( myBuilder->isDone )
225
setIsBuilding( false );
227
//tr_metainfo_builder_err result;
85
str = tr( "Creating \"%1\"" ).arg( base );
86
else if( b->result == TR_MAKEMETA_OK )
87
str = tr( "Created \"%1\"!" ).arg( base );
88
else if( b->result == TR_MAKEMETA_URL )
89
str = tr( "Error: invalid announce URL \"%1\"" ).arg( b->errfile );
90
else if( b->result == TR_MAKEMETA_CANCELLED )
91
str = tr( "Cancelled" );
92
else if( b->result == TR_MAKEMETA_IO_READ )
93
str = tr( "Error reading \"%1\": %2" ).arg( b->errfile ).arg( strerror(b->my_errno) );
94
else if( b->result == TR_MAKEMETA_IO_WRITE )
95
str = tr( "Error writing \"%1\": %2" ).arg( b->errfile ).arg( strerror(b->my_errno) );
96
myNewLabel->setText( str );
99
(myNewButtonBox->button(QDialogButtonBox::Abort))->setEnabled( !b->isDone );
100
(myNewButtonBox->button(QDialogButtonBox::Ok))->setEnabled( b->isDone );
101
(myNewButtonBox->button(QDialogButtonBox::Open))->setEnabled( b->isDone && !b->result );
231
106
MakeDialog :: makeTorrent( )
243
119
tr_tracker_info tmp;
244
120
tmp.announce = tr_strdup( line.toUtf8().constData( ) );
246
std::cerr << "tier [" << tmp.tier << "] announce [" << tmp.announce << ']' << std::endl;
247
122
trackers.append( tmp );
127
QDialog * dialog = new QDialog( this );
128
dialog->setWindowTitle( tr( "New Torrent" ) );
129
myNewDialog = dialog;
130
QVBoxLayout * top = new QVBoxLayout( dialog );
131
top->addWidget(( myNewLabel = new QLabel));
132
top->addWidget(( myNewProgress = new QProgressBar ));
133
QDialogButtonBox * buttons = new QDialogButtonBox( QDialogButtonBox::Ok
134
| QDialogButtonBox::Open
135
| QDialogButtonBox::Abort );
136
myNewButtonBox = buttons;
137
connect( buttons, SIGNAL(clicked(QAbstractButton*)),
138
this, SLOT(onNewButtonBoxClicked(QAbstractButton*)) );
139
top->addWidget( buttons );
142
connect( dialog, SIGNAL(destroyed(QObject*)),
143
this, SLOT(onNewDialogDestroyed(QObject*)) );
144
myTimer.start( 100 );
146
// the file to create
147
myTarget = QDir( myDestination ).filePath( QFileInfo(myBuilder->top).baseName() + ".torrent" );
148
std::cerr << qPrintable(myTarget) << std::endl;
152
if( myCommentCheck->isChecked() )
153
comment = myCommentEdit->text().toUtf8().constData();
155
// start making the torrent
251
156
tr_makeMetaInfo( myBuilder,
157
myTarget.toUtf8().constData(),
158
(trackers.isEmpty() ? 0 : &trackers.front()),
255
myCommentEdit->text().toUtf8().constData(),
160
(comment.isEmpty() ? NULL : comment.toUtf8().constData()),
256
161
myPrivateCheck->isChecked() );
259
setIsBuilding( true );
169
MakeDialog :: onFileClicked( )
171
QFileDialog * d = new QFileDialog( this, tr( "Select File" ) );
172
d->setFileMode( QFileDialog::ExistingFile );
173
connect( d, SIGNAL(filesSelected(const QStringList&)),
174
this, SLOT(onFileSelected(const QStringList&)) );
178
MakeDialog :: onFileSelected( const QStringList& list )
180
if( list.size() == 1 )
182
myFile = list.first( );
183
myFileButton->setText( QFileInfo(myFile).fileName() );
189
MakeDialog :: onFolderClicked( )
191
QFileDialog * d = new QFileDialog( this, tr( "Select Folder" ) );
192
d->setFileMode( QFileDialog::Directory );
193
connect( d, SIGNAL(filesSelected(const QStringList&)),
194
this, SLOT(onFolderSelected(const QStringList&)) );
198
MakeDialog :: onFolderSelected( const QStringList& list )
200
if( list.size() == 1 )
202
myFolder = list.first();
203
myFolderButton->setText( QFileInfo(myFolder).fileName() );
209
MakeDialog :: onDestinationClicked( )
211
QFileDialog * d = new QFileDialog( this, tr( "Select Folder" ) );
212
d->setFileMode( QFileDialog::Directory );
213
connect( d, SIGNAL(filesSelected(const QStringList&)),
214
this, SLOT(onDestinationSelected(const QStringList&)) );
218
MakeDialog :: onDestinationSelected( const QStringList& list )
220
if( list.size() == 1 )
222
myDestination = list.first( );
223
myDestinationButton->setText( QFileInfo(myDestination).fileName() );
228
MakeDialog :: enableBuddyWhenChecked( QRadioButton * box, QWidget * buddy )
230
connect( box, SIGNAL(toggled(bool)), buddy, SLOT(setEnabled(bool)) );
231
buddy->setEnabled( box->isChecked( ) );
234
MakeDialog :: enableBuddyWhenChecked( QCheckBox * box, QWidget * buddy )
236
connect( box, SIGNAL(toggled(bool)), buddy, SLOT(setEnabled(bool)) );
237
buddy->setEnabled( box->isChecked( ) );
241
MakeDialog :: getSource( ) const
243
return myFileRadio->isChecked( ) ? myFile : myFolder;
263
247
MakeDialog :: onButtonBoxClicked( QAbstractButton * button )
265
if( button == myMakeButton )
268
if( button == myStopButton )
269
myBuilder->abortFlag = true;
271
if( button == myCloseButton )
249
switch( myButtonBox->standardButton( button ) )
251
case QDialogButtonBox::Ok:
255
default: // QDialogButtonBox::Close:
301
288
.arg( Utils::sizeToString( myBuilder->pieceSize ) );
303
291
mySourceLabel->setText( text );
309
MakeDialog :: onFileSelectedInDialog( const QString& path )
295
// bah, there doesn't seem to be any cleaner way to override
296
// QPlainTextEdit's default desire to be 12 lines tall
297
class ShortPlainTextEdit: public QPlainTextEdit {
299
virtual ~ShortPlainTextEdit( ) { }
300
ShortPlainTextEdit( QWidget * parent = 0 ): QPlainTextEdit(parent) { }
301
virtual QSize sizeHint ( ) const { return QSize( 256, 50 ); }
304
MakeDialog :: MakeDialog( Session & session, QWidget * parent ):
305
QDialog( parent, Qt::Dialog ),
306
mySession( session ),
311
mySourceEdit->setText( path );
309
connect( &myTimer, SIGNAL(timeout()), this, SLOT(onProgress()) );
311
setWindowTitle( tr( "New Torrent" ) );
312
QVBoxLayout * top = new QVBoxLayout( this );
313
top->setSpacing( HIG :: PAD );
316
hig->setContentsMargins( 0, 0, 0, 0 );
317
hig->addSectionTitle( tr( "Files" ) );
319
QFileIconProvider iconProvider;
320
const int iconSize( style()->pixelMetric( QStyle::PM_SmallIconSize ) );
321
const QIcon folderIcon = iconProvider.icon( QFileIconProvider::Folder );
322
const QPixmap folderPixmap = folderIcon.pixmap( iconSize );
323
QPushButton * b = new QPushButton;
324
b->setIcon( folderPixmap );
325
b->setStyleSheet( "text-align: left; padding-left: 5; padding-right: 5" );
326
myDestination = QDir::homePath();
327
b->setText( myDestination );
328
connect( b, SIGNAL(clicked(bool)),
329
this, SLOT(onDestinationClicked(void)) );
330
myDestinationButton = b;
331
hig->addRow( tr( "Sa&ve to:" ), b );
333
myFolderRadio = new QRadioButton( tr( "Source F&older:" ) );
334
connect( myFolderRadio, SIGNAL(toggled(bool)),
335
this, SLOT(onSourceChanged()) );
336
myFolderButton = new QPushButton;
337
myFolderButton->setIcon( folderPixmap );
338
myFolderButton->setText( tr( "(None)" ) );
339
myFolderButton->setStyleSheet( "text-align: left; padding-left: 5; padding-right: 5" );
340
connect( myFolderButton, SIGNAL(clicked(bool)),
341
this, SLOT(onFolderClicked(void)) );
342
hig->addRow( myFolderRadio, myFolderButton );
343
enableBuddyWhenChecked( myFolderRadio, myFolderButton );
345
const QIcon fileIcon = iconProvider.icon( QFileIconProvider::File );
346
const QPixmap filePixmap = fileIcon.pixmap( iconSize );
347
myFileRadio = new QRadioButton( tr( "Source &File:" ) );
348
myFileRadio->setChecked( true );
349
connect( myFileRadio, SIGNAL(toggled(bool)),
350
this, SLOT(onSourceChanged()) );
351
myFileButton = new QPushButton;
352
myFileButton->setText( tr( "(None)" ) );
353
myFileButton->setIcon( filePixmap );
354
myFileButton->setStyleSheet( "text-align: left; padding-left: 5; padding-right: 5" );
355
connect( myFileButton, SIGNAL(clicked(bool)),
356
this, SLOT(onFileClicked(void)) );
357
hig->addRow( myFileRadio, myFileButton );
358
enableBuddyWhenChecked( myFileRadio, myFileButton );
360
mySourceLabel = new QLabel( this );
361
hig->addRow( tr( "" ), mySourceLabel );
363
hig->addSectionDivider( );
364
hig->addSectionTitle( tr( "Properties" ) );
366
hig->addWideControl( myTrackerEdit = new ShortPlainTextEdit );
367
const int height = fontMetrics().size( 0, "\n\n\n\n" ).height( );
368
myTrackerEdit->setMinimumHeight( height );
369
hig->addTallRow( tr( "&Trackers:" ), myTrackerEdit );
370
QLabel * l = new QLabel( tr( "To add a backup URL, add it on the line after the primary URL.\nTo add another primary URL, add it after a blank line." ) );
371
l->setAlignment( Qt::AlignLeft );
372
hig->addRow( tr( "" ), l );
373
myTrackerEdit->resize( 500, height );
375
myCommentCheck = new QCheckBox( tr( "Co&mment" ) );
376
myCommentEdit = new QLineEdit( );
377
hig->addRow( myCommentCheck, myCommentEdit );
378
enableBuddyWhenChecked( myCommentCheck, myCommentEdit );
380
myPrivateCheck = hig->addWideCheckBox( tr( "&Private torrent" ), false );
383
top->addWidget( hig, 1 );
385
myButtonBox = new QDialogButtonBox( QDialogButtonBox::Ok
386
| QDialogButtonBox::Close );
387
connect( myButtonBox, SIGNAL(clicked(QAbstractButton*)),
388
this, SLOT(onButtonBoxClicked(QAbstractButton*)) );
390
top->addWidget( myButtonBox );
312
391
onSourceChanged( );
316
MakeDialog :: onFolderButtonPressed( )
318
QFileDialog * f = new QFileDialog( this );
319
f->setFileMode( QFileDialog :: Directory );
320
connect( f, SIGNAL(fileSelected(const QString&)), this, SLOT(onFileSelectedInDialog(const QString&)));
325
MakeDialog :: onFileButtonPressed( )
327
QFileDialog * f = new QFileDialog( this );
328
f->setFileMode( QFileDialog :: ExistingFile );
329
connect( f, SIGNAL(fileSelected(const QString&)), this, SLOT(onFileSelectedInDialog(const QString&)));
394
MakeDialog :: ~MakeDialog( )
397
tr_metaInfoBuilderFree( myBuilder );