source: trunk/qt/app.cc @ 9175

Last change on this file since 9175 was 9175, checked in by charles, 13 years ago

(trunk qt) #2418: Cannot open a torrent in kde4 with right clicking

  • Property svn:keywords set to Date Rev Author Id
File size: 8.0 KB
Line 
1/*
2 * This file Copyright (C) 2009 Charles Kerr <charles@transmissionbt.com>
3 *
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.
9 *
10 * $Id: app.cc 9175 2009-09-26 04:11:00Z charles $
11 */
12
13#include <cassert>
14#include <ctime>
15#include <iostream>
16
17#include <QIcon>
18#include <QLibraryInfo>
19#include <QRect>
20#include <QTranslator>
21
22#include <libtransmission/transmission.h>
23#include <libtransmission/tr-getopt.h>
24#include <libtransmission/version.h>
25
26#include "app.h"
27#include "mainwin.h"
28#include "options.h"
29#include "prefs.h"
30#include "session.h"
31#include "session-dialog.h"
32#include "torrent-model.h"
33#include "utils.h"
34#include "watchdir.h"
35
36namespace
37{
38    const char * MY_NAME( "transmission" );
39
40    const tr_option opts[] =
41    {
42        { 'g', "config-dir", "Where to look for configuration files", "g", 1, "<path>" },
43        { 'm', "minimized",  "Start minimized in system tray", "m", 0, NULL },
44        { 'v', "version", "Show version number and exit", "v", 0, NULL },
45        { 0, NULL, NULL, NULL, 0, NULL }
46    };
47
48    const char*
49    getUsage( void )
50    {
51        return "Usage:\n"
52               "  transmission [OPTIONS...] [torrent files]";
53    }
54
55    void
56    showUsage( void )
57    {
58        tr_getopt_usage( MY_NAME, getUsage( ), opts );
59        exit( 0 );
60    }
61
62    enum
63    {
64        STATS_REFRESH_INTERVAL_MSEC = 3000,
65        SESSION_REFRESH_INTERVAL_MSEC = 3000,
66        MODEL_REFRESH_INTERVAL_MSEC = 3000
67    };
68}
69
70MyApp :: MyApp( int& argc, char ** argv ):
71    QApplication( argc, argv ),
72    myLastFullUpdateTime( 0 )
73{
74    setApplicationName( MY_NAME );
75
76    // install the qt translator
77    QTranslator * t = new QTranslator( );
78    t->load( "qt_" + QLocale::system().name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath));
79    installTranslator( t );
80
81    // install the transmission translator
82    t = new QTranslator( );
83    t->load( QString(MY_NAME) + "_" + QLocale::system().name() );
84    installTranslator( t );
85
86    // set the default icon
87    QIcon icon;
88    icon.addPixmap( QPixmap( ":/icons/transmission-16.png" ) );
89    icon.addPixmap( QPixmap( ":/icons/transmission-22.png" ) );
90    icon.addPixmap( QPixmap( ":/icons/transmission-24.png" ) );
91    icon.addPixmap( QPixmap( ":/icons/transmission-32.png" ) );
92    icon.addPixmap( QPixmap( ":/icons/transmission-48.png" ) );
93    setWindowIcon( icon );
94
95    // parse the command-line arguments
96    int c;
97    bool minimized = false;
98    const char * optarg;
99    const char * configDir = 0;
100    QStringList filenames;
101    while( ( c = tr_getopt( getUsage( ), argc, (const char**)argv, opts, &optarg ) ) ) {
102        switch( c ) {
103            case 'g': configDir = optarg; break;
104            case 'm': minimized = true; break;
105            case 'v':        Utils::toStderr( QObject::tr( "transmission %1" ).arg( LONG_VERSION_STRING ) ); exit( 0 ); break;
106            case TR_OPT_ERR: Utils::toStderr( QObject::tr( "Invalid option" ) ); showUsage( ); break;
107            default:         filenames.append( optarg ); break;
108        }
109    }
110
111    // set the fallback config dir
112    if( configDir == 0 )
113        configDir = tr_getDefaultConfigDir( MY_NAME );
114
115    // is this the first time we've run transmission?
116    const bool firstTime = !QFile(QDir(configDir).absoluteFilePath("settings.json")).exists();
117
118    myPrefs = new Prefs ( configDir );
119    mySession = new Session( configDir, *myPrefs );
120    myModel = new TorrentModel( *myPrefs );
121    myWindow = new TrMainWindow( *mySession, *myPrefs, *myModel, minimized );
122    myWatchDir = new WatchDir( *myModel );
123
124    // when the session gets torrent info, update the model
125    connect( mySession, SIGNAL(torrentsUpdated(tr_benc*,bool)), myModel, SLOT(updateTorrents(tr_benc*,bool)) );
126    connect( mySession, SIGNAL(torrentsUpdated(tr_benc*,bool)), myWindow, SLOT(refreshActionSensitivity()) );
127    connect( mySession, SIGNAL(torrentsRemoved(tr_benc*)), myModel, SLOT(removeTorrents(tr_benc*)) );
128    // when the model sees a torrent for the first time, ask the session for full info on it
129    connect( myModel, SIGNAL(torrentsAdded(QSet<int>)), mySession, SLOT(initTorrents(QSet<int>)) );
130
131    mySession->initTorrents( );
132    mySession->refreshSessionStats( );
133
134    // when torrents are added to the watch directory, tell the session
135    connect( myWatchDir, SIGNAL(torrentFileAdded(QString)), this, SLOT(addTorrent(QString)) );
136
137    // init from preferences
138    QList<int> initKeys;
139    initKeys << Prefs::DIR_WATCH;
140    foreach( int key, initKeys )
141        refreshPref( key );
142    connect( myPrefs, SIGNAL(changed(int)), this, SLOT(refreshPref(const int)) );
143
144    QTimer * timer = &myModelTimer;
145    connect( timer, SIGNAL(timeout()), this, SLOT(refreshTorrents()) );
146    timer->setSingleShot( false );
147    timer->setInterval( MODEL_REFRESH_INTERVAL_MSEC );
148    timer->start( );
149
150    timer = &myStatsTimer;
151    connect( timer, SIGNAL(timeout()), mySession, SLOT(refreshSessionStats()) );
152    timer->setSingleShot( false );
153    timer->setInterval( STATS_REFRESH_INTERVAL_MSEC );
154    timer->start( );
155
156    timer = &mySessionTimer;
157    connect( timer, SIGNAL(timeout()), mySession, SLOT(refreshSessionInfo()) );
158    timer->setSingleShot( false );
159    timer->setInterval( SESSION_REFRESH_INTERVAL_MSEC );
160    timer->start( );
161
162    maybeUpdateBlocklist( );
163
164    if( !firstTime )
165        mySession->restart( );
166    else {
167        QDialog * d = new SessionDialog( *mySession, *myPrefs, myWindow );
168        d->show( );
169    }
170
171    for( QStringList::const_iterator it=filenames.begin(), end=filenames.end(); it!=end; ++it )
172        mySession->addTorrent( *it );
173}
174
175MyApp :: ~MyApp( )
176{
177    const QRect mainwinRect( myWindow->geometry( ) );
178    delete myWatchDir;
179    delete myWindow;
180    delete myModel;
181    delete mySession;
182
183    myPrefs->set( Prefs :: MAIN_WINDOW_HEIGHT, std::max( 100, mainwinRect.height( ) ) );
184    myPrefs->set( Prefs :: MAIN_WINDOW_WIDTH, std::max( 100, mainwinRect.width( ) ) );
185    myPrefs->set( Prefs :: MAIN_WINDOW_X, mainwinRect.x( ) );
186    myPrefs->set( Prefs :: MAIN_WINDOW_Y, mainwinRect.y( ) );
187    delete myPrefs;
188}
189
190/***
191****
192***/
193
194void
195MyApp :: refreshPref( int key )
196{
197    switch( key )
198    {
199        case Prefs :: BLOCKLIST_UPDATES_ENABLED:
200            maybeUpdateBlocklist( );
201            break;
202
203        case Prefs :: DIR_WATCH:
204        case Prefs :: DIR_WATCH_ENABLED: {
205            const QString path( myPrefs->getString( Prefs::DIR_WATCH ) );
206            const bool isEnabled( myPrefs->getBool( Prefs::DIR_WATCH_ENABLED ) );
207            myWatchDir->setPath( path, isEnabled );
208            break;
209        }
210
211        default:
212            break;
213    }
214}
215
216void
217MyApp :: maybeUpdateBlocklist( )
218{
219    if( !myPrefs->getBool( Prefs :: BLOCKLIST_UPDATES_ENABLED ) )
220        return;
221
222     const QDateTime lastUpdatedAt = myPrefs->getDateTime( Prefs :: BLOCKLIST_DATE );
223     const QDateTime nextUpdateAt = lastUpdatedAt.addDays( 7 );
224     const QDateTime now = QDateTime::currentDateTime( );
225     if( now < nextUpdateAt )
226     {
227         mySession->updateBlocklist( );
228         myPrefs->set( Prefs :: BLOCKLIST_DATE, now );
229     }
230}
231
232void
233MyApp :: refreshTorrents( )
234{
235    // usually we just poll the torrents that have shown recent activity,
236    // but we also periodically ask for updates on the others to ensure
237    // nothing's falling through the cracks.
238    const time_t now = time( NULL );
239    if( myLastFullUpdateTime + 60 >= now )
240        mySession->refreshActiveTorrents( );
241    else {
242        myLastFullUpdateTime = now;
243        mySession->refreshAllTorrents( );
244    }
245}
246
247void
248MyApp :: addTorrent( const QString& filename )
249{
250    if( myPrefs->getBool( Prefs :: OPTIONS_PROMPT ) ) {
251        Options * o = new Options( *mySession, *myPrefs, filename, myWindow );
252        o->show( );
253        QApplication :: alert( o );
254    } else {
255        mySession->addTorrent( filename );
256        QApplication :: alert ( myWindow );
257    }
258}
259
260
261/***
262****
263***/
264
265int
266main( int argc, char * argv[] )
267{
268    MyApp app( argc, argv );
269    return app.exec( );
270}
Note: See TracBrowser for help on using the repository browser.