@ -1,6 +1,7 @@
@@ -1,6 +1,7 @@
/*
* Bittorrent Client using Qt4 and libtorrent .
* Copyright ( C ) 2010 Christophe Dumez
* Bittorrent Client using Qt and libtorrent .
* Copyright ( C ) 2017 Mike Tzou ( Chocobo1 )
* Copyright ( C ) 2010 Christophe Dumez < chris @ qbittorrent . org >
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
@ -24,258 +25,233 @@
@@ -24,258 +25,233 @@
* modify file ( s ) , you may extend this exception to your version of the file ( s ) ,
* but you are not obligated to do so . If you do not wish to do so , delete this
* exception statement from your version .
*
* Contact : chris @ qbittorrent . org
*/
# include "torrentcreatordlg.h"
# include <QCloseEvent>
# include <QDebug>
# include <QFileDialog>
# include <QMessageBox>
# include <QMimeData>
# include <QUrl>
# include "torrentcreatordlg.h"
# include "base/utils/fs.h"
# include "base/utils/misc.h"
# include "base/preferences.h"
# include "guiiconprovider.h"
# include "base/bittorrent/session.h"
# include "base/bittorrent/torrentinfo.h"
# include "base/bittorrent/torrentcreatorthread.h"
# include "base/bittorrent/torrentinfo.h"
# include "base/global.h"
# include "base/utils/fs.h"
# include "ui_torrentcreatordlg.h"
const uint NB_PIECES_MIN = 1200 ;
const uint NB_PIECES_MAX = 2200 ;
# define SETTINGS_KEY(name) "TorrentCreator / " name
TorrentCreatorDlg : : TorrentCreatorDlg ( QWidget * parent )
TorrentCreatorDlg : : TorrentCreatorDlg ( QWidget * parent , const QString & defaultPath )
: QDialog ( parent )
, m_creatorThread ( 0 )
, m_ui ( new Ui : : TorrentCreatorDlg )
, m_creatorThread ( new BitTorrent : : TorrentCreatorThread ( this ) )
, m_storeDialogSize ( SETTINGS_KEY ( " Dimension " ) )
, m_storePieceSize ( SETTINGS_KEY ( " PieceSize " ) )
, m_storePrivateTorrent ( SETTINGS_KEY ( " PrivateTorrent " ) )
, m_storeStartSeeding ( SETTINGS_KEY ( " StartSeeding " ) )
, m_storeIgnoreRatio ( SETTINGS_KEY ( " IgnoreRatio " ) )
, m_storeLastAddPath ( SETTINGS_KEY ( " LastAddPath " ) , QDir : : homePath ( ) )
, m_storeTrackerList ( SETTINGS_KEY ( " TrackerList " ) )
, m_storeWebSeedList ( SETTINGS_KEY ( " WebSeedList " ) )
, m_storeComments ( SETTINGS_KEY ( " Comments " ) )
, m_storeLastSavePath ( SETTINGS_KEY ( " LastSavePath " ) , QDir : : homePath ( ) )
{
setupUi ( this ) ;
// Icons
addFile_button - > setIcon ( GuiIconProvider : : instance ( ) - > getIcon ( " document-new " ) ) ;
addFolder_button - > setIcon ( GuiIconProvider : : instance ( ) - > getIcon ( " folder-new " ) ) ;
createButton - > setIcon ( GuiIconProvider : : instance ( ) - > getIcon ( " document-save " ) ) ;
cancelButton - > setIcon ( GuiIconProvider : : instance ( ) - > getIcon ( " dialog-cancel " ) ) ;
m_ui - > setupUi ( this ) ;
setAttribute ( Qt : : WA_DeleteOnClose ) ;
setModal ( true ) ;
showProgressBar ( false ) ;
loadTrackerList ( ) ;
// Piece sizes
m_pieceSizes < < 16 < < 32 < < 64 < < 128 < < 256 < < 512 < < 1024 < < 2048 < < 4096 < < 8192 < < 16384 ;
setModal ( false ) ;
m_ui - > buttonBox - > button ( QDialogButtonBox : : Ok ) - > setText ( tr ( " Create Torrent " ) ) ;
connect ( m_ui - > addFileButton , SIGNAL ( clicked ( bool ) ) , SLOT ( onAddFileButtonClicked ( ) ) ) ;
connect ( m_ui - > addFolderButton , SIGNAL ( clicked ( bool ) ) , SLOT ( onAddFolderButtonClicked ( ) ) ) ;
connect ( m_ui - > buttonBox , SIGNAL ( accepted ( ) ) , SLOT ( onCreateButtonClicked ( ) ) ) ;
connect ( m_creatorThread , SIGNAL ( creationSuccess ( QString , QString ) ) , this , SLOT ( handleCreationSuccess ( QString , QString ) ) ) ;
connect ( m_creatorThread , SIGNAL ( creationFailure ( QString ) ) , this , SLOT ( handleCreationFailure ( QString ) ) ) ;
connect ( m_creatorThread , SIGNAL ( updateProgress ( int ) ) , this , SLOT ( updateProgressBar ( int ) ) ) ;
loadSettings ( ) ;
updateInputPath ( defaultPath ) ;
show ( ) ;
}
TorrentCreatorDlg : : ~ TorrentCreatorDlg ( )
{
saveSettings ( ) ;
if ( m_creatorThread )
delete m_creatorThread ;
delete m_ui ;
}
void TorrentCreatorDlg : : on_addFolder_button_clicked ( )
void TorrentCreatorDlg : : updateInputPath ( const QString & path )
{
Preferences * const pref = Preferences : : instance ( ) ;
QString lastPath = pref - > getCreateTorLastAddPath ( ) ;
QString dir = QFileDialog : : getExistingDirectory ( this , tr ( " Select a folder to add to the torrent " ) , lastPath , QFileDialog : : ShowDirsOnly ) ;
if ( ! dir . isEmpty ( ) ) {
pref - > setCreateTorLastAddPath ( dir ) ;
textInputPath - > setText ( Utils : : Fs : : toNativePath ( dir ) ) ;
// Update piece size
if ( checkAutoPieceSize - > isChecked ( ) )
updateOptimalPieceSize ( ) ;
}
if ( path . isEmpty ( ) ) return ;
m_ui - > textInputPath - > setText ( Utils : : Fs : : toNativePath ( path ) ) ;
updateProgressBar ( 0 ) ;
}
void TorrentCreatorDlg : : on_addFile_button_c licked ( )
void TorrentCreatorDlg : : onAddFolderButtonClicked ( )
{
Preferences * const pref = Preferences : : instance ( ) ;
QString lastPath = pref - > getCreateTorLastAddPath ( ) ;
QString file = QFileDialog : : getOpenFileName ( this , tr ( " Select a file to add to the torrent " ) , lastP ath) ;
if ( ! file . isEmpty ( ) ) {
pref - > setCreateTorLastAddPath ( Utils : : Fs : : branchPath ( file ) ) ;
textInputPath - > setText ( Utils : : Fs : : toNativePath ( file ) ) ;
// Update piece size
if ( checkAutoPieceSize - > isChecked ( ) )
updateOptimalPieceSize ( ) ;
}
QString oldPath = m_ui - > textInputPath - > text ( ) ;
QString path = QFileDialog : : getExistingDirectory ( this , tr ( " Select folder " ) , oldPath ) ;
updateInputPath ( path ) ;
}
void TorrentCreatorDlg : : onAddFileButtonClicked ( )
{
QString oldPath = m_ui - > textInputPath - > text ( ) ;
QString path = QFileDialog : : getOpenFileName ( this , tr ( " Select file " ) , oldPath ) ;
updateInputPath ( path ) ;
}
int TorrentCreatorDlg : : getPieceSize ( ) const
{
return m_pieceSizes . at ( comboPieceSize - > currentIndex ( ) ) * 1024 ;
const int pieceSizes [ ] = { 0 , 16 , 32 , 64 , 128 , 256 , 512 , 1024 , 2048 , 4096 , 8192 , 16384 } ; // base unit in KiB
return pieceSizes [ m_ui - > comboPieceSize - > currentIndex ( ) ] * 1024 ;
}
void TorrentCreatorDlg : : dropEvent ( QDropEvent * event )
{
event - > acceptProposedAction ( ) ;
if ( event - > mimeData ( ) - > hasUrls ( ) ) {
// only take the first one
QUrl firstItem = event - > mimeData ( ) - > urls ( ) . first ( ) ;
QString path = ( firstItem . scheme ( ) . compare ( " file " , Qt : : CaseInsensitive ) = = 0 )
? firstItem . toLocalFile ( ) : firstItem . toString ( ) ;
updateInputPath ( path ) ;
}
}
void TorrentCreatorDlg : : dragEnterEvent ( QDragEnterEvent * event )
{
if ( event - > mimeData ( ) - > hasFormat ( " text/plain " ) | | event - > mimeData ( ) - > hasFormat ( " text/uri-list " ) )
event - > acceptProposedAction ( ) ;
}
// Main function that create a .torrent file
void TorrentCreatorDlg : : on_createButton_clicked ( )
void TorrentCreatorDlg : : onCreateButtonC licked ( )
{
QString input = Utils : : Fs : : fromNativePath ( textInputPath - > text ( ) ) . trimmed ( ) ;
if ( input . endsWith ( " / " ) )
input . chop ( 1 ) ;
if ( input . isEmpty ( ) ) {
QMessageBox : : critical ( 0 , tr ( " No input path set " ) , tr ( " Please type an input path first " ) ) ;
QString input = Utils : : Fs : : fromNativePath ( m_ui - > textInputPath - > text ( ) ) . trimmed ( ) ;
// test if readable
QFileInfo fi ( input ) ;
if ( ! fi . isReadable ( ) ) {
QMessageBox : : critical ( this , tr ( " Torrent creator failed " ) , tr ( " Reason: Path to file/folder is not readable. " ) ) ;
return ;
}
QStringList trackers = trackers_list - > toPlainText ( ) . split ( " \n " ) ;
if ( ! trackers_list - > toPlainText ( ) . trimmed ( ) . isEmpty ( ) )
saveTrackerList ( ) ;
Preferences * const pref = Preferences : : instance ( ) ;
QString lastPath = pref - > getCreateTorLastSavePath ( ) ;
input = fi . canonicalFilePath ( ) ;
QString destination = QFileDialog : : getSaveFileName ( this , tr ( " Select destination torrent file " ) , lastPath , tr ( " Torrent Files (*.torrent) " ) ) ;
// get save path
QString lastPath = m_storeLastSavePath ;
QString destination = QFileDialog : : getSaveFileName ( this , tr ( " Select where to save the new torrent " ) , lastPath , tr ( " Torrent Files (*.torrent) " ) ) ;
if ( destination . isEmpty ( ) )
return ;
if ( ! destination . endsWith ( C_TORRENT_FILE_EXTENSION , Qt : : CaseInsensitive ) )
destination + = C_TORRENT_FILE_EXTENSION ;
m_storeLastSavePath = Utils : : Fs : : branchPath ( destination ) ;
pref - > setCreateTorLastSavePath ( Utils : : Fs : : branchPath ( destination ) ) ;
if ( ! destination . toUpper ( ) . endsWith ( " .TORRENT " ) )
destination + = QString : : fromUtf8 ( " .torrent " ) ;
// Disable dialog
// Disable dialog & set busy cursor
setInteractionEnabled ( false ) ;
showProgressBar ( true ) ;
// Set busy cursor
setCursor ( QCursor ( Qt : : WaitCursor ) ) ;
// Actually create the torrent
QStringList urlSeeds = URLSeeds_list - > toPlainText ( ) . split ( " \n " ) ;
QString comment = txt_comment - > toPlainText ( ) ;
// Create the creator thread
m_creatorThread = new BitTorrent : : TorrentCreatorThread ( this ) ;
connect ( m_creatorThread , SIGNAL ( creationSuccess ( QString , QString ) ) , this , SLOT ( handleCreationSuccess ( QString , QString ) ) ) ;
connect ( m_creatorThread , SIGNAL ( creationFailure ( QString ) ) , this , SLOT ( handleCreationFailure ( QString ) ) ) ;
connect ( m_creatorThread , SIGNAL ( updateProgress ( int ) ) , this , SLOT ( updateProgressBar ( int ) ) ) ;
m_creatorThread - > create ( input , destination , trackers , urlSeeds , comment , check_private - > isChecked ( ) , getPieceSize ( ) ) ;
QStringList trackers = m_ui - > trackersList - > toPlainText ( ) . split ( " \n " ) ;
QStringList urlSeeds = m_ui - > URLSeedsList - > toPlainText ( ) . split ( " \n " ) ;
QString comment = m_ui - > txtComment - > toPlainText ( ) ;
// run the creator thread
m_creatorThread - > create ( input , destination , trackers , urlSeeds , comment , m_ui - > checkPrivate - > isChecked ( ) , getPieceSize ( ) ) ;
}
void TorrentCreatorDlg : : handleCreationFailure ( QString msg )
void TorrentCreatorDlg : : handleCreationFailure ( const QString & msg )
{
// Remove busy cursor
setCursor ( QCursor ( Qt : : ArrowCursor ) ) ;
QMessageBox : : information ( 0 , tr ( " Torrent creation " ) , tr ( " Torrent creation was unsuccessful, r eason: %1" ) . arg ( msg ) ) ;
QMessageBox : : information ( this , tr ( " Torrent creator failed " ) , tr ( " R eason: %1" ) . arg ( msg ) ) ;
setInteractionEnabled ( true ) ;
showProgressBar ( false ) ;
}
void TorrentCreatorDlg : : handleCreationSuccess ( QString path , QString branch_p ath)
void TorrentCreatorDlg : : handleCreationSuccess ( const QString & path , const QString & branchP ath)
{
// Remove busy cursor
setCursor ( QCursor ( Qt : : ArrowCursor ) ) ;
if ( checkStartSeeding - > isChecked ( ) ) {
if ( m_ui - > checkStartSeeding - > isChecked ( ) ) {
// Create save path temp data
BitTorrent : : TorrentInfo t = BitTorrent : : TorrentInfo : : loadFromFile ( Utils : : Fs : : toNativePath ( path ) ) ;
if ( ! t . isValid ( ) ) {
QMessageBox : : critical ( 0 , tr ( " Torrent creation " ) , tr ( " Created torrent file is invalid. It won't be added to download list. " ) ) ;
QMessageBox : : critical ( this , tr ( " Torrent creator failed " ) , tr ( " Reason: Created torrent is invalid. It won't be added to download list." ) ) ;
return ;
}
BitTorrent : : AddTorrentParams params ;
params . savePath = branch_p ath ;
params . savePath = branchP ath ;
params . skipChecking = true ;
params . ignoreShareLimits = checkIgnoreShareLimits - > isChecked ( ) ;
params . ignoreShareLimits = m_ui - > checkIgnoreShareLimits - > isChecked ( ) ;
BitTorrent : : Session : : instance ( ) - > addTorrent ( t , params ) ;
}
QMessageBox : : information ( 0 , tr ( " Torrent creation " ) , tr ( " Torrent was created successfully: %1 " , " %1 is the path of the torrent " ) . arg ( Utils : : Fs : : toNativePath ( path ) ) ) ;
close ( ) ;
}
void TorrentCreatorDlg : : on_cancelButton_clicked ( )
{
// End torrent creation thread
if ( m_creatorThread & & m_creatorThread - > isRunning ( ) ) {
m_creatorThread - > abortCreation ( ) ;
m_creatorThread - > terminate ( ) ;
// Wait for termination
m_creatorThread - > wait ( ) ;
}
// Close the dialog
close ( ) ;
QMessageBox : : information ( this , tr ( " Torrent creator " ) , QString ( " %1 \n %2 " ) . arg ( tr ( " Create torrent success: " ) ) . arg ( Utils : : Fs : : toNativePath ( path ) ) ) ;
setInteractionEnabled ( true ) ;
}
void TorrentCreatorDlg : : updateProgressBar ( int progress )
{
progressBar - > setValue ( progress ) ;
m_ui - > progressBar - > setValue ( progress ) ;
}
void TorrentCreatorDlg : : setInteractionEnabled ( bool enabled )
{
textInputPath - > setEnabled ( enabled ) ;
addFile_button - > setEnabled ( enabled ) ;
addFolder_button - > setEnabled ( enabled ) ;
trackers_list - > setEnabled ( enabled ) ;
URLSeeds_list - > setEnabled ( enabled ) ;
txt_comment - > setEnabled ( enabled ) ;
comboPieceSize - > setEnabled ( enabled ) ;
checkAutoPieceSize - > setEnabled ( enabled ) ;
check_private - > setEnabled ( enabled ) ;
checkStartSeeding - > setEnabled ( enabled ) ;
createButton - > setEnabled ( enabled ) ;
checkIgnoreShareLimits - > setEnabled ( enabled & & checkStartSeeding - > isChecked ( ) ) ;
m_ui - > textInputPath - > setEnabled ( enabled ) ;
m_ui - > addFileButton - > setEnabled ( enabled ) ;
m_ui - > addFolderButton - > setEnabled ( enabled ) ;
m_ui - > trackersList - > setEnabled ( enabled ) ;
m_ui - > URLSeedsList - > setEnabled ( enabled ) ;
m_ui - > txtComment - > setEnabled ( enabled ) ;
m_ui - > comboPieceSize - > setEnabled ( enabled ) ;
m_ui - > checkPrivate - > setEnabled ( enabled ) ;
m_ui - > checkStartSeeding - > setEnabled ( enabled ) ;
m_ui - > buttonBox - > button ( QDialogButtonBox : : Ok ) - > setEnabled ( enabled ) ;
m_ui - > checkIgnoreShareLimits - > setEnabled ( enabled & & m_ui - > checkStartSeeding - > isChecked ( ) ) ;
}
void TorrentCreatorDlg : : showProgressBar ( bool show )
void TorrentCreatorDlg : : saveSettings ( )
{
progressLbl - > setVisible ( show ) ;
progressBar - > setVisible ( show ) ;
}
m_storeLastAddPath = m_ui - > textInputPath - > text ( ) . trimmed ( ) ;
void TorrentCreatorDlg : : on_checkAutoPieceSize_clicked ( bool checked )
{
comboPieceSize - > setEnabled ( ! checked ) ;
if ( checked )
updateOptimalPieceSize ( ) ;
}
m_storePieceSize = m_ui - > comboPieceSize - > currentIndex ( ) ;
m_storePrivateTorrent = m_ui - > checkPrivate - > isChecked ( ) ;
m_storeStartSeeding = m_ui - > checkStartSeeding - > isChecked ( ) ;
m_storeIgnoreRatio = m_ui - > checkIgnoreShareLimits - > isChecked ( ) ;
void TorrentCreatorDlg : : updateOptimalPieceSize ( )
{
qint64 torrentSize = Utils : : Fs : : computePathSize ( textInputPath - > text ( ) ) ;
qDebug ( " Torrent size is %lld " , torrentSize ) ;
if ( torrentSize < 0 )
return ;
int i = 0 ;
qulonglong nb_pieces = 0 ;
do {
nb_pieces = ( double ) torrentSize / ( m_pieceSizes . at ( i ) * 1024. ) ;
qDebug ( " nb_pieces=%lld with piece_size=%s " , nb_pieces , qPrintable ( comboPieceSize - > itemText ( i ) ) ) ;
if ( nb_pieces < = NB_PIECES_MIN ) {
if ( i > 1 )
- - i ;
break ;
}
else if ( nb_pieces < NB_PIECES_MAX ) {
qDebug ( " Good, nb_pieces=%lld < %d " , nb_pieces + 1 , NB_PIECES_MAX ) ;
break ;
}
+ + i ;
} while ( i < ( m_pieceSizes . size ( ) - 1 ) ) ;
comboPieceSize - > setCurrentIndex ( i ) ;
}
m_storeTrackerList = m_ui - > trackersList - > toPlainText ( ) ;
m_storeWebSeedList = m_ui - > URLSeedsList - > toPlainText ( ) ;
m_storeComments = m_ui - > txtComment - > toPlainText ( ) ;
void TorrentCreatorDlg : : saveTrackerList ( )
{
Preferences : : instance ( ) - > setCreateTorTrackers ( trackers_list - > toPlainText ( ) ) ;
m_storeDialogSize = size ( ) ;
}
void TorrentCreatorDlg : : loadTrackerList ( )
void TorrentCreatorDlg : : loadSettings ( )
{
trackers_list - > setPlainText ( Preferences : : instance ( ) - > getCreateTorTrackers ( ) ) ;
}
m_ui - > textInputPath - > setText ( m_storeLastAddPath ) ;
void TorrentCreatorDlg : : saveSettings ( )
{
Preferences * const pref = Preferences : : instance ( ) ;
pref - > setCreateTorGeometry ( saveGeometry ( ) ) ;
pref - > setCreateTorIgnoreRatio ( checkIgnoreShareLimits - > isChecked ( ) ) ;
}
m_ui - > comboPieceSize - > setCurrentIndex ( m_storePieceSize ) ;
m_ui - > checkPrivate - > setChecked ( m_storePrivateTorrent ) ;
m_ui - > checkStartSeeding - > setChecked ( m_storeStartSeeding ) ;
m_ui - > checkIgnoreShareLimits - > setChecked ( m_storeIgnoreRatio ) ;
m_ui - > checkIgnoreShareLimits - > setEnabled ( m_ui - > checkStartSeeding - > isChecked ( ) ) ;
void TorrentCreatorDlg : : loadSettings ( )
{
const Preferences * const pref = Preferences : : instance ( ) ;
restoreGeometry ( pref - > getCreateTorGeometry ( ) ) ;
checkIgnoreShareLimits - > setChecked ( pref - > getCreateTorIgnoreRatio ( ) ) ;
}
m_ui - > trackersList - > setPlainText ( m_storeTrackerList ) ;
m_ui - > URLSeedsList - > setPlainText ( m_storeWebSeedList ) ;
m_ui - > txtComment - > setPlainText ( m_storeComments ) ;
void TorrentCreatorDlg : : closeEvent ( QCloseEvent * event )
{
qDebug ( ) < < Q_FUNC_INFO ;
saveSettings ( ) ;
QDialog : : closeEvent ( event ) ;
if ( m_storeDialogSize . value ( ) . isValid ( ) )
resize ( m_storeDialogSize ) ;
}