2
* This file Copyright (C) 2009 Charles Kerr <charles@transmissionbt.com>
4
* This file is licensed by the GPL version 2. Works owned by the
5
* Transmission project are granted a special exemption to clause 2(b)
6
* so that the bulk of its code can remain under the MIT license.
7
* This exemption does not extend to derived works not owned by
8
* the Transmission project.
18
#include <QLibraryInfo>
20
#include <QTranslator>
22
#include <libtransmission/transmission.h>
23
#include <libtransmission/tr-getopt.h>
29
#include "torrent-model.h"
36
const char * MY_NAME( "transmission" );
38
const tr_option opts[] =
40
{ 'g', "config-dir", "Where to look for configuration files", "g", 1, "<path>" },
41
{ 'm', "minimized", "Start minimized in system tray", "m", 0, NULL },
42
{ 'p', "paused", "Pause all torrents on sartup", "p", 0, NULL },
43
{ 'r', "remote", "Remotely control a pre-existing session", "r", 1, "<URL>" },
44
{ 'v', "version", "Show version number and exit", "v", 0, NULL },
45
{ 0, NULL, NULL, NULL, 0, NULL }
51
return "Transmission " LONG_VERSION_STRING "\n"
52
"http://www.transmissionbt.com/\n"
53
"A fast and easy BitTorrent client";
59
tr_getopt_usage( MY_NAME, getUsage( ), opts );
65
STATS_REFRESH_INTERVAL_MSEC = 3000,
66
SESSION_REFRESH_INTERVAL_MSEC = 3000,
67
MODEL_REFRESH_INTERVAL_MSEC = 3000
71
MyApp :: MyApp( int& argc, char ** argv ):
72
QApplication( argc, argv ),
73
myLastFullUpdateTime( 0 )
75
setApplicationName( MY_NAME );
77
// install the qt translator
78
QTranslator * t = new QTranslator( );
79
t->load( "qt_" + QLocale::system().name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath));
80
installTranslator( t );
82
// install the transmission translator
83
t = new QTranslator( );
84
t->load( QString(MY_NAME) + "_" + QLocale::system().name() );
85
installTranslator( t );
87
// set the default icon
89
icon.addPixmap( QPixmap( ":/icons/transmission-16.png" ) );
90
icon.addPixmap( QPixmap( ":/icons/transmission-22.png" ) );
91
icon.addPixmap( QPixmap( ":/icons/transmission-24.png" ) );
92
icon.addPixmap( QPixmap( ":/icons/transmission-32.png" ) );
93
icon.addPixmap( QPixmap( ":/icons/transmission-48.png" ) );
94
setWindowIcon( icon );
96
// parse the command-line arguments
99
bool minimized = false;
101
const char * configDir = 0;
102
const char * url = 0;
103
while( ( c = tr_getopt( getUsage( ), argc, (const char**)argv, opts, &optarg ) ) ) {
105
case 'g': configDir = optarg; break;
106
case 'm': minimized = true; break;
107
case 'p': paused = true; break;
108
case 'r': url = optarg; break;
109
case 'v': Utils::toStderr( QObject::tr( "transmission %1" ).arg( LONG_VERSION_STRING ) ); exit( 0 ); break;
110
case TR_OPT_ERR: Utils::toStderr( QObject::tr( "Invalid option" ) ); showUsage( ); break;
111
default: Utils::toStderr( QObject::tr( "Got opt %1" ).arg((int)c) ); showUsage( ); break;
115
// set the fallback config dir
117
configDir = tr_getDefaultConfigDir( MY_NAME );
119
myPrefs = new Prefs ( configDir );
120
mySession = new Session( configDir, *myPrefs, url, paused );
121
myModel = new TorrentModel( *myPrefs );
122
myWindow = new TrMainWindow( *mySession, *myPrefs, *myModel, minimized );
123
myWatchDir = new WatchDir( *myModel );
125
/* when the session gets torrent info, update the model */
126
connect( mySession, SIGNAL(torrentsUpdated(tr_benc*,bool)), myModel, SLOT(updateTorrents(tr_benc*,bool)) );
127
connect( mySession, SIGNAL(torrentsUpdated(tr_benc*,bool)), myWindow, SLOT(refreshActionSensitivity()) );
128
connect( mySession, SIGNAL(torrentsRemoved(tr_benc*)), myModel, SLOT(removeTorrents(tr_benc*)) );
129
/* when the model sees a torrent for the first time, ask the session for full info on it */
130
connect( myModel, SIGNAL(torrentsAdded(QSet<int>)), mySession, SLOT(initTorrents(QSet<int>)) );
132
mySession->initTorrents( );
133
mySession->refreshSessionStats( );
135
/* when torrents are added to the watch directory, tell the session */
136
connect( myWatchDir, SIGNAL(torrentFileAdded(QString)), this, SLOT(addTorrent(QString)) );
138
/* init from preferences */
140
initKeys << Prefs::DIR_WATCH;
141
foreach( int key, initKeys )
143
connect( myPrefs, SIGNAL(changed(int)), this, SLOT(refreshPref(const int)) );
145
QTimer * timer = &myModelTimer;
146
connect( timer, SIGNAL(timeout()), this, SLOT(refreshTorrents()) );
147
timer->setSingleShot( false );
148
timer->setInterval( MODEL_REFRESH_INTERVAL_MSEC );
151
timer = &myStatsTimer;
152
connect( timer, SIGNAL(timeout()), mySession, SLOT(refreshSessionStats()) );
153
timer->setSingleShot( false );
154
timer->setInterval( STATS_REFRESH_INTERVAL_MSEC );
157
timer = &mySessionTimer;
158
connect( timer, SIGNAL(timeout()), mySession, SLOT(refreshSessionInfo()) );
159
timer->setSingleShot( false );
160
timer->setInterval( SESSION_REFRESH_INTERVAL_MSEC );
163
maybeUpdateBlocklist( );
168
const QRect mainwinRect( myWindow->geometry( ) );
174
myPrefs->set( Prefs :: MAIN_WINDOW_HEIGHT, std::max( 100, mainwinRect.height( ) ) );
175
myPrefs->set( Prefs :: MAIN_WINDOW_WIDTH, std::max( 100, mainwinRect.width( ) ) );
176
myPrefs->set( Prefs :: MAIN_WINDOW_X, mainwinRect.x( ) );
177
myPrefs->set( Prefs :: MAIN_WINDOW_Y, mainwinRect.y( ) );
186
MyApp :: refreshPref( int key )
190
case Prefs :: BLOCKLIST_UPDATES_ENABLED:
191
maybeUpdateBlocklist( );
194
case Prefs :: DIR_WATCH:
195
case Prefs :: DIR_WATCH_ENABLED: {
196
const QString path( myPrefs->getString( Prefs::DIR_WATCH ) );
197
const bool isEnabled( myPrefs->getBool( Prefs::DIR_WATCH_ENABLED ) );
198
myWatchDir->setPath( path, isEnabled );
208
MyApp :: maybeUpdateBlocklist( )
210
if( !myPrefs->getBool( Prefs :: BLOCKLIST_UPDATES_ENABLED ) )
213
const QDateTime lastUpdatedAt = myPrefs->getDateTime( Prefs :: BLOCKLIST_DATE );
214
const QDateTime nextUpdateAt = lastUpdatedAt.addDays( 7 );
215
const QDateTime now = QDateTime::currentDateTime( );
216
if( now < nextUpdateAt )
218
mySession->updateBlocklist( );
219
myPrefs->set( Prefs :: BLOCKLIST_DATE, now );
224
MyApp :: refreshTorrents( )
226
// usually we just poll the torrents that have shown recent activity,
227
// but we also periodically ask for updates on the others to ensure
228
// nothing's falling through the cracks.
229
const time_t now = time( NULL );
230
if( myLastFullUpdateTime + 60 >= now )
231
mySession->refreshActiveTorrents( );
233
myLastFullUpdateTime = now;
234
mySession->refreshAllTorrents( );
239
MyApp :: addTorrent( const QString& filename )
241
if( myPrefs->getBool( Prefs :: OPTIONS_PROMPT ) ) {
242
Options * o = new Options( *mySession, *myPrefs, filename, myWindow );
244
QApplication :: alert( o );
246
mySession->addTorrent( filename );
247
QApplication :: alert ( myWindow );
257
main( int argc, char * argv[] )
259
MyApp app( argc, argv );