@ -41,6 +41,7 @@
@@ -41,6 +41,7 @@
# include <QHeaderView>
# include <QApplication>
# include <QDesktopWidget>
# include <QInputDialog>
# include <libtorrent/session.hpp>
# include <libtorrent/bencode.hpp>
@ -67,6 +68,7 @@ private:
@@ -67,6 +68,7 @@ private:
PropListDelegate * PropDelegate ;
unsigned int nbFiles ;
boost : : intrusive_ptr < torrent_info > t ;
QStringList files_path ;
public :
torrentAdditionDialog ( QWidget * parent , Bittorrent * _BTSession ) : QDialog ( parent ) {
@ -80,6 +82,7 @@ public:
@@ -80,6 +82,7 @@ public:
PropDelegate = new PropListDelegate ( ) ;
torrentContentList - > setItemDelegate ( PropDelegate ) ;
connect ( torrentContentList , SIGNAL ( clicked ( const QModelIndex & ) ) , torrentContentList , SLOT ( edit ( const QModelIndex & ) ) ) ;
connect ( torrentContentList , SIGNAL ( customContextMenuRequested ( const QPoint & ) ) , this , SLOT ( displayContentListMenu ( const QPoint & ) ) ) ;
connect ( collapseAllButton , SIGNAL ( clicked ( ) ) , torrentContentList , SLOT ( collapseAll ( ) ) ) ;
connect ( expandAllButton , SIGNAL ( clicked ( ) ) , torrentContentList , SLOT ( expandAll ( ) ) ) ;
// Remember columns width
@ -194,113 +197,235 @@ public:
@@ -194,113 +197,235 @@ public:
foreach ( const QString & label , customLabels ) {
comboLabel - > addItem ( label ) ;
}
// Loads files path in the torrent
for ( uint i = 0 ; i < nbFiles ; + + i ) {
files_path < < misc : : toQString ( t - > file_at ( i ) . path . string ( ) ) ;
}
// Show the dialog
show ( ) ;
}
public slots :
void updateDiskSpaceLabels ( ) {
long long available = misc : : freeDiskSpaceOnPath ( misc : : expandPath ( savePathTxt - > text ( ) ) ) ;
lbl_disk_space - > setText ( misc : : friendlyUnit ( available ) ) ;
// Determine torrent size
qulonglong torrent_size = 0 ;
unsigned int nbFiles = t - > num_files ( ) ;
std : : vector < int > priorities = PropListModel - > getFilesPriorities ( nbFiles ) ;
for ( unsigned int i = 0 ; i < nbFiles ; + + i ) {
if ( priorities [ i ] > 0 )
torrent_size + = t - > file_at ( i ) . size ;
void displayContentListMenu ( const QPoint & ) {
QMenu myFilesLlistMenu ;
QModelIndexList selectedRows = torrentContentList - > selectionModel ( ) - > selectedRows ( 0 ) ;
QAction * actRename = 0 ;
if ( selectedRows . size ( ) = = 1 ) {
actRename = myFilesLlistMenu . addAction ( QIcon ( QString : : fromUtf8 ( " :/Icons/oxygen/edit_clear.png " ) ) , tr ( " Rename... " ) ) ;
//myFilesLlistMenu.addSeparator();
} else {
return ;
}
lbl_torrent_size - > setText ( misc : : friendlyUnit ( torrent_size ) ) ;
// Check if free space is sufficient
if ( available > 0 ) {
if ( ( unsigned long long ) available > torrent_size ) {
// Space is sufficient
label_space_msg - > setText ( tr ( " (%1 left after torrent download) " , " e.g. (100MiB left after torrent download) " ) . arg ( misc : : friendlyUnit ( available - torrent_size ) ) ) ;
} else {
// Space is unsufficient
label_space_msg - > setText ( " <font color= \" red \" > " + tr ( " (%1 more are required to download) " , " e.g. (100MiB more are required to download) " ) . arg ( misc : : friendlyUnit ( torrent_size - available ) ) + " </font> " ) ;
// Call menu
QAction * act = myFilesLlistMenu . exec ( QCursor : : pos ( ) ) ;
if ( act ) {
if ( act = = actRename ) {
renameSelectedFile ( ) ;
}
} else {
// Available disk space is unknown
label_space_msg - > setText ( " " ) ;
}
}
void on_browseButton_clicked ( ) {
QString dir ;
QString save_path = misc : : expandPath ( savePathTxt - > text ( ) ) ;
QDir saveDir ( save_path ) ;
if ( ! save_path . isEmpty ( ) & & saveDir . exists ( ) ) {
dir = QFileDialog : : getExistingDirectory ( this , tr ( " Choose save path " ) , saveDir . absolutePath ( ) ) ;
} else {
dir = QFileDialog : : getExistingDirectory ( this , tr ( " Choose save path " ) , QDir : : homePath ( ) ) ;
}
if ( ! dir . isNull ( ) ) {
savePathTxt - > setText ( dir ) ;
}
}
void renameSelectedFile ( ) {
QModelIndexList selectedIndexes = torrentContentList - > selectionModel ( ) - > selectedRows ( 0 ) ;
Q_ASSERT ( selectedIndexes . size ( ) = = 1 ) ;
QModelIndex index = selectedIndexes . first ( ) ;
// Ask for new name
bool ok ;
QString new_name_last = QInputDialog : : getText ( this , tr ( " Rename torrent file " ) ,
tr ( " New name: " ) , QLineEdit : : Normal ,
index . data ( ) . toString ( ) , & ok ) ;
if ( ok & & ! new_name_last . isEmpty ( ) ) {
if ( PropListModel - > getType ( index ) = = TFILE ) {
// File renaming
uint file_index = PropListModel - > getFileIndex ( index ) ;
QString old_name = files_path . at ( file_index ) ;
QStringList path_items = old_name . split ( QDir : : separator ( ) ) ;
path_items . removeLast ( ) ;
path_items < < new_name_last ;
QString new_name = path_items . join ( QDir : : separator ( ) ) ;
if ( old_name = = new_name ) {
qDebug ( " Name did not change " ) ;
return ;
}
// Check if that name is already used
for ( uint i = 0 ; i < nbFiles ; + + i ) {
if ( i = = file_index ) continue ;
# ifdef Q_WS_WIN
if ( files_path . at ( i ) . compare ( new_name , Qt : : CaseInsensitive ) = = 0 ) {
# else
if ( files_path . at ( i ) . compare ( new_name , Qt : : CaseSensitive ) = = 0 ) {
# endif
// Display error message
QMessageBox : : warning ( this , tr ( " The file could not be renamed " ) ,
tr ( " This name is already in use in this folder. Please use a different name. " ) ,
QMessageBox : : Ok ) ;
return ;
}
}
qDebug ( " Renaming %s to %s " , old_name . toLocal8Bit ( ) . data ( ) , new_name . toLocal8Bit ( ) . data ( ) ) ;
// Rename file in files_path
files_path . replace ( file_index , new_name ) ;
// Rename in torrent files model too
PropListModel - > setData ( index , new_name_last ) ;
} else {
// Folder renaming
QStringList path_items ;
path_items < < index . data ( ) . toString ( ) ;
QModelIndex parent = PropListModel - > parent ( index ) ;
while ( parent . isValid ( ) ) {
path_items . prepend ( parent . data ( ) . toString ( ) ) ;
parent = PropListModel - > parent ( parent ) ;
}
QString old_path = path_items . join ( QDir : : separator ( ) ) ;
path_items . removeLast ( ) ;
path_items < < new_name_last ;
QString new_path = path_items . join ( QDir : : separator ( ) ) ;
// Check for overwriting
for ( uint i = 0 ; i < nbFiles ; + + i ) {
QString current_name = files_path . at ( i ) ;
# ifdef Q_WS_WIN
if ( current_name . contains ( new_path , Qt : : CaseInsensitive ) ) {
# else
if ( current_name . contains ( new_path , Qt : : CaseSensitive ) ) {
# endif
QMessageBox : : warning ( this , tr ( " The folder could not be renamed " ) ,
tr ( " This name is already in use in this folder. Please use a different name. " ) ,
QMessageBox : : Ok ) ;
return ;
}
}
// Replace path in all files
for ( uint i = 0 ; i < nbFiles ; + + i ) {
QString current_name = files_path . at ( i ) ;
QString new_name = current_name . replace ( old_path , new_path ) ;
qDebug ( " Rename %s to %s " , current_name . toLocal8Bit ( ) . data ( ) , new_name . toLocal8Bit ( ) . data ( ) ) ;
// Rename in files_path
files_path . replace ( i , new_name ) ;
}
// Rename folder in torrent files model too
PropListModel - > setData ( index , new_name_last ) ;
}
}
}
void on_CancelButton_clicked ( ) {
close ( ) ;
}
void updateDiskSpaceLabels ( ) {
long long available = misc : : fr eeDiskSpaceOnPath ( misc : : expandPath ( savePathTxt - > text ( ) ) ) ;
lbl_disk_space - > setText ( misc : : friendlyUnit ( available ) ) ;
bool allFiltered ( ) const {
return PropListModel - > allFiltered ( ) ;
}
// Determine torrent size
qulonglong torrent_size = 0 ;
unsigned int nbFiles = t - > num_files ( ) ;
std : : vector < int > priorities = PropListModel - > getFilesPriorities ( nbFiles ) ;
void savePiecesPriorities ( ) {
qDebug ( " Saving pieces priorities " ) ;
std : : vector < int > priorities = PropListModel - > getFilesPriorities ( t - > num_files ( ) ) ;
TorrentTempData : : setFilesPriority ( hash , priorities ) ;
}
for ( unsigned int i = 0 ; i < nbFiles ; + + i ) {
if ( priorities [ i ] > 0 )
torrent_size + = t - > file_at ( i ) . size ;
}
lbl_torrent_size - > setText ( misc : : friendlyUnit ( torrent_size ) ) ;
// Check if free space is sufficient
if ( available > 0 ) {
if ( ( unsigned long long ) available > torrent_size ) {
// Space is sufficient
label_space_msg - > setText ( tr ( " (%1 left after torrent download) " , " e.g. (100MiB left after torrent download) " ) . arg ( misc : : friendlyUnit ( available - torrent_size ) ) ) ;
} else {
// Space is unsufficient
label_space_msg - > setText ( " <font color= \" red \" > " + tr ( " (%1 more are required to download) " , " e.g. (100MiB more are required to download) " ) . arg ( misc : : friendlyUnit ( torrent_size - available ) ) + " </font> " ) ;
}
} else {
// Available disk space is unknown
label_space_msg - > setText ( " " ) ;
}
}
void on_OkButton_clicked ( ) {
if ( savePathTxt - > text ( ) . trimmed ( ) . isEmpty ( ) ) {
QMessageBox : : critical ( 0 , tr ( " Empty save path " ) , tr ( " Please enter a save path " ) ) ;
return ;
}
QDir savePath ( misc : : expandPath ( savePathTxt - > text ( ) ) ) ;
// Check if savePath exists
if ( ! savePath . exists ( ) ) {
if ( ! savePath . mkpath ( savePath . path ( ) ) ) {
QMessageBox : : critical ( 0 , tr ( " Save path creation error " ) , tr ( " Could not create the save path " ) ) ;
return ;
void on_browseButton_clicked ( ) {
QString dir ;
QString save_path = misc : : expandPath ( savePathTxt - > text ( ) ) ;
QDir saveDir ( save_path ) ;
if ( ! save_path . isEmpty ( ) & & saveDir . exists ( ) ) {
dir = QFileDialog : : getExistingDirectory ( this , tr ( " Choose save path " ) , saveDir . absolutePath ( ) ) ;
} else {
dir = QFileDialog : : getExistingDirectory ( this , tr ( " Choose save path " ) , QDir : : homePath ( ) ) ;
}
if ( ! dir . isNull ( ) ) {
savePathTxt - > setText ( dir ) ;
}
}
}
// Save savepath
TorrentTempData : : setSavePath ( hash , savePath . path ( ) ) ;
qDebug ( " Torrent label is: %s " , comboLabel - > currentText ( ) . trimmed ( ) . toLocal8Bit ( ) . data ( ) ) ;
TorrentTempData : : setLabel ( hash , comboLabel - > currentText ( ) . trimmed ( ) ) ;
// Is download sequential?
TorrentTempData : : setSequential ( hash , checkIncrementalDL - > isChecked ( ) ) ;
# ifdef LIBTORRENT_0_15
// Skip file checking and directly start seeding
if ( addInSeed - > isChecked ( ) ) {
// Check if local file(s) actually exist
if ( savePath . exists ( misc : : toQString ( t - > name ( ) ) ) ) {
TorrentTempData : : setSeedingMode ( hash , true ) ;
} else {
QMessageBox : : warning ( 0 , tr ( " Seeding mode error " ) , tr ( " You chose to skip file checking. However, local files do not seem to exist in the current destionation folder. Please disable this feature or update the save path. " ) ) ;
return ;
void on_CancelButton_clicked ( ) {
close ( ) ;
}
}
bool allFiltered ( ) const {
return PropListModel - > allFiltered ( ) ;
}
void savePiecesPriorities ( ) {
qDebug ( " Saving pieces priorities " ) ;
std : : vector < int > priorities = PropListModel - > getFilesPriorities ( t - > num_files ( ) ) ;
TorrentTempData : : setFilesPriority ( hash , priorities ) ;
}
void on_OkButton_clicked ( ) {
if ( savePathTxt - > text ( ) . trimmed ( ) . isEmpty ( ) ) {
QMessageBox : : critical ( 0 , tr ( " Empty save path " ) , tr ( " Please enter a save path " ) ) ;
return ;
}
QDir savePath ( misc : : expandPath ( savePathTxt - > text ( ) ) ) ;
// Check if savePath exists
if ( ! savePath . exists ( ) ) {
if ( ! savePath . mkpath ( savePath . path ( ) ) ) {
QMessageBox : : critical ( 0 , tr ( " Save path creation error " ) , tr ( " Could not create the save path " ) ) ;
return ;
}
}
// Save savepath
TorrentTempData : : setSavePath ( hash , savePath . path ( ) ) ;
qDebug ( " Torrent label is: %s " , comboLabel - > currentText ( ) . trimmed ( ) . toLocal8Bit ( ) . data ( ) ) ;
TorrentTempData : : setLabel ( hash , comboLabel - > currentText ( ) . trimmed ( ) ) ;
// Is download sequential?
TorrentTempData : : setSequential ( hash , checkIncrementalDL - > isChecked ( ) ) ;
// Save files path
// Loads files path in the torrent
bool path_changed = false ;
for ( uint i = 0 ; i < nbFiles ; + + i ) {
# ifdef Q_WS_WIN
if ( files_path . at ( i ) . compare ( misc : : toQString ( t - > file_at ( i ) . path . string ( ) ) , Qt : : CaseInsensitive ) ! = 0 ) {
# else
if ( files_path . at ( i ) . compare ( misc : : toQString ( t - > file_at ( i ) . path . string ( ) ) , Qt : : CaseSensitive ) ! = 0 ) {
# endif
// Check if there is at least one selected file
if ( allFiltered ( ) ) {
QMessageBox : : warning ( 0 , tr ( " Invalid file selection " ) , tr ( " You must select at least one file in the torrent " ) ) ;
return ;
}
// save filtered files
savePiecesPriorities ( ) ;
// Add to download list
QTorrentHandle h = BTSession - > addTorrent ( filePath , false , from_url ) ;
if ( addInPause - > isChecked ( ) & & h . is_valid ( ) )
h . pause ( ) ;
close ( ) ;
}
} ;
path_changed = true ;
break ;
}
}
if ( path_changed ) {
TorrentTempData : : setFilesPath ( hash , files_path ) ;
}
# ifdef LIBTORRENT_0_15
// Skip file checking and directly start seeding
if ( addInSeed - > isChecked ( ) ) {
// Check if local file(s) actually exist
if ( savePath . exists ( misc : : toQString ( t - > name ( ) ) ) ) {
TorrentTempData : : setSeedingMode ( hash , true ) ;
} else {
QMessageBox : : warning ( 0 , tr ( " Seeding mode error " ) , tr ( " You chose to skip file checking. However, local files do not seem to exist in the current destionation folder. Please disable this feature or update the save path. " ) ) ;
return ;
}
}
# endif
// Check if there is at least one selected file
if ( allFiltered ( ) ) {
QMessageBox : : warning ( 0 , tr ( " Invalid file selection " ) , tr ( " You must select at least one file in the torrent " ) ) ;
return ;
}
// save filtered files
savePiecesPriorities ( ) ;
// Add to download list
QTorrentHandle h = BTSession - > addTorrent ( filePath , false , from_url ) ;
if ( addInPause - > isChecked ( ) & & h . is_valid ( ) )
h . pause ( ) ;
close ( ) ;
}
} ;
# endif