(trunk Qt) #2096 "magnet links" -- fix crashes when displaying magnet links in Qt client

This commit is contained in:
Charles Kerr 2009-12-03 17:23:53 +00:00
parent 31a3ed1684
commit bc25b7591e
7 changed files with 69 additions and 29 deletions

View File

@ -254,13 +254,15 @@ Details :: refresh( )
int64_t haveUnverified = 0;
int64_t verifiedPieces = 0;
foreach( const Torrent * t, torrents ) {
haveTotal += t->haveTotal( );
haveUnverified += t->haveUnverified( );
const uint64_t v = t->haveVerified( );
haveVerified += v;
verifiedPieces += v / t->pieceSize( );
sizeWhenDone += t->sizeWhenDone( );
leftUntilDone += t->leftUntilDone( );
if( t->hasMetadata( ) ) {
haveTotal += t->haveTotal( );
haveUnverified += t->haveUnverified( );
const uint64_t v = t->haveVerified( );
haveVerified += v;
verifiedPieces += v / t->pieceSize( );
sizeWhenDone += t->sizeWhenDone( );
leftUntilDone += t->leftUntilDone( );
}
}
if( !haveVerified && !haveUnverified )
string = none;

View File

@ -18,6 +18,7 @@
#include <QDesktopServices>
#include <QFileDialog>
#include <QHBoxLayout>
#include <QInputDialog>
#include <QLabel>
#include <QSignalMapper>
#include <QSize>
@ -110,7 +111,7 @@ TrMainWindow :: TrMainWindow( Session& session, Prefs& prefs, TorrentModel& mode
const QSize smallIconSize( i, i );
// icons
ui.action_Add->setIcon( getStockIcon( "list-add", QStyle::SP_DialogOpenButton ) );
ui.action_AddFile->setIcon( getStockIcon( "list-add", QStyle::SP_DialogOpenButton ) );
ui.action_New->setIcon( getStockIcon( "document-new", QStyle::SP_DesktopIcon ) );
ui.action_Properties->setIcon( getStockIcon( "document-properties", QStyle::SP_DesktopIcon ) );
ui.action_OpenFolder->setIcon( getStockIcon( "folder-open", QStyle::SP_DirOpenIcon ) );
@ -152,7 +153,8 @@ TrMainWindow :: TrMainWindow( Session& session, Prefs& prefs, TorrentModel& mode
connect( ui.action_Announce, SIGNAL(triggered()), this, SLOT(reannounceSelected()) );
connect( ui.action_StartAll, SIGNAL(triggered()), this, SLOT(startAll()));
connect( ui.action_PauseAll, SIGNAL(triggered()), this, SLOT(pauseAll()));
connect( ui.action_Add, SIGNAL(triggered()), this, SLOT(openTorrent()));
connect( ui.action_AddFile, SIGNAL(triggered()), this, SLOT(openTorrent()));
connect( ui.action_AddURL, SIGNAL(triggered()), this, SLOT(openURL()));
connect( ui.action_New, SIGNAL(triggered()), this, SLOT(newTorrent()));
connect( ui.action_Preferences, SIGNAL(triggered()), myPrefsDialog, SLOT(show()));
connect( ui.action_Statistics, SIGNAL(triggered()), myStatsDialog, SLOT(show()));
@ -219,7 +221,8 @@ TrMainWindow :: TrMainWindow( Session& session, Prefs& prefs, TorrentModel& mode
actionGroup->addAction( ui.action_SortByTracker );
QMenu * menu = new QMenu( );
menu->addAction( ui.action_Add );
menu->addAction( ui.action_AddFile );
menu->addAction( ui.action_AddURL );
menu->addSeparator( );
menu->addAction( ui.action_ShowMainWindow );
menu->addAction( ui.action_ShowMessageLog );
@ -1099,12 +1102,27 @@ TrMainWindow :: openTorrent( )
layout->addWidget( button, layout->rowCount( ), 0, 1, -1, Qt::AlignLeft );
myFileDialogOptionsCheck = button;
connect( myFileDialog, SIGNAL(filesSelected(const QStringList&)), this, SLOT(addTorrents(const QStringList&)));
connect( myFileDialog, SIGNAL(filesSelected(const QStringList&)),
this, SLOT(addTorrents(const QStringList&)));
}
myFileDialog->show( );
}
void
TrMainWindow :: openURL( )
{
bool ok;
const QString key = QInputDialog::getText( this,
tr( "Add URL or Magnet Link" ),
tr( "Add URL or Magnet Link" ),
QLineEdit::Normal,
QString( ),
&ok );
if( ok && !key.isEmpty( ) )
mySession.addTorrent( key );
}
void
TrMainWindow :: addTorrents( const QStringList& filenames )
{

View File

@ -110,6 +110,7 @@ class TrMainWindow: public QMainWindow
void refreshTitle( );
void refreshStatusBar( );
void openTorrent( );
void openURL( );
void newTorrent( );
void trayActivated( QSystemTrayIcon::ActivationReason );
void refreshPref( int key );

View File

@ -51,7 +51,7 @@
<x>0</x>
<y>0</y>
<width>792</width>
<height>23</height>
<height>25</height>
</rect>
</property>
<property name="sizePolicy">
@ -126,7 +126,8 @@
<property name="title">
<string>&amp;File</string>
</property>
<addaction name="action_Add"/>
<addaction name="action_AddFile"/>
<addaction name="action_AddURL"/>
<addaction name="action_New"/>
<addaction name="separator"/>
<addaction name="action_StartAll"/>
@ -168,16 +169,16 @@
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="action_Add"/>
<addaction name="action_AddFile"/>
<addaction name="action_Start"/>
<addaction name="action_Pause"/>
<addaction name="action_Remove"/>
<addaction name="separator"/>
<addaction name="action_Properties"/>
</widget>
<action name="action_Add">
<action name="action_AddFile">
<property name="text">
<string>&amp;Add...</string>
<string>&amp;Add File...</string>
</property>
<property name="toolTip">
<string>Add a torrent</string>
@ -549,6 +550,11 @@
<string>&amp;Copy Magnet Link to Clipboard</string>
</property>
</action>
<action name="action_AddURL">
<property name="text">
<string>Add &amp;URL...</string>
</property>
</action>
</widget>
<resources>
<include location="application.qrc"/>

View File

@ -857,30 +857,37 @@ Session :: addTorrent( QString filename )
}
void
Session :: addTorrent( QString filename, QString localPath )
Session :: addTorrent( QString key, QString localPath )
{
QFile file( filename );
tr_benc top, *args;
tr_bencInitDict( &top, 2 );
tr_bencDictAddStr( &top, "method", "torrent-add" );
args = tr_bencDictAddDict( &top, "arguments", 3 );
tr_bencDictAddStr( args, "download-dir", qPrintable(localPath) );
tr_bencDictAddInt( args, "paused", !myPrefs.getBool( Prefs::START ) );
// if "key" is a readable local file, add it as metadata...
// otherwise it's probably a URL or magnet link, so pass it along
// for the daemon to handle
QFile file( key );
file.open( QIODevice::ReadOnly );
const QByteArray raw( file.readAll( ) );
file.close( );
if( !raw.isEmpty( ) )
{
int b64len = 0;
char * b64 = tr_base64_encode( raw.constData(), raw.size(), &b64len );
tr_benc top, *args;
tr_bencInitDict( &top, 2 );
tr_bencDictAddStr( &top, "method", "torrent-add" );
args = tr_bencDictAddDict( &top, "arguments", 3 );
tr_bencDictAddStr( args, "download-dir", qPrintable(localPath) );
tr_bencDictAddRaw( args, "metainfo", b64, b64len );
tr_bencDictAddInt( args, "paused", !myPrefs.getBool( Prefs::START ) );
exec( &top );
tr_free( b64 );
tr_bencFree( &top );
}
else
{
tr_bencDictAddStr( args, "filename", key.toUtf8().constData() );
}
exec( &top );
tr_bencFree( &top );
}
void

View File

@ -71,6 +71,7 @@ Torrent :: myProperties[] =
{ PEERS_SENDING_TO_US, "peersSendingToUs", QVariant::Int, STAT },
{ WEBSEEDS_SENDING_TO_US, "webseedsSendingToUs", QVariant::Int, STAT_EXTRA },
{ PERCENT_DONE, "percentDone", QVariant::Double, STAT },
{ METADATA_PERCENT_DONE, "metadataPercentComplete", QVariant::Double, STAT },
{ PERCENT_VERIFIED, "recheckProgress", QVariant::Double, STAT },
{ DATE_ACTIVITY, "activityDate", QVariant::DateTime, STAT_EXTRA },
{ DATE_ADDED, "addedDate", QVariant::DateTime, INFO },
@ -413,8 +414,10 @@ Torrent :: updateMimeIcon( )
if( files.size( ) > 1 )
icon = QFileIconProvider().icon( QFileIconProvider::Folder );
else
else if( files.size( ) == 1 )
icon = Utils :: guessMimeIcon( files.at(0).filename );
else
icon = QIcon( );
setIcon( MIME_ICON, icon );
}

View File

@ -101,6 +101,7 @@ class Torrent: public QObject
PEERS_SENDING_TO_US,
WEBSEEDS_SENDING_TO_US,
PERCENT_DONE,
METADATA_PERCENT_DONE,
PERCENT_VERIFIED,
DATE_ACTIVITY,
DATE_ADDED,
@ -222,9 +223,11 @@ class Torrent: public QObject
uint64_t sizeWhenDone( ) const { return getSize( SIZE_WHEN_DONE ); }
uint64_t leftUntilDone( ) const { return getSize( LEFT_UNTIL_DONE ); }
uint64_t pieceSize( ) const { return getSize( PIECE_SIZE ); }
bool hasMetadata( ) const { return getDouble( METADATA_PERCENT_DONE ) >= 1.0; }
int pieceCount( ) const { return getInt( PIECE_COUNT ); }
double ratio( ) const { return getDouble( RATIO ); }
double percentDone( ) const { return getDouble( PERCENT_DONE ); }
double metadataPercentDone( ) const { return getDouble( METADATA_PERCENT_DONE ); }
uint64_t downloadedEver( ) const { return getSize( DOWNLOADED_EVER ); }
uint64_t uploadedEver( ) const { return getSize( UPLOADED_EVER ); }
uint64_t failedEver( ) const { return getSize( FAILED_EVER ); }