source: trunk/qt/prefs.cc @ 8326

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

(trunk) very minor tweaks

File size: 12.6 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:$
11 */
12
13#include <cassert>
14#include <iostream>
15#include <cstdlib> // strtod
16
17#include <QDir>
18#include <QFile>
19
20#include <libtransmission/transmission.h>
21#include <libtransmission/bencode.h>
22#include <libtransmission/json.h>
23#include <libtransmission/utils.h>
24#include "prefs.h"
25#include "types.h"
26
27/***
28****
29***/
30
31Prefs::PrefItem Prefs::myItems[] =
32{
33    /* gui settings */
34    { OPTIONS_PROMPT, "show-options-window", QVariant::Bool },
35    { OPEN_DIALOG_FOLDER, "open-dialog-dir", QVariant::String },
36    { INHIBIT_HIBERNATION, "inhibit-desktop-hibernation", QVariant::Bool },
37    { DIR_WATCH, "watch-dir", QVariant::String },
38    { DIR_WATCH_ENABLED, "watch-dir-enabled", QVariant::Bool },
39    { SHOW_TRAY_ICON, "show-notification-area-icon", QVariant::Bool },
40    { SHOW_DESKTOP_NOTIFICATION, "show-desktop-notification", QVariant::Bool },
41    { START, "start-added-torrents", QVariant::Bool },
42    { TRASH_ORIGINAL, "trash-original-torrent-files", QVariant::Bool },
43    { ASKQUIT, "prompt-before-exit", QVariant::Bool },
44    { SORT_MODE, "sort-mode", TrTypes::SortModeType },
45    { SORT_REVERSED, "sort-reversed", QVariant::Bool },
46    { MINIMAL_VIEW, "minimal-view", QVariant::Bool },
47    { FILTERBAR, "show-filterbar", QVariant::Bool },
48    { STATUSBAR, "show-statusbar", QVariant::Bool },
49    { STATUSBAR_STATS, "statusbar-stats", QVariant::String },
50    { TOOLBAR, "show-toolbar" , QVariant::Bool },
51    { BLOCKLIST_DATE, "blocklist-date", QVariant::DateTime },
52    { BLOCKLIST_UPDATES_ENABLED, "blocklist-updates-enabled" , QVariant::Bool },
53    { MAIN_WINDOW_LAYOUT_ORDER, "main-window-layout-order", QVariant::String },
54    { MAIN_WINDOW_HEIGHT, "main-window-height", QVariant::Int },
55    { MAIN_WINDOW_WIDTH, "main-window-width", QVariant::Int },
56    { MAIN_WINDOW_X, "main-window-x", QVariant::Int },
57    { MAIN_WINDOW_Y, "main-window-y", QVariant::Int },
58    { FILTER_MODE, "filter-mode", TrTypes::FilterModeType },
59    { SESSION_IS_REMOTE, "remote-session-enabled", QVariant::Bool },
60    { SESSION_REMOTE_HOST, "remote-session-host", QVariant::String },
61    { SESSION_REMOTE_PORT, "remote-session-port", QVariant::Int },
62    { SESSION_REMOTE_AUTH, "remote-session-requres-authentication", QVariant::Bool },
63    { SESSION_REMOTE_USERNAME, "remote-session-username", QVariant::String },
64    { SESSION_REMOTE_PASSWORD, "remote-session-password", QVariant::String },
65
66    /* libtransmission settings */
67    { ALT_SPEED_LIMIT_UP, TR_PREFS_KEY_ALT_SPEED_UP, QVariant::Int },
68    { ALT_SPEED_LIMIT_DOWN, TR_PREFS_KEY_ALT_SPEED_DOWN, QVariant::Int },
69    { ALT_SPEED_LIMIT_ENABLED, TR_PREFS_KEY_ALT_SPEED_ENABLED, QVariant::Bool },
70    { ALT_SPEED_LIMIT_TIME_BEGIN, TR_PREFS_KEY_ALT_SPEED_TIME_BEGIN, QVariant::Int },
71    { ALT_SPEED_LIMIT_TIME_END, TR_PREFS_KEY_ALT_SPEED_TIME_END, QVariant::Int },
72    { ALT_SPEED_LIMIT_TIME_ENABLED, TR_PREFS_KEY_ALT_SPEED_TIME_ENABLED, QVariant::Bool },
73    { ALT_SPEED_LIMIT_TIME_DAY, TR_PREFS_KEY_ALT_SPEED_TIME_DAY, QVariant::Int },
74    { BLOCKLIST_ENABLED, TR_PREFS_KEY_BLOCKLIST_ENABLED, QVariant::Bool },
75    { DSPEED, TR_PREFS_KEY_DSPEED, QVariant::Int },
76    { DSPEED_ENABLED, TR_PREFS_KEY_DSPEED_ENABLED, QVariant::Bool },
77    { DOWNLOAD_DIR, TR_PREFS_KEY_DOWNLOAD_DIR, QVariant::String },
78    { ENCRYPTION, TR_PREFS_KEY_ENCRYPTION, QVariant::Int },
79    { LAZY_BITFIELD, TR_PREFS_KEY_LAZY_BITFIELD, QVariant::Bool },
80    { MSGLEVEL, TR_PREFS_KEY_MSGLEVEL, QVariant::Int },
81    { OPEN_FILE_LIMIT, TR_PREFS_KEY_OPEN_FILE_LIMIT, QVariant::Int },
82    { PEER_LIMIT_GLOBAL, TR_PREFS_KEY_PEER_LIMIT_GLOBAL, QVariant::Int },
83    { PEER_LIMIT_TORRENT, TR_PREFS_KEY_PEER_LIMIT_TORRENT, QVariant::Int },
84    { PEER_PORT, TR_PREFS_KEY_PEER_PORT, QVariant::Int },
85    { PEER_PORT_RANDOM_ON_START, TR_PREFS_KEY_PEER_PORT_RANDOM_ON_START, QVariant::Bool },
86    { PEER_PORT_RANDOM_LOW, TR_PREFS_KEY_PEER_PORT_RANDOM_LOW, QVariant::Int },
87    { PEER_PORT_RANDOM_HIGH, TR_PREFS_KEY_PEER_PORT_RANDOM_HIGH, QVariant::Int },
88    { SOCKET_TOS, TR_PREFS_KEY_PEER_SOCKET_TOS, QVariant::Int },
89    { PEX_ENABLED, TR_PREFS_KEY_PEX_ENABLED, QVariant::Bool },
90    { PORT_FORWARDING, TR_PREFS_KEY_PORT_FORWARDING, QVariant::Bool },
91    { PROXY_AUTH_ENABLED, TR_PREFS_KEY_PROXY_AUTH_ENABLED, QVariant::Bool },
92    { PREALLOCATION, TR_PREFS_KEY_PREALLOCATION, QVariant::Int },
93    { PROXY_ENABLED, TR_PREFS_KEY_PROXY_ENABLED, QVariant::Bool },
94    { PROXY_PASSWORD, TR_PREFS_KEY_PROXY_PASSWORD, QVariant::String },
95    { PROXY_PORT, TR_PREFS_KEY_PROXY_PORT, QVariant::Int },
96    { PROXY, TR_PREFS_KEY_PROXY, QVariant::String },
97    { PROXY_TYPE, TR_PREFS_KEY_PROXY_TYPE, QVariant::Int },
98    { PROXY_USERNAME, TR_PREFS_KEY_PROXY_USERNAME, QVariant::String },
99    { RATIO, TR_PREFS_KEY_RATIO, QVariant::Double },
100    { RATIO_ENABLED, TR_PREFS_KEY_RATIO_ENABLED, QVariant::Bool },
101    { RPC_AUTH_REQUIRED, TR_PREFS_KEY_RPC_AUTH_REQUIRED, QVariant::Bool },
102    { RPC_ENABLED, TR_PREFS_KEY_RPC_ENABLED, QVariant::Bool },
103    { RPC_PASSWORD, TR_PREFS_KEY_RPC_PASSWORD, QVariant::String },
104    { RPC_PORT, TR_PREFS_KEY_RPC_PORT, QVariant::Int },
105    { RPC_USERNAME, TR_PREFS_KEY_RPC_USERNAME, QVariant::String },
106    { RPC_WHITELIST_ENABLED, TR_PREFS_KEY_RPC_WHITELIST_ENABLED, QVariant::Bool },
107    { RPC_WHITELIST, TR_PREFS_KEY_RPC_WHITELIST, QVariant::String },
108    { SEED_RATIO_LIMIT, TR_PREFS_KEY_RATIO, QVariant::Double },
109    { SEED_RATIO_LIMITED, TR_PREFS_KEY_RATIO_ENABLED, QVariant::Bool },
110    { USPEED_ENABLED, TR_PREFS_KEY_USPEED_ENABLED, QVariant::Bool },
111    { USPEED, TR_PREFS_KEY_USPEED, QVariant::Int },
112    { UPLOAD_SLOTS_PER_TORRENT, TR_PREFS_KEY_UPLOAD_SLOTS_PER_TORRENT, QVariant::Int }
113};
114
115/***
116****
117***/
118
119Prefs :: Prefs( const char * configDir ):
120    myConfigDir( configDir )
121{
122    assert( sizeof(myItems) / sizeof(myItems[0]) == PREFS_COUNT );
123    for( int i=0; i<PREFS_COUNT; ++i )
124        assert( myItems[i].id == i );
125
126    tr_benc top;
127    tr_bencInitDict( &top, 0 );
128    initDefaults( &top );
129    tr_sessionLoadSettings( &top, configDir, NULL );
130    for( int i=0; i<PREFS_COUNT; ++i )
131    {
132        double d;
133        tr_bool boolVal;
134        int64_t intVal;
135        const char * str;
136        tr_benc * b( tr_bencDictFind( &top, myItems[i].key ) );
137
138        switch( myItems[i].type )
139        {
140            case QVariant::Int:
141                if( tr_bencGetInt( b, &intVal ) )
142                    myValues[i].setValue( qlonglong(intVal) );
143                break;
144            case TrTypes::SortModeType:
145                if( tr_bencGetStr( b, &str ) )
146                    myValues[i] = QVariant::fromValue( SortMode( str ) );
147                break;
148            case TrTypes::FilterModeType:
149                if( tr_bencGetStr( b, &str ) )
150                    myValues[i] = QVariant::fromValue( FilterMode( str ) );
151                break;
152            case QVariant::String:
153                if( tr_bencGetStr( b, &str ) )
154                    myValues[i].setValue( QString::fromUtf8(str) );
155                break;
156            case QVariant::Bool:
157                if( tr_bencGetBool( b, &boolVal ) )
158                    myValues[i].setValue( bool(boolVal) );
159                break;
160            case QVariant::Double:
161                if( tr_bencGetReal( b, &d ) )
162                    myValues[i].setValue( d );
163                break;
164            case QVariant::DateTime:
165                if( tr_bencGetInt( b, &intVal ) )
166                    myValues[i].setValue( QDateTime :: fromTime_t( intVal ) );
167                break;
168            default:
169                assert( "unhandled type" && 0 );
170                break;
171        }
172    }
173
174    tr_bencFree( &top );
175}
176
177Prefs :: ~Prefs( )
178{
179    tr_benc top;
180
181    /* load in the existing preferences file */
182    QFile file( QDir( myConfigDir ).absoluteFilePath( "settings.json" ) );
183    file.open( QIODevice::ReadOnly | QIODevice::Text );
184    const QByteArray oldPrefs = file.readAll( );
185    file.close( );
186    if( tr_jsonParse( oldPrefs.data(), oldPrefs.length(), &top, NULL ) )
187        tr_bencInitDict( &top, PREFS_COUNT );
188
189    /* merge our own settings with the ones already in the file */
190    for( int i=0; i<PREFS_COUNT; ++i ) {
191        const char * key = myItems[i].key;
192        const QVariant& val = myValues[i];
193        switch( myItems[i].type ) {
194            case QVariant::Int:
195                tr_bencDictAddInt( &top, key, val.toInt() );
196                break;
197            case TrTypes::SortModeType:
198                tr_bencDictAddStr( &top, key, val.value<SortMode>().name().toUtf8().constData() );
199                break;
200            case TrTypes::FilterModeType:
201                tr_bencDictAddStr( &top, key, val.value<FilterMode>().name().toUtf8().constData() );
202                break;
203            case QVariant::String:
204                tr_bencDictAddStr( &top, key, val.toString().toUtf8().constData() );
205                break;
206            case QVariant::Bool:
207                tr_bencDictAddBool( &top, key, val.toBool() );
208                break;
209            case QVariant::Double:
210                tr_bencDictAddReal( &top, key, val.toDouble() );
211                break;
212            case QVariant::DateTime:
213                tr_bencDictAddInt( &top, key, val.toDateTime().toTime_t() );
214                break;
215            default:
216                assert( "unhandled type" && 0 );
217                break;
218        }
219    }
220
221    /* write back out the serialized preferences */
222    char * json = tr_bencToJSON( &top );
223    if( json && *json ) {
224        file.open( QIODevice::WriteOnly | QIODevice::Text );
225        file.write( json );
226        file.close( );
227    }
228    tr_free( json );
229    tr_bencFree( &top );
230}
231
232/**
233 * This is where we initialize the preferences file with the default values.
234 * If you add a new preferences key, you /must/ add a default value here.
235 */
236void
237Prefs :: initDefaults( tr_benc * d )
238{
239    tr_bencDictAddStr( d, keyStr(DIR_WATCH), tr_getDefaultDownloadDir( ) );
240    tr_bencDictAddInt( d, keyStr(DIR_WATCH_ENABLED), false );
241    tr_bencDictAddInt( d, keyStr(INHIBIT_HIBERNATION), false );
242    tr_bencDictAddInt( d, keyStr(BLOCKLIST_DATE), 0 );
243    tr_bencDictAddInt( d, keyStr(BLOCKLIST_UPDATES_ENABLED), true );
244    tr_bencDictAddStr( d, keyStr(OPEN_DIALOG_FOLDER), QDir::home().absolutePath().toLatin1() );
245    tr_bencDictAddInt( d, keyStr(TOOLBAR), true );
246    tr_bencDictAddInt( d, keyStr(FILTERBAR), true );
247    tr_bencDictAddInt( d, keyStr(STATUSBAR), true );
248    tr_bencDictAddInt( d, keyStr(SHOW_TRAY_ICON), false );
249    tr_bencDictAddInt( d, keyStr(SHOW_DESKTOP_NOTIFICATION), true );
250    tr_bencDictAddStr( d, keyStr(STATUSBAR_STATS), "total-ratio" );
251    tr_bencDictAddInt( d, keyStr(OPTIONS_PROMPT), true );
252    tr_bencDictAddInt( d, keyStr(MAIN_WINDOW_HEIGHT), 500 );
253    tr_bencDictAddInt( d, keyStr(MAIN_WINDOW_WIDTH), 300 );
254    tr_bencDictAddInt( d, keyStr(MAIN_WINDOW_X), 50 );
255    tr_bencDictAddInt( d, keyStr(MAIN_WINDOW_Y), 50 );
256    tr_bencDictAddStr( d, keyStr(FILTER_MODE), "all" );
257    tr_bencDictAddStr( d, keyStr(MAIN_WINDOW_LAYOUT_ORDER), "menu,toolbar,filter,list,statusbar" );
258    tr_bencDictAddStr( d, keyStr(DOWNLOAD_DIR), tr_getDefaultDownloadDir( ) );
259    tr_bencDictAddInt( d, keyStr(ASKQUIT), true );
260    tr_bencDictAddStr( d, keyStr(SORT_MODE), "sort-by-name" );
261    tr_bencDictAddInt( d, keyStr(SORT_REVERSED), false );
262    tr_bencDictAddInt( d, keyStr(MINIMAL_VIEW), false );
263    tr_bencDictAddInt( d, keyStr(START), true );
264    tr_bencDictAddInt( d, keyStr(TRASH_ORIGINAL), false );
265    tr_bencDictAddStr( d, keyStr(SESSION_REMOTE_HOST), "localhost" );
266    tr_bencDictAddInt( d, keyStr(SESSION_REMOTE_PORT), atoi(TR_DEFAULT_RPC_PORT_STR) );
267    tr_bencDictAddBool( d, keyStr(SESSION_IS_REMOTE), false );
268    tr_bencDictAddBool( d, keyStr(SESSION_REMOTE_AUTH), false );
269}
270
271/***
272****
273***/
274
275bool
276Prefs :: getBool( int key ) const
277{
278    assert( myItems[key].type == QVariant::Bool );
279    return myValues[key].toBool( );
280}
281
282QString
283Prefs :: getString( int key ) const
284{
285    assert( myItems[key].type == QVariant::String );
286    return myValues[key].toString( );
287}
288
289int
290Prefs :: getInt( int key ) const
291{
292    assert( myItems[key].type == QVariant::Int );
293    return myValues[key].toInt( );
294}
295
296double
297Prefs :: getDouble( int key ) const
298{
299    assert( myItems[key].type == QVariant::Double );
300    return myValues[key].toDouble( );
301}
302
303QDateTime
304Prefs :: getDateTime( int key ) const
305{
306    assert( myItems[key].type == QVariant::DateTime );
307    return myValues[key].toDateTime( );
308}
309
310/***
311****
312***/
313
314void
315Prefs :: toggleBool( int key )
316{
317    set( key, !getBool( key ) );
318}
Note: See TracBrowser for help on using the repository browser.