MuleTrayIcon: show MB/s instead kB/s
[amule.git] / src / Preferences.cpp
blob46ef640dbe92019e4ee11ff10ee76b17be3bbef1
1 //
2 // This file is part of the aMule Project.
3 //
4 // Copyright (c) 2003-2011 aMule Team ( admin@amule.org / http://www.amule.org )
5 // Copyright (c) 2002-2011 Merkur ( devs@emule-project.net / http://www.emule-project.net )
6 //
7 // Any parts of this program derived from the xMule, lMule or eMule project,
8 // or contributed by third-party developers are copyrighted by their
9 // respective authors.
11 // This program is free software; you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation; either version 2 of the License, or
14 // (at your option) any later version.
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU General Public License for more details.
21 // You should have received a copy of the GNU General Public License
22 // along with this program; if not, write to the Free Software
23 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26 #include <wx/wx.h>
27 #include "Preferences.h"
29 #include <protocol/ed2k/Constants.h>
30 #include <common/Constants.h>
31 #include <common/DataFileVersion.h>
33 #include <wx/config.h>
34 #include <wx/dir.h>
35 #include <wx/stdpaths.h>
36 #include <wx/stopwatch.h>
37 #include <wx/tokenzr.h>
38 #include <wx/utils.h> // Needed for wxBusyCursor
40 #include "amule.h"
41 #ifdef HAVE_CONFIG_H
42 #include "config.h" // Needed for PACKAGE_STRING
43 #endif
45 #include "CFile.h"
46 #include <common/MD5Sum.h>
47 #include "Logger.h"
48 #include <common/Format.h> // Needed for CFormat
49 #include <common/TextFile.h> // Needed for CTextFile
50 #include <common/ClientVersion.h>
52 #include "UserEvents.h"
54 #ifndef AMULE_DAEMON
55 #include <wx/valgen.h>
56 #include "muuli_wdr.h"
57 #include "StatisticsDlg.h"
58 #include "MuleColour.h"
59 #endif
61 #ifndef CLIENT_GUI
62 #include "RandomFunctions.h"
63 #include "PlatformSpecific.h" // Needed for PlatformSpecific::GetMaxConnections()
64 #include "SharedFileList.h" // Needed for theApp->sharedfiles->Reload()
65 #endif
67 // Needed for IP filtering prefs
68 #include "ClientList.h"
69 #include "ServerList.h"
70 #include "GuiEvents.h"
72 #define DEFAULT_TCP_PORT 4662
73 #define DEFAULT_UDP_PORT 4672
75 // Static variables
76 unsigned long CPreferences::s_colors[cntStatColors];
77 unsigned long CPreferences::s_colors_ref[cntStatColors];
79 CPreferences::CFGMap CPreferences::s_CfgList;
80 CPreferences::CFGList CPreferences::s_MiscList;
82 wxString CPreferences::s_configDir;
84 /* Proxy */
85 CProxyData CPreferences::s_ProxyData;
87 /* The rest, organize it! */
88 wxString CPreferences::s_nick;
89 Cfg_Lang_Base * CPreferences::s_cfgLang;
90 uint16 CPreferences::s_maxupload;
91 uint16 CPreferences::s_maxdownload;
92 uint16 CPreferences::s_slotallocation;
93 wxString CPreferences::s_Addr;
94 uint16 CPreferences::s_port;
95 uint16 CPreferences::s_udpport;
96 bool CPreferences::s_UDPEnable;
97 uint16 CPreferences::s_maxconnections;
98 bool CPreferences::s_reconnect;
99 bool CPreferences::s_autoconnect;
100 bool CPreferences::s_autoconnectstaticonly;
101 bool CPreferences::s_UPnPEnabled;
102 bool CPreferences::s_UPnPECEnabled;
103 bool CPreferences::s_UPnPWebServerEnabled;
104 uint16 CPreferences::s_UPnPTCPPort;
105 bool CPreferences::s_autoserverlist;
106 bool CPreferences::s_deadserver;
107 CPath CPreferences::s_incomingdir;
108 CPath CPreferences::s_tempdir;
109 bool CPreferences::s_ICH;
110 uint8 CPreferences::s_depth3D;
111 bool CPreferences::s_scorsystem;
112 bool CPreferences::s_hideonclose;
113 bool CPreferences::s_mintotray;
114 bool CPreferences::s_notify;
115 bool CPreferences::s_trayiconenabled;
116 bool CPreferences::s_addnewfilespaused;
117 bool CPreferences::s_addserversfromserver;
118 bool CPreferences::s_addserversfromclient;
119 uint16 CPreferences::s_maxsourceperfile;
120 uint16 CPreferences::s_trafficOMeterInterval;
121 uint16 CPreferences::s_statsInterval;
122 uint32 CPreferences::s_maxGraphDownloadRate;
123 uint32 CPreferences::s_maxGraphUploadRate;
124 bool CPreferences::s_confirmExit;
125 bool CPreferences::s_filterLanIP;
126 bool CPreferences::s_paranoidfilter;
127 bool CPreferences::s_IPFilterSys;
128 bool CPreferences::s_onlineSig;
129 uint16 CPreferences::s_OSUpdate;
130 wxString CPreferences::s_languageID;
131 uint8 CPreferences::s_iSeeShares;
132 uint8 CPreferences::s_iToolDelayTime;
133 uint8 CPreferences::s_splitterbarPosition;
134 uint16 CPreferences::s_deadserverretries;
135 uint32 CPreferences::s_dwServerKeepAliveTimeoutMins;
136 uint8 CPreferences::s_statsMax;
137 uint8 CPreferences::s_statsAverageMinutes;
138 bool CPreferences::s_bpreviewprio;
139 bool CPreferences::s_smartidcheck;
140 uint8 CPreferences::s_smartidstate;
141 bool CPreferences::s_safeServerConnect;
142 bool CPreferences::s_startMinimized;
143 uint16 CPreferences::s_MaxConperFive;
144 bool CPreferences::s_checkDiskspace;
145 uint32 CPreferences::s_uMinFreeDiskSpace;
146 wxString CPreferences::s_yourHostname;
147 bool CPreferences::s_bVerbose;
148 bool CPreferences::s_bVerboseLogfile;
149 bool CPreferences::s_bmanualhighprio;
150 bool CPreferences::s_bstartnextfile;
151 bool CPreferences::s_bstartnextfilesame;
152 bool CPreferences::s_bstartnextfilealpha;
153 bool CPreferences::s_bshowoverhead;
154 bool CPreferences::s_bDAP;
155 bool CPreferences::s_bUAP;
156 #ifndef __SVN__
157 bool CPreferences::s_showVersionOnTitle;
158 #endif
159 uint8_t CPreferences::s_showRatesOnTitle;
160 wxString CPreferences::s_VideoPlayer;
161 bool CPreferences::s_showAllNotCats;
162 bool CPreferences::s_msgonlyfriends;
163 bool CPreferences::s_msgsecure;
164 uint8 CPreferences::s_filterlevel;
165 uint8 CPreferences::s_iFileBufferSize;
166 uint8 CPreferences::s_iQueueSize;
167 wxString CPreferences::s_datetimeformat;
168 wxString CPreferences::s_sWebPath;
169 wxString CPreferences::s_sWebPassword;
170 wxString CPreferences::s_sWebLowPassword;
171 uint16 CPreferences::s_nWebPort;
172 uint16 CPreferences::s_nWebUPnPTCPPort;
173 bool CPreferences::s_bWebEnabled;
174 bool CPreferences::s_bWebUseGzip;
175 uint32 CPreferences::s_nWebPageRefresh;
176 bool CPreferences::s_bWebLowEnabled;
177 wxString CPreferences::s_WebTemplate;
178 bool CPreferences::s_showCatTabInfos;
179 AllCategoryFilter CPreferences::s_allcatFilter;
180 bool CPreferences::s_AcceptExternalConnections;
181 wxString CPreferences::s_ECAddr;
182 uint32 CPreferences::s_ECPort;
183 wxString CPreferences::s_ECPassword;
184 bool CPreferences::s_TransmitOnlyUploadingClients;
185 bool CPreferences::s_IPFilterClients;
186 bool CPreferences::s_IPFilterServers;
187 bool CPreferences::s_UseSrcSeeds;
188 bool CPreferences::s_ProgBar;
189 bool CPreferences::s_Percent;
190 bool CPreferences::s_SecIdent;
191 bool CPreferences::s_ExtractMetaData;
192 bool CPreferences::s_allocFullFile;
193 bool CPreferences::s_createFilesSparse;
194 wxString CPreferences::s_CustomBrowser;
195 bool CPreferences::s_BrowserTab;
196 CPath CPreferences::s_OSDirectory;
197 wxString CPreferences::s_Skin;
198 bool CPreferences::s_FastED2KLinksHandler;
199 bool CPreferences::s_ToolbarOrientation;
200 bool CPreferences::s_AICHTrustEveryHash;
201 wxString CPreferences::s_CommentFilterString;
202 bool CPreferences::s_IPFilterAutoLoad;
203 wxString CPreferences::s_IPFilterURL;
204 CMD4Hash CPreferences::s_userhash;
205 bool CPreferences::s_MustFilterMessages;
206 wxString CPreferences::s_MessageFilterString;
207 bool CPreferences::s_FilterAllMessages;
208 bool CPreferences::s_FilterComments;
209 bool CPreferences::s_FilterSomeMessages;
210 bool CPreferences::s_ShowMessagesInLog;
211 bool CPreferences::s_IsAdvancedSpamfilterEnabled;
212 bool CPreferences::s_IsChatCaptchaEnabled;
213 bool CPreferences::s_ShareHiddenFiles;
214 bool CPreferences::s_AutoSortDownload;
215 bool CPreferences::s_NewVersionCheck;
216 bool CPreferences::s_ConnectToKad;
217 bool CPreferences::s_ConnectToED2K;
218 unsigned CPreferences::s_maxClientVersions;
219 bool CPreferences::s_DropSlowSources;
220 bool CPreferences::s_IsClientCryptLayerSupported;
221 bool CPreferences::s_bCryptLayerRequested;
222 bool CPreferences::s_IsClientCryptLayerRequired;
223 uint32 CPreferences::s_dwKadUDPKey;
224 uint8 CPreferences::s_byCryptTCPPaddingLength;
226 wxString CPreferences::s_Ed2kURL;
227 wxString CPreferences::s_KadURL;
228 bool CPreferences::s_GeoIPEnabled;
229 wxString CPreferences::s_GeoIPUpdateUrl;
230 bool CPreferences::s_preventSleepWhileDownloading;
231 wxString CPreferences::s_StatsServerName;
232 wxString CPreferences::s_StatsServerURL;
235 * Template Cfg class for connecting with widgets.
237 * This template provides the base functionionality needed to syncronize a
238 * variable with a widget. However, please note that wxGenericValidator only
239 * supports a few types (int, wxString, bool and wxArrayInt), so this template
240 * can't always be used directly.
242 * Cfg_Str and Cfg_Bool are able to use this template directly, whereas Cfg_Int
243 * makes use of serveral workaround to enable it to be used with integers other
244 * than int.
246 template <typename TYPE>
247 class Cfg_Tmpl : public Cfg_Base
249 public:
251 * Constructor.
253 * @param keyname
254 * @param value
255 * @param defaultVal
257 Cfg_Tmpl( const wxString& keyname, TYPE& value, const TYPE& defaultVal )
258 : Cfg_Base( keyname ),
259 m_value( value ),
260 m_default( defaultVal ),
261 m_widget( NULL )
264 #ifndef AMULE_DAEMON
266 * Connects the Cfg to a widget.
268 * @param id The ID of the widget to be connected.
269 * @param parent The parent of the widget. Use this to speed up searches.
271 * This function works by setting the wxValidator of the class. This however
272 * poses some restrictions on which variable types can be used for this
273 * template, as noted above. It also poses some limits on the widget types,
274 * refer to the wx documentation for those.
276 virtual bool ConnectToWidget( int id, wxWindow* parent = NULL )
278 if ( id ) {
279 m_widget = wxWindow::FindWindowById( id, parent );
281 if ( m_widget ) {
282 wxGenericValidator validator( &m_value );
284 m_widget->SetValidator( validator );
286 return true;
288 } else {
289 m_widget = NULL;
292 return false;
296 /** Updates the assosiated variable, returning true on success. */
297 virtual bool TransferFromWindow()
299 if ( m_widget ) {
300 wxValidator* validator = m_widget->GetValidator();
302 if ( validator ) {
303 TYPE temp = m_value;
305 if ( validator->TransferFromWindow() ) {
306 SetChanged( temp != m_value );
308 return true;
313 return false;
316 /** Updates the assosiated widget, returning true on success. */
317 virtual bool TransferToWindow()
319 if ( m_widget ) {
320 wxValidator* validator = m_widget->GetValidator();
322 if ( validator )
323 return validator->TransferToWindow();
326 return false;
329 #endif
331 /** Sets the default value. */
332 void SetDefault(const TYPE& defaultVal)
334 m_default = defaultVal;
337 protected:
338 //! Reference to the associated variable
339 TYPE& m_value;
341 //! Default variable value
342 TYPE m_default;
344 //! Pointer to the widget assigned to the Cfg instance
345 wxWindow* m_widget;
349 /** Cfg class for wxStrings. */
350 class Cfg_Str : public Cfg_Tmpl<wxString>
352 public:
353 /** Constructor. */
354 Cfg_Str( const wxString& keyname, wxString& value, const wxString& defaultVal = EmptyString )
355 : Cfg_Tmpl<wxString>( keyname, value, defaultVal )
358 /** Loads the string, using the specified default value. */
359 virtual void LoadFromFile(wxConfigBase* cfg)
361 cfg->Read( GetKey(), &m_value, m_default );
365 /** Saves the string to the specified wxConfig object. */
366 virtual void SaveToFile(wxConfigBase* cfg)
368 cfg->Write( GetKey(), m_value );
374 * Cfg-class for encrypting strings, for example for passwords.
376 class Cfg_Str_Encrypted : public Cfg_Str
378 public:
379 Cfg_Str_Encrypted( const wxString& keyname, wxString& value, const wxString& defaultVal = EmptyString )
380 : Cfg_Str( keyname, value, defaultVal )
383 #ifndef AMULE_DAEMON
384 virtual bool TransferFromWindow()
386 // Shakraw: when storing value, store it encrypted here (only if changed in prefs)
387 if ( Cfg_Str::TransferFromWindow() ) {
389 // Only recalucate the hash for new, non-empty passwords
390 if ( HasChanged() && !m_value.IsEmpty() ) {
391 m_value = MD5Sum( m_value ).GetHash();
394 return true;
398 return false;
400 #endif
404 /** Cfg class for CPath. */
405 class Cfg_Path : public Cfg_Str
407 public:
408 /** Constructor. */
409 Cfg_Path(const wxString& keyname, CPath& value, const wxString& defaultVal = EmptyString )
410 : Cfg_Str(keyname, m_temp_path, defaultVal)
411 , m_real_path(value)
414 /** @see Cfg_Str::LoadFromFile. */
415 virtual void LoadFromFile(wxConfigBase* cfg)
417 Cfg_Str::LoadFromFile(cfg);
419 m_real_path = CPath::FromUniv(m_temp_path);
423 /** @see Cfg_Str::SaveToFile. */
424 virtual void SaveToFile(wxConfigBase* cfg)
426 m_temp_path = CPath::ToUniv(m_real_path);
428 Cfg_Str::SaveToFile(cfg);
432 /** @see Cfg_Tmpl::TransferToWindow. */
433 virtual bool TransferToWindow()
435 m_temp_path = m_real_path.GetRaw();
437 return Cfg_Str::TransferToWindow();
440 /** @see Cfg_Tmpl::TransferFromWindow. */
441 virtual bool TransferFromWindow()
443 if (Cfg_Str::TransferFromWindow()) {
444 m_real_path = CPath(m_temp_path);
445 return true;
448 return false;
451 private:
452 wxString m_temp_path;
453 CPath& m_real_path;
458 * Cfg class that takes care of integer types.
460 * This template is needed since wxValidator only supports normals ints, and
461 * wxConfig for the matter only supports longs, thus some worksarounds are
462 * needed.
464 * There are two work-arounds:
465 * 1) wxValidator only supports int*, so we need a immediate variable to act
466 * as a storage. Thus we use Cfg_Tmpl<int> as base class. Thus this class
467 * contains a integer which we use to pass the value back and forth
468 * between the widgets.
470 * 2) wxConfig uses longs to save and read values, thus we need an immediate
471 * stage when loading and saving the value.
473 template <typename TYPE>
474 class Cfg_Int : public Cfg_Tmpl<int>
476 public:
477 Cfg_Int( const wxString& keyname, TYPE& value, int defaultVal = 0 )
478 : Cfg_Tmpl<int>( keyname, m_temp_value, defaultVal ),
479 m_real_value( value ),
480 m_temp_value( value )
484 virtual void LoadFromFile(wxConfigBase* cfg)
486 long tmp = 0;
487 cfg->Read( GetKey(), &tmp, m_default );
489 // Set the temp value
490 m_temp_value = (int)tmp;
491 // Set the actual value
492 m_real_value = (TYPE)tmp;
495 virtual void SaveToFile(wxConfigBase* cfg)
497 cfg->Write( GetKey(), (long)m_real_value );
501 #ifndef AMULE_DAEMON
502 virtual bool TransferFromWindow()
504 if ( Cfg_Tmpl<int>::TransferFromWindow() ) {
505 m_real_value = (TYPE)m_temp_value;
507 return true;
510 return false;
513 virtual bool TransferToWindow()
515 m_temp_value = (int)m_real_value;
517 if ( Cfg_Tmpl<int>::TransferToWindow() ) {
519 // In order to let us update labels on slider-changes, we trigger a event
520 wxSlider *slider = dynamic_cast<wxSlider *>(m_widget);
521 if (slider) {
522 int id = m_widget->GetId();
523 int pos = slider->GetValue();
524 wxScrollEvent evt( wxEVT_SCROLL_THUMBRELEASE, id, pos );
525 m_widget->GetEventHandler()->ProcessEvent( evt );
528 return true;
531 return false;
533 #endif
535 protected:
537 TYPE& m_real_value;
538 int m_temp_value;
543 * Helper function for creating new Cfg_Ints.
545 * @param keyname The cfg-key under which the item should be saved.
546 * @param value The variable to syncronize. The type of this variable defines the type used to create the Cfg_Int.
547 * @param defaultVal The default value if the key isn't found when loading the value.
548 * @return A pointer to the new Cfg_Int object. The caller is responsible for deleting it.
550 * This template-function returns a Cfg_Int of the appropriate type for the
551 * variable used as argument and should be used to avoid having to specify
552 * the integer type when adding a new Cfg_Int, since that's just increases
553 * the maintainence burden.
555 template <class TYPE>
556 Cfg_Base* MkCfg_Int( const wxString& keyname, TYPE& value, int defaultVal )
558 return new Cfg_Int<TYPE>( keyname, value, defaultVal );
563 * Cfg-class for bools.
565 class Cfg_Bool : public Cfg_Tmpl<bool>
567 public:
568 Cfg_Bool( const wxString& keyname, bool& value, bool defaultVal )
569 : Cfg_Tmpl<bool>( keyname, value, defaultVal )
573 virtual void LoadFromFile(wxConfigBase* cfg)
575 cfg->Read( GetKey(), &m_value, m_default );
578 virtual void SaveToFile(wxConfigBase* cfg)
580 cfg->Write( GetKey(), m_value );
585 #ifndef AMULE_DAEMON
587 class Cfg_Colour : public Cfg_Base
589 public:
590 Cfg_Colour(const wxString& key, wxColour& colour)
591 : Cfg_Base(key),
592 m_colour(colour),
593 m_default(CMuleColour(colour).GetULong())
596 virtual void LoadFromFile(wxConfigBase* cfg)
598 long int rgb;
599 cfg->Read(GetKey(), &rgb, m_default);
600 m_colour.Set(rgb);
603 virtual void SaveToFile(wxConfigBase* cfg)
605 cfg->Write(GetKey(), static_cast<long int>(CMuleColour(m_colour).GetULong()));
608 private:
609 wxColour& m_colour;
610 long int m_default;
614 typedef struct {
615 int id;
616 bool available;
617 wxString displayname;
618 wxString name;
619 } LangInfo;
623 * The languages aMule has translation for.
625 * Add new languages here.
626 * Then activate the test code in Cfg_Lang::UpdateChoice below!
628 static LangInfo aMuleLanguages[] = {
629 { wxLANGUAGE_DEFAULT, true, wxEmptyString, wxTRANSLATE("System default") },
630 { wxLANGUAGE_ALBANIAN, false, wxEmptyString, wxTRANSLATE("Albanian") },
631 { wxLANGUAGE_ARABIC, false, wxEmptyString, wxTRANSLATE("Arabic") },
632 { wxLANGUAGE_ASTURIAN, false, wxEmptyString, wxTRANSLATE("Asturian") },
633 { wxLANGUAGE_BASQUE, false, wxEmptyString, wxTRANSLATE("Basque") },
634 { wxLANGUAGE_BULGARIAN, false, wxEmptyString, wxTRANSLATE("Bulgarian") },
635 { wxLANGUAGE_CATALAN, false, wxEmptyString, wxTRANSLATE("Catalan") },
636 { wxLANGUAGE_CHINESE_SIMPLIFIED, false, wxEmptyString, wxTRANSLATE("Chinese (Simplified)") },
637 { wxLANGUAGE_CHINESE_TRADITIONAL, false, wxEmptyString, wxTRANSLATE("Chinese (Traditional)") },
638 { wxLANGUAGE_CROATIAN, false, wxEmptyString, wxTRANSLATE("Croatian") },
639 { wxLANGUAGE_CZECH, false, wxEmptyString, wxTRANSLATE("Czech") },
640 { wxLANGUAGE_DANISH, false, wxEmptyString, wxTRANSLATE("Danish") },
641 { wxLANGUAGE_DUTCH, false, wxEmptyString, wxTRANSLATE("Dutch") },
642 { wxLANGUAGE_ENGLISH, false, wxEmptyString, wxTRANSLATE("English (U.K.)") },
643 { wxLANGUAGE_ESTONIAN, false, wxEmptyString, wxTRANSLATE("Estonian") },
644 { wxLANGUAGE_FINNISH, false, wxEmptyString, wxTRANSLATE("Finnish") },
645 { wxLANGUAGE_FRENCH, false, wxEmptyString, wxTRANSLATE("French") },
646 { wxLANGUAGE_GALICIAN, false, wxEmptyString, wxTRANSLATE("Galician") },
647 { wxLANGUAGE_GERMAN, false, wxEmptyString, wxTRANSLATE("German") },
648 { wxLANGUAGE_GREEK, false, wxEmptyString, wxTRANSLATE("Greek") },
649 { wxLANGUAGE_HEBREW, false, wxEmptyString, wxTRANSLATE("Hebrew") },
650 { wxLANGUAGE_HUNGARIAN, false, wxEmptyString, wxTRANSLATE("Hungarian") },
651 { wxLANGUAGE_ITALIAN, false, wxEmptyString, wxTRANSLATE("Italian") },
652 { wxLANGUAGE_ITALIAN_SWISS, false, wxEmptyString, wxTRANSLATE("Italian (Swiss)") },
653 { wxLANGUAGE_JAPANESE, false, wxEmptyString, wxTRANSLATE("Japanese") },
654 { wxLANGUAGE_KOREAN, false, wxEmptyString, wxTRANSLATE("Korean") },
655 { wxLANGUAGE_LITHUANIAN, false, wxEmptyString, wxTRANSLATE("Lithuanian") },
656 { wxLANGUAGE_NORWEGIAN_NYNORSK, false, wxEmptyString, wxTRANSLATE("Norwegian (Nynorsk)") },
657 { wxLANGUAGE_POLISH, false, wxEmptyString, wxTRANSLATE("Polish") },
658 { wxLANGUAGE_PORTUGUESE, false, wxEmptyString, wxTRANSLATE("Portuguese") },
659 { wxLANGUAGE_PORTUGUESE_BRAZILIAN, false, wxEmptyString, wxTRANSLATE("Portuguese (Brazilian)") },
660 { wxLANGUAGE_ROMANIAN, false, wxEmptyString, wxTRANSLATE("Romanian") },
661 { wxLANGUAGE_RUSSIAN, false, wxEmptyString, wxTRANSLATE("Russian") },
662 { wxLANGUAGE_SLOVENIAN, false, wxEmptyString, wxTRANSLATE("Slovenian") },
663 { wxLANGUAGE_SPANISH, false, wxEmptyString, wxTRANSLATE("Spanish") },
664 { wxLANGUAGE_SWEDISH, false, wxEmptyString, wxTRANSLATE("Swedish") },
665 { wxLANGUAGE_TURKISH, false, wxEmptyString, wxTRANSLATE("Turkish") },
666 { wxLANGUAGE_UKRAINIAN, false, wxEmptyString, wxTRANSLATE("Ukrainian") },
670 typedef Cfg_Int<int> Cfg_PureInt;
672 class Cfg_Lang : public Cfg_PureInt, public Cfg_Lang_Base
674 public:
675 // cppcheck-suppress uninitMemberVar m_selection, m_langSelector
676 Cfg_Lang()
677 : Cfg_PureInt( wxEmptyString, m_selection, 0 )
679 m_languagesReady = false;
680 m_changePos = 0;
683 virtual void LoadFromFile(wxConfigBase* WXUNUSED(cfg)) {}
684 virtual void SaveToFile(wxConfigBase* WXUNUSED(cfg)) {}
687 virtual bool TransferFromWindow()
689 if (!m_languagesReady) {
690 return true; // nothing changed, no problem
693 if ( Cfg_PureInt::TransferFromWindow() ) {
694 // find wx ID of selected language
695 int i = 0;
696 while (m_selection > 0) {
697 i++;
698 if (aMuleLanguages[i].available) {
699 m_selection--;
702 int id = aMuleLanguages[i].id;
704 // save language selection
705 thePrefs::SetLanguageID(wxLang2Str(id));
707 return true;
710 return false;
714 virtual bool TransferToWindow()
716 m_langSelector = dynamic_cast<wxChoice*>(m_widget); // doesn't work in ctor!
717 if (m_languagesReady) {
718 FillChoice();
719 } else {
720 int wxId = StrLang2wx(thePrefs::GetLanguageID());
721 m_langSelector->Clear();
722 m_selection = 0;
723 for (uint32 i = 0; i < itemsof(aMuleLanguages); i++) {
724 if ( aMuleLanguages[i].id == wxId ) {
725 m_langSelector->Append(wxString(wxGetTranslation(aMuleLanguages[i].name)) + wxT(" [") + aMuleLanguages[i].name + wxT("]"));
726 break;
729 m_langSelector->Append(_("Change Language"));
730 m_changePos = m_langSelector->GetCount() - 1;
733 return Cfg_PureInt::TransferToWindow();
736 virtual void UpdateChoice(int pos)
738 if (!m_languagesReady && pos == m_changePos) {
739 // Find available languages and translate them.
740 // This is only done when the user selects "Change Language"
741 // Language is changed rarely, and the go-through-all locales takes a considerable
742 // time when the settings dialog is opened for the first time.
743 wxBusyCursor busyCursor;
744 aMuleLanguages[0].displayname = wxGetTranslation(aMuleLanguages[0].name);
746 // This supresses error-messages about invalid locales
747 for (unsigned int i = 1; i < itemsof(aMuleLanguages); ++i) {
748 if ((aMuleLanguages[i].id > wxLANGUAGE_USER_DEFINED) || wxLocale::IsAvailable(aMuleLanguages[i].id)) {
749 wxLogNull logTarget;
750 wxLocale locale_to_check;
751 InitLocale(locale_to_check, aMuleLanguages[i].id);
752 if (locale_to_check.IsOk() && locale_to_check.IsLoaded(wxT(PACKAGE))) {
753 aMuleLanguages[i].displayname = wxString(wxGetTranslation(aMuleLanguages[i].name)) + wxT(" [") + aMuleLanguages[i].name + wxT("]");
754 aMuleLanguages[i].available = true;
755 #if 0
756 // Check for language problems
757 // Activate this code temporarily after messing with the languages!
758 int wxid = StrLang2wx(wxLang2Str(aMuleLanguages[i].id));
759 if (wxid != aMuleLanguages[i].id) {
760 AddDebugLogLineN(logGeneral, CFormat(wxT("Language problem for %s : aMule id %d != wx id %d"))
761 % aMuleLanguages[i].name % aMuleLanguages[i].id % wxid);
763 #endif
767 // Restore original locale
768 wxLocale tmpLocale;
769 InitLocale(tmpLocale, theApp->m_locale.GetLanguage());
770 FillChoice();
771 if (m_langSelector->GetCount() == 1) {
772 wxMessageBox(_("There are no translations installed for aMule"), _("No languages available"), wxICON_INFORMATION | wxOK);
774 m_langSelector->SetSelection(m_selection);
775 m_languagesReady = true;
779 protected:
780 int m_selection;
782 private:
783 void FillChoice()
785 int wxId = StrLang2wx(thePrefs::GetLanguageID());
786 m_langSelector->Clear();
787 // Add all available languages and find the index of the selected language.
788 for ( unsigned int i = 0, j = 0; i < itemsof(aMuleLanguages); i++) {
789 if (aMuleLanguages[i].available) {
790 m_langSelector->Append(aMuleLanguages[i].displayname);
791 if ( aMuleLanguages[i].id == wxId ) {
792 m_selection = j;
794 j++;
799 bool m_languagesReady; // true: all translations calculated
800 int m_changePos;
801 wxChoice * m_langSelector;
804 #endif /* ! AMULE_DAEMON */
806 void Cfg_Lang_Base::UpdateChoice(int) {} // dummy
808 class Cfg_Skin : public Cfg_Str
810 public:
811 Cfg_Skin( const wxString& keyname, wxString& value, const wxString& defaultVal = EmptyString )
812 : Cfg_Str( keyname, value, defaultVal ),
813 m_is_skin(false)
816 #ifndef AMULE_DAEMON
817 virtual bool TransferFromWindow()
819 if ( Cfg_Str::TransferFromWindow() ) {
820 if (m_is_skin) {
821 wxChoice *skinSelector = dynamic_cast<wxChoice*>(m_widget);
822 // "- default -" is always the first
823 if (skinSelector->GetSelection() == 0) {
824 m_value.Clear();
827 return true;
830 return false;
834 virtual bool TransferToWindow()
837 wxChoice *skinSelector = dynamic_cast<wxChoice*>(m_widget);
838 skinSelector->Clear();
840 wxString folder;
841 int flags = wxDIR_DIRS;
842 wxString filespec;
843 wxString defaultSelection = _("- default -");
844 //#warning there has to be a better way...
845 if ( GetKey() == wxT("/SkinGUIOptions/Skin") ) {
846 folder = wxT("skins");
847 m_is_skin = true;
848 flags = wxDIR_FILES;
849 filespec = wxT("*.zip");
850 skinSelector->Append(defaultSelection);
851 } else {
852 folder = wxT("webserver");
854 wxString dirName(JoinPaths(thePrefs::GetConfigDir(), folder));
855 wxString Filename;
856 wxDir d;
858 if (wxDir::Exists(dirName) &&
859 d.Open(dirName) &&
860 d.GetFirst(& Filename, filespec, flags)
865 if (m_is_skin) {
866 Filename = wxT("User:") + Filename;
868 skinSelector->Append(Filename);
870 while (d.GetNext(&Filename));
873 wxString dataDir;
874 if (m_is_skin) {
875 dataDir = wxStandardPaths::Get().GetDataDir();
876 } else {
877 dataDir = wxStandardPaths::Get().GetResourcesDir();
879 #if !defined(__WINDOWS__) && !defined(__WXMAC__)
880 dataDir = dataDir.BeforeLast(wxT('/')) + wxT("/amule");
881 #endif
882 wxString systemDir(JoinPaths(dataDir,folder));
884 if (wxDir::Exists(systemDir) &&
885 d.Open(systemDir) &&
886 d.GetFirst(& Filename, filespec, flags)
891 if (m_is_skin) {
892 Filename = wxT("System:") + Filename;
894 // avoid duplicates for webserver templates
895 if (skinSelector->FindString(Filename) == wxNOT_FOUND) {
896 skinSelector->Append(Filename);
899 while (d.GetNext(&Filename));
902 if ( skinSelector->GetCount() == 0 ) {
903 skinSelector->Append(_("no options available"));
906 int id = skinSelector->FindString(m_value);
907 if ( id == wxNOT_FOUND ) {
908 id = 0;
909 if (m_is_skin) {
910 m_value = defaultSelection;
913 skinSelector->SetSelection(id);
915 return Cfg_Str::TransferToWindow();
917 #endif /* ! AMULE_DAEMON */
919 protected:
920 bool m_is_skin;
924 /// new implementation
925 CPreferences::CPreferences()
927 srand( wxGetLocalTimeMillis().GetLo() ); // we need random numbers sometimes
929 // load preferences.dat or set standard values
930 wxString fullpath(s_configDir + wxT("preferences.dat"));
931 CFile preffile;
932 if (wxFileExists(fullpath)) {
933 if (preffile.Open(fullpath, CFile::read)) {
934 try {
935 preffile.ReadUInt8(); // Version. Value is not used.
936 s_userhash = preffile.ReadHash();
937 } catch (const CSafeIOException& e) {
938 AddDebugLogLineC(logGeneral,
939 wxT("Error while reading userhash: ") + e.what());
944 if (s_userhash.IsEmpty()) {
945 for (int i = 0; i < 8; i++) {
946 RawPokeUInt16(s_userhash.GetHash() + (i * 2), rand());
949 Save();
952 // Mark hash as an eMule-type hash
953 // See also CUpDownClient::GetHashType
954 s_userhash[5] = 14;
955 s_userhash[14] = 111;
957 #ifndef CLIENT_GUI
958 LoadPreferences();
959 ReloadSharedFolders();
961 // serverlist adresses
962 CTextFile slistfile;
963 if (slistfile.Open(s_configDir + wxT("addresses.dat"), CTextFile::read)) {
964 adresses_list = slistfile.ReadLines();
966 #endif
970 // Gets called at init time
972 void CPreferences::BuildItemList( const wxString& appdir )
974 #ifndef AMULE_DAEMON
975 #define NewCfgItem(ID, COMMAND) s_CfgList[ID] = COMMAND
976 #else
977 int current_id = 0;
978 #define NewCfgItem(ID, COMMAND) s_CfgList[++current_id] = COMMAND
979 #endif /* AMULE_DAEMON */
982 * User settings
984 NewCfgItem(IDC_NICK, (new Cfg_Str( wxT("/eMule/Nick"), s_nick, wxT("http://www.aMule.org") )));
985 #ifndef AMULE_DAEMON
986 Cfg_Lang * cfgLang = new Cfg_Lang();
987 s_cfgLang = cfgLang;
988 NewCfgItem(IDC_LANGUAGE, cfgLang);
989 #endif
992 * Browser options
994 #ifdef __WXMAC__
995 wxString customBrowser = wxT("/usr/bin/open");
996 #else
997 wxString customBrowser; // left empty
998 #endif
1000 NewCfgItem(IDC_BROWSERTABS, (new Cfg_Bool( wxT("/Browser/OpenPageInTab"), s_BrowserTab, true )));
1001 NewCfgItem(IDC_BROWSERSELF, (new Cfg_Str( wxT("/Browser/CustomBrowserString"), s_CustomBrowser, customBrowser )));
1005 * Misc
1007 NewCfgItem(IDC_QUEUESIZE, (MkCfg_Int( wxT("/eMule/QueueSizePref"), s_iQueueSize, 50 )));
1010 #ifdef __DEBUG__
1012 * Debugging
1014 NewCfgItem(ID_VERBOSEDEBUG, (new Cfg_Bool( wxT("/eMule/VerboseDebug"), s_bVerbose, false )));
1015 NewCfgItem(ID_VERBOSEDEBUGLOGFILE, (new Cfg_Bool( wxT("/eMule/VerboseDebugLogfile"), s_bVerboseLogfile, false )));
1016 #endif
1019 * Connection settings
1021 NewCfgItem(IDC_MAXUP, (MkCfg_Int( wxT("/eMule/MaxUpload"), s_maxupload, 0 )));
1022 NewCfgItem(IDC_MAXDOWN, (MkCfg_Int( wxT("/eMule/MaxDownload"), s_maxdownload, 0 )));
1023 NewCfgItem(IDC_SLOTALLOC, (MkCfg_Int( wxT("/eMule/SlotAllocation"), s_slotallocation, 2 )));
1024 NewCfgItem(IDC_PORT, (MkCfg_Int( wxT("/eMule/Port"), s_port, DEFAULT_TCP_PORT )));
1025 NewCfgItem(IDC_UDPPORT, (MkCfg_Int( wxT("/eMule/UDPPort"), s_udpport, DEFAULT_UDP_PORT )));
1026 NewCfgItem(IDC_UDPENABLE, (new Cfg_Bool( wxT("/eMule/UDPEnable"), s_UDPEnable, true )));
1027 NewCfgItem(IDC_ADDRESS, (new Cfg_Str( wxT("/eMule/Address"), s_Addr, wxEmptyString)));
1028 NewCfgItem(IDC_AUTOCONNECT, (new Cfg_Bool( wxT("/eMule/Autoconnect"), s_autoconnect, true )));
1029 NewCfgItem(IDC_MAXSOURCEPERFILE, (MkCfg_Int( wxT("/eMule/MaxSourcesPerFile"), s_maxsourceperfile, 300 )));
1030 NewCfgItem(IDC_MAXCON, (MkCfg_Int( wxT("/eMule/MaxConnections"), s_maxconnections, GetRecommendedMaxConnections() )));
1031 NewCfgItem(IDC_MAXCON5SEC, (MkCfg_Int( wxT("/eMule/MaxConnectionsPerFiveSeconds"), s_MaxConperFive, 20 )));
1034 * Proxy
1036 NewCfgItem(ID_PROXY_ENABLE_PROXY, (new Cfg_Bool( wxT("/Proxy/ProxyEnableProxy"), s_ProxyData.m_proxyEnable, false )));
1037 NewCfgItem(ID_PROXY_TYPE, (MkCfg_Int( wxT("/Proxy/ProxyType"), s_ProxyData.m_proxyType, 0 )));
1038 NewCfgItem(ID_PROXY_NAME, (new Cfg_Str( wxT("/Proxy/ProxyName"), s_ProxyData.m_proxyHostName, wxEmptyString )));
1039 NewCfgItem(ID_PROXY_PORT, (MkCfg_Int( wxT("/Proxy/ProxyPort"), s_ProxyData.m_proxyPort, 1080 )));
1040 NewCfgItem(ID_PROXY_ENABLE_PASSWORD, (new Cfg_Bool( wxT("/Proxy/ProxyEnablePassword"), s_ProxyData.m_enablePassword, false )));
1041 NewCfgItem(ID_PROXY_USER, (new Cfg_Str( wxT("/Proxy/ProxyUser"), s_ProxyData.m_userName, wxEmptyString )));
1042 NewCfgItem(ID_PROXY_PASSWORD, (new Cfg_Str( wxT("/Proxy/ProxyPassword"), s_ProxyData.m_password, wxEmptyString )));
1043 // These were copied from eMule config file, maybe someone with windows can complete this?
1044 // NewCfgItem(ID_PROXY_AUTO_SERVER_CONNECT_WITHOUT_PROXY, (new Cfg_Bool( wxT("/Proxy/Proxy????"), s_Proxy????, false )));
1047 * Servers
1049 NewCfgItem(IDC_REMOVEDEAD, (new Cfg_Bool( wxT("/eMule/RemoveDeadServer"), s_deadserver, 1 )));
1050 NewCfgItem(IDC_SERVERRETRIES, (MkCfg_Int( wxT("/eMule/DeadServerRetry"), s_deadserverretries, 3 )));
1051 NewCfgItem(IDC_SERVERKEEPALIVE, (MkCfg_Int( wxT("/eMule/ServerKeepAliveTimeout"), s_dwServerKeepAliveTimeoutMins, 0 )));
1052 NewCfgItem(IDC_RECONN, (new Cfg_Bool( wxT("/eMule/Reconnect"), s_reconnect, true )));
1053 NewCfgItem(IDC_SCORE, (new Cfg_Bool( wxT("/eMule/Scoresystem"), s_scorsystem, true )));
1054 NewCfgItem(IDC_AUTOSERVER, (new Cfg_Bool( wxT("/eMule/Serverlist"), s_autoserverlist, false )));
1055 NewCfgItem(IDC_UPDATESERVERCONNECT, (new Cfg_Bool( wxT("/eMule/AddServerListFromServer"), s_addserversfromserver, false)));
1056 NewCfgItem(IDC_UPDATESERVERCLIENT, (new Cfg_Bool( wxT("/eMule/AddServerListFromClient"), s_addserversfromclient, false )));
1057 NewCfgItem(IDC_SAFESERVERCONNECT, (new Cfg_Bool( wxT("/eMule/SafeServerConnect"), s_safeServerConnect, false )));
1058 NewCfgItem(IDC_AUTOCONNECTSTATICONLY, (new Cfg_Bool( wxT("/eMule/AutoConnectStaticOnly"), s_autoconnectstaticonly, false )));
1059 NewCfgItem(IDC_UPNP_ENABLED, (new Cfg_Bool( wxT("/eMule/UPnPEnabled"), s_UPnPEnabled, false )));
1060 NewCfgItem(IDC_UPNPTCPPORT, (MkCfg_Int( wxT("/eMule/UPnPTCPPort"), s_UPnPTCPPort, 50000 )));
1061 NewCfgItem(IDC_SMARTIDCHECK, (new Cfg_Bool( wxT("/eMule/SmartIdCheck"), s_smartidcheck, true )));
1062 // Enabled networks
1063 NewCfgItem( IDC_NETWORKKAD, (new Cfg_Bool( wxT("/eMule/ConnectToKad"), s_ConnectToKad, true )) );
1064 NewCfgItem( IDC_NETWORKED2K, ( new Cfg_Bool( wxT("/eMule/ConnectToED2K"), s_ConnectToED2K, true ) ));
1068 * Files
1070 NewCfgItem(IDC_TEMPFILES, (new Cfg_Path( wxT("/eMule/TempDir"), s_tempdir, appdir + wxT("Temp") )));
1072 #if defined(__WXMAC__) || defined(__WINDOWS__)
1073 wxString incpath = wxStandardPaths::Get().GetDocumentsDir();
1074 if (incpath.IsEmpty()) {
1075 // There is a built-in possibility for this call to fail, though I can't imagine a reason for that.
1076 incpath = appdir + wxT("Incoming");
1077 } else {
1078 incpath = JoinPaths(incpath, wxT("aMule Downloads"));
1080 #else
1081 wxString incpath = appdir + wxT("Incoming");
1082 #endif
1083 NewCfgItem(IDC_INCFILES, (new Cfg_Path( wxT("/eMule/IncomingDir"), s_incomingdir, incpath )));
1085 NewCfgItem(IDC_ICH, (new Cfg_Bool( wxT("/eMule/ICH"), s_ICH, true )));
1086 NewCfgItem(IDC_AICHTRUST, (new Cfg_Bool( wxT("/eMule/AICHTrust"), s_AICHTrustEveryHash, false )));
1087 NewCfgItem(IDC_CHECKDISKSPACE, (new Cfg_Bool( wxT("/eMule/CheckDiskspace"), s_checkDiskspace, true )));
1088 NewCfgItem(IDC_MINDISKSPACE, (MkCfg_Int( wxT("/eMule/MinFreeDiskSpace"), s_uMinFreeDiskSpace, 1 )));
1089 NewCfgItem(IDC_ADDNEWFILESPAUSED, (new Cfg_Bool( wxT("/eMule/AddNewFilesPaused"), s_addnewfilespaused, false )));
1090 NewCfgItem(IDC_PREVIEWPRIO, (new Cfg_Bool( wxT("/eMule/PreviewPrio"), s_bpreviewprio, false )));
1091 NewCfgItem(IDC_MANUALSERVERHIGHPRIO, (new Cfg_Bool( wxT("/eMule/ManualHighPrio"), s_bmanualhighprio, false )));
1092 NewCfgItem(IDC_STARTNEXTFILE, (new Cfg_Bool( wxT("/eMule/StartNextFile"), s_bstartnextfile, false )));
1093 NewCfgItem(IDC_STARTNEXTFILE_SAME, (new Cfg_Bool( wxT("/eMule/StartNextFileSameCat"), s_bstartnextfilesame, false )));
1094 NewCfgItem(IDC_STARTNEXTFILE_ALPHA, (new Cfg_Bool( wxT("/eMule/StartNextFileAlpha"), s_bstartnextfilealpha, false )));
1095 NewCfgItem(IDC_SRCSEEDS, (new Cfg_Bool( wxT("/ExternalConnect/UseSrcSeeds"), s_UseSrcSeeds, false )));
1096 NewCfgItem(IDC_FILEBUFFERSIZE, (MkCfg_Int( wxT("/eMule/FileBufferSizePref"), s_iFileBufferSize, 16 )));
1097 NewCfgItem(IDC_DAP, (new Cfg_Bool( wxT("/eMule/DAPPref"), s_bDAP, true )));
1098 NewCfgItem(IDC_UAP, (new Cfg_Bool( wxT("/eMule/UAPPref"), s_bUAP, true )));
1099 NewCfgItem(IDC_ALLOCFULLFILE, (new Cfg_Bool( wxT("/eMule/AllocateFullFile"), s_allocFullFile, false )));
1102 * Web Server
1104 NewCfgItem(IDC_OSDIR, (new Cfg_Path( wxT("/eMule/OSDirectory"), s_OSDirectory, appdir )));
1105 NewCfgItem(IDC_ONLINESIG, (new Cfg_Bool( wxT("/eMule/OnlineSignature"), s_onlineSig, false )));
1106 NewCfgItem(IDC_OSUPDATE, (MkCfg_Int( wxT("/eMule/OnlineSignatureUpdate"), s_OSUpdate, 5 )));
1107 NewCfgItem(IDC_ENABLE_WEB, (new Cfg_Bool( wxT("/WebServer/Enabled"), s_bWebEnabled, false )));
1108 NewCfgItem(IDC_WEB_PASSWD, (new Cfg_Str_Encrypted( wxT("/WebServer/Password"), s_sWebPassword )));
1109 NewCfgItem(IDC_WEB_PASSWD_LOW, (new Cfg_Str_Encrypted( wxT("/WebServer/PasswordLow"), s_sWebLowPassword )));
1110 NewCfgItem(IDC_WEB_PORT, (MkCfg_Int( wxT("/WebServer/Port"), s_nWebPort, 4711 )));
1111 NewCfgItem(IDC_WEBUPNPTCPPORT, (MkCfg_Int( wxT("/WebServer/WebUPnPTCPPort"), s_nWebUPnPTCPPort, 50001 )));
1112 NewCfgItem(IDC_UPNP_WEBSERVER_ENABLED,
1113 (new Cfg_Bool( wxT("/WebServer/UPnPWebServerEnabled"), s_UPnPWebServerEnabled, false )));
1114 NewCfgItem(IDC_WEB_GZIP, (new Cfg_Bool( wxT("/WebServer/UseGzip"), s_bWebUseGzip, true )));
1115 NewCfgItem(IDC_ENABLE_WEB_LOW, (new Cfg_Bool( wxT("/WebServer/UseLowRightsUser"), s_bWebLowEnabled, false )));
1116 NewCfgItem(IDC_WEB_REFRESH_TIMEOUT, (MkCfg_Int( wxT("/WebServer/PageRefreshTime"), s_nWebPageRefresh, 120 )));
1117 NewCfgItem(IDC_WEBTEMPLATE, (new Cfg_Skin( wxT("/WebServer/Template"), s_WebTemplate, wxEmptyString )));
1120 * External Connections
1122 NewCfgItem(IDC_EXT_CONN_ACCEPT, (new Cfg_Bool( wxT("/ExternalConnect/AcceptExternalConnections"), s_AcceptExternalConnections, false )));
1123 NewCfgItem(IDC_EXT_CONN_IP, (new Cfg_Str( wxT("/ExternalConnect/ECAddress"), s_ECAddr, wxEmptyString )));
1124 NewCfgItem(IDC_EXT_CONN_TCP_PORT, (MkCfg_Int( wxT("/ExternalConnect/ECPort"), s_ECPort, 4712 )));
1125 NewCfgItem(IDC_EXT_CONN_PASSWD, (new Cfg_Str_Encrypted( wxT("/ExternalConnect/ECPassword"), s_ECPassword, wxEmptyString )));
1126 NewCfgItem(IDC_UPNP_EC_ENABLED, (new Cfg_Bool( wxT("/ExternalConnect/UPnPECEnabled"), s_UPnPECEnabled, false )));
1129 * GUI behavior
1131 NewCfgItem(IDC_MACHIDEONCLOSE, (new Cfg_Bool( wxT("/GUI/HideOnClose"), s_hideonclose, false )));
1132 NewCfgItem(IDC_ENABLETRAYICON, (new Cfg_Bool( wxT("/eMule/EnableTrayIcon"), s_trayiconenabled, false )));
1133 NewCfgItem(IDC_MINTRAY, (new Cfg_Bool( wxT("/eMule/MinToTray"), s_mintotray, false )));
1134 NewCfgItem(IDC_NOTIF, (new Cfg_Bool( wxT("/eMule/Notifications"), s_notify, false )));
1135 NewCfgItem(IDC_EXIT, (new Cfg_Bool( wxT("/eMule/ConfirmExit"), s_confirmExit, true )));
1136 NewCfgItem(IDC_STARTMIN, (new Cfg_Bool( wxT("/eMule/StartupMinimized"), s_startMinimized, false )));
1139 * GUI appearence
1141 NewCfgItem(IDC_3DDEPTH, (MkCfg_Int( wxT("/eMule/3DDepth"), s_depth3D, 10 )));
1142 NewCfgItem(IDC_TOOLTIPDELAY, (MkCfg_Int( wxT("/eMule/ToolTipDelay"), s_iToolDelayTime, 1 )));
1143 NewCfgItem(IDC_SHOWOVERHEAD, (new Cfg_Bool( wxT("/eMule/ShowOverhead"), s_bshowoverhead, false )));
1144 NewCfgItem(IDC_EXTCATINFO, (new Cfg_Bool( wxT("/eMule/ShowInfoOnCatTabs"), s_showCatTabInfos, true )));
1145 NewCfgItem(IDC_FED2KLH, (new Cfg_Bool( wxT("/Razor_Preferences/FastED2KLinksHandler"), s_FastED2KLinksHandler, true )));
1146 NewCfgItem(IDC_PROGBAR, (new Cfg_Bool( wxT("/ExternalConnect/ShowProgressBar"), s_ProgBar, true )));
1147 NewCfgItem(IDC_PERCENT, (new Cfg_Bool( wxT("/ExternalConnect/ShowPercent"), s_Percent, true )));
1148 NewCfgItem(IDC_SKIN, (new Cfg_Skin( wxT("/SkinGUIOptions/Skin"), s_Skin, wxEmptyString )));
1149 NewCfgItem(IDC_VERTTOOLBAR, (new Cfg_Bool( wxT("/eMule/VerticalToolbar"), s_ToolbarOrientation, false )));
1150 NewCfgItem(IDC_SHOW_COUNTRY_FLAGS, (new Cfg_Bool( wxT("/eMule/GeoIPEnabled"), s_GeoIPEnabled, true )));
1151 #ifndef __SVN__
1152 NewCfgItem(IDC_SHOWVERSIONONTITLE, (new Cfg_Bool( wxT("/eMule/ShowVersionOnTitle"), s_showVersionOnTitle, false )));
1153 #endif
1156 * External Apps
1158 NewCfgItem(IDC_VIDEOPLAYER, (new Cfg_Str( wxT("/eMule/VideoPlayer"), s_VideoPlayer, wxEmptyString )));
1161 * Statistics
1163 NewCfgItem(IDC_SLIDER, (MkCfg_Int( wxT("/eMule/StatGraphsInterval"), s_trafficOMeterInterval, 3 )));
1164 NewCfgItem(IDC_SLIDER2, (MkCfg_Int( wxT("/eMule/statsInterval"), s_statsInterval, 30 )));
1165 NewCfgItem(IDC_DOWNLOAD_CAP, (MkCfg_Int( wxT("/eMule/DownloadCapacity"), s_maxGraphDownloadRate, 300 )));
1166 NewCfgItem(IDC_UPLOAD_CAP, (MkCfg_Int( wxT("/eMule/UploadCapacity"), s_maxGraphUploadRate, 100 )));
1167 NewCfgItem(IDC_SLIDER3, (MkCfg_Int( wxT("/eMule/StatsAverageMinutes"), s_statsAverageMinutes, 5 )));
1168 NewCfgItem(IDC_SLIDER4, (MkCfg_Int( wxT("/eMule/VariousStatisticsMaxValue"), s_statsMax, 100 )));
1169 NewCfgItem(IDC_CLIENTVERSIONS, (MkCfg_Int( wxT("/Statistics/MaxClientVersions"), s_maxClientVersions, 0 )));
1172 * Security
1174 NewCfgItem(IDC_SEESHARES, (MkCfg_Int( wxT("/eMule/SeeShare"), s_iSeeShares, 2 )));
1175 NewCfgItem(IDC_SECIDENT, (new Cfg_Bool( wxT("/ExternalConnect/UseSecIdent"), s_SecIdent, true )));
1176 NewCfgItem(IDC_IPFCLIENTS, (new Cfg_Bool( wxT("/ExternalConnect/IpFilterClients"), s_IPFilterClients, true )));
1177 NewCfgItem(IDC_IPFSERVERS, (new Cfg_Bool( wxT("/ExternalConnect/IpFilterServers"), s_IPFilterServers, true )));
1178 NewCfgItem(IDC_FILTERLAN, (new Cfg_Bool( wxT("/eMule/FilterLanIPs"), s_filterLanIP, true )));
1179 NewCfgItem(IDC_PARANOID, (new Cfg_Bool( wxT("/eMule/ParanoidFiltering"), s_paranoidfilter, true )));
1180 NewCfgItem(IDC_AUTOIPFILTER, (new Cfg_Bool( wxT("/eMule/IPFilterAutoLoad"), s_IPFilterAutoLoad, true )));
1181 NewCfgItem(IDC_IPFILTERURL, (new Cfg_Str( wxT("/eMule/IPFilterURL"), s_IPFilterURL, wxEmptyString )));
1182 NewCfgItem(ID_IPFILTERLEVEL, (MkCfg_Int( wxT("/eMule/FilterLevel"), s_filterlevel, 127 )));
1183 NewCfgItem(IDC_IPFILTERSYS, (new Cfg_Bool( wxT("/eMule/IPFilterSystem"), s_IPFilterSys, false )));
1186 * Message Filter
1188 NewCfgItem(IDC_MSGFILTER, (new Cfg_Bool( wxT("/eMule/FilterMessages"), s_MustFilterMessages, true )));
1189 NewCfgItem(IDC_MSGFILTER_ALL, (new Cfg_Bool( wxT("/eMule/FilterAllMessages"), s_FilterAllMessages, false )));
1190 NewCfgItem(IDC_MSGFILTER_NONFRIENDS, (new Cfg_Bool( wxT("/eMule/MessagesFromFriendsOnly"), s_msgonlyfriends, false )));
1191 NewCfgItem(IDC_MSGFILTER_NONSECURE, (new Cfg_Bool( wxT("/eMule/MessageFromValidSourcesOnly"), s_msgsecure, true )));
1192 NewCfgItem(IDC_MSGFILTER_WORD, (new Cfg_Bool( wxT("/eMule/FilterWordMessages"), s_FilterSomeMessages, false )));
1193 NewCfgItem(IDC_MSGWORD, (new Cfg_Str( wxT("/eMule/MessageFilter"), s_MessageFilterString, wxEmptyString )));
1194 NewCfgItem(IDC_MSGLOG, (new Cfg_Bool( wxT("/eMule/ShowMessagesInLog"), s_ShowMessagesInLog, true )));
1195 //Todo NewCfgItem(IDC_MSGADVSPAM, (new Cfg_Bool( wxT("/eMule/AdvancedSpamFilter"), s_IsAdvancedSpamfilterEnabled, true )));
1196 //Todo NewCfgItem(IDC_MSGCAPTCHA, (new Cfg_Bool( wxT("/eMule/MessageUseCaptchas"), s_IsChatCaptchaEnabled, true )));
1197 s_MiscList.push_back( new Cfg_Bool( wxT("/eMule/AdvancedSpamFilter"), s_IsAdvancedSpamfilterEnabled, true ) );
1198 s_MiscList.push_back( new Cfg_Bool( wxT("/eMule/MessageUseCaptchas"), s_IsChatCaptchaEnabled, true ) );
1200 NewCfgItem(IDC_FILTERCOMMENTS, (new Cfg_Bool( wxT("/eMule/FilterComments"), s_FilterComments, false )));
1201 NewCfgItem(IDC_COMMENTWORD, (new Cfg_Str( wxT("/eMule/CommentFilter"), s_CommentFilterString, wxEmptyString )));
1204 * Hidden files sharing
1206 NewCfgItem(IDC_SHAREHIDDENFILES, (new Cfg_Bool( wxT("/eMule/ShareHiddenFiles"), s_ShareHiddenFiles, false )));
1209 * Auto-Sorting of downloads
1211 NewCfgItem(IDC_AUTOSORT, (new Cfg_Bool( wxT("/eMule/AutoSortDownloads"), s_AutoSortDownload, false )));
1214 * Version check
1216 NewCfgItem(IDC_NEWVERSION, (new Cfg_Bool( wxT("/eMule/NewVersionCheck"), s_NewVersionCheck, true )));
1219 * Obfuscation
1221 NewCfgItem( IDC_SUPPORT_PO, ( new Cfg_Bool( wxT("/Obfuscation/IsClientCryptLayerSupported"), s_IsClientCryptLayerSupported, true )));
1222 NewCfgItem( IDC_ENABLE_PO_OUTGOING, ( new Cfg_Bool( wxT("/Obfuscation/IsCryptLayerRequested"), s_bCryptLayerRequested, true )));
1223 NewCfgItem( IDC_ENFORCE_PO_INCOMING, ( new Cfg_Bool( wxT("/Obfuscation/IsClientCryptLayerRequired"), s_IsClientCryptLayerRequired, false )));
1224 #ifndef CLIENT_GUI
1225 // There is no need for GUI items for this two.
1226 s_MiscList.push_back( MkCfg_Int( wxT("/Obfuscation/CryptoPaddingLenght"), s_byCryptTCPPaddingLength, 254 ) );
1227 s_MiscList.push_back( MkCfg_Int( wxT("/Obfuscation/CryptoKadUDPKey"), s_dwKadUDPKey, GetRandomUint32() ) );
1228 #endif
1231 * Power management
1233 NewCfgItem( IDC_PREVENT_SLEEP, ( new Cfg_Bool( wxT("/PowerManagement/PreventSleepWhileDownloading"), s_preventSleepWhileDownloading, false )));
1236 * The following doesn't have an associated widget or section
1238 s_MiscList.push_back( new Cfg_Str( wxT("/eMule/Language"), s_languageID ) );
1239 s_MiscList.push_back( MkCfg_Int( wxT("/eMule/SplitterbarPosition"), s_splitterbarPosition, 75 ) );
1240 s_MiscList.push_back( new Cfg_Str( wxT("/eMule/YourHostname"), s_yourHostname, wxEmptyString ) );
1241 s_MiscList.push_back( new Cfg_Str( wxT("/eMule/DateTimeFormat"), s_datetimeformat, wxT("%A, %x, %X") ) );
1243 s_MiscList.push_back( MkCfg_Int( wxT("/eMule/AllcatType"), s_allcatFilter, 0 ) );
1244 s_MiscList.push_back( new Cfg_Bool( wxT("/eMule/ShowAllNotCats"), s_showAllNotCats, false ) );
1246 s_MiscList.push_back( MkCfg_Int( wxT("/eMule/SmartIdState"), s_smartidstate, 0 ) );
1248 s_MiscList.push_back( new Cfg_Bool( wxT("/eMule/DropSlowSources"), s_DropSlowSources, false ) );
1250 s_MiscList.push_back( new Cfg_Str( wxT("/eMule/KadNodesUrl"), s_KadURL, wxT("http://upd.emule-security.org/nodes.dat") ) );
1251 s_MiscList.push_back( new Cfg_Str( wxT("/eMule/Ed2kServersUrl"), s_Ed2kURL, wxT("http://upd.emule-security.org/server.met") ) );
1252 s_MiscList.push_back( MkCfg_Int( wxT("/eMule/ShowRatesOnTitle"), s_showRatesOnTitle, 0 ));
1254 s_MiscList.push_back( new Cfg_Str( wxT("/eMule/GeoLiteCountryUpdateUrl"), s_GeoIPUpdateUrl, wxT("http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz") ) );
1255 wxConfigBase::Get()->DeleteEntry(wxT("/eMule/GeoIPUpdateUrl")); // get rid of the old one for a while
1257 s_MiscList.push_back( new Cfg_Str( wxT("/WebServer/Path"), s_sWebPath, wxT("amuleweb") ) );
1259 s_MiscList.push_back( new Cfg_Str( wxT("/eMule/StatsServerName"), s_StatsServerName, wxT("Shorty's ED2K stats") ) );
1260 s_MiscList.push_back( new Cfg_Str( wxT("/eMule/StatsServerURL"), s_StatsServerURL, wxT("http://ed2k.shortypower.dyndns.org/?hash=") ) );
1262 s_MiscList.push_back( new Cfg_Bool( wxT("/ExternalConnect/TransmitOnlyUploadingClients"), s_TransmitOnlyUploadingClients, false ) );
1263 s_MiscList.push_back( new Cfg_Bool( wxT("/eMule/CreateSparseFiles"), s_createFilesSparse, true ) );
1265 #ifndef AMULE_DAEMON
1266 // Colors have been moved from global prefs to CStatisticsDlg
1267 for ( int i = 0; i < cntStatColors; i++ ) {
1268 wxString str = CFormat(wxT("/eMule/StatColor%i")) % i;
1269 s_MiscList.push_back( new Cfg_Colour( str, CStatisticsDlg::acrStat[i] ) );
1271 #endif
1273 // User events
1274 for (unsigned int i = 0; i < CUserEvents::GetCount(); ++i) {
1275 // We can't use NewCfgItem here, because we need to find these items
1276 // later, which would be impossible in amuled with NewCfgItem.
1277 // The IDs we assign here are high enough to not cause any collision
1278 // even on the daemon.
1279 s_CfgList[USEREVENTS_FIRST_ID + i * USEREVENTS_IDS_PER_EVENT + 1] = new Cfg_Bool(wxT("/UserEvents/") + CUserEvents::GetKey(i) + wxT("/CoreEnabled"), CUserEvents::GetCoreEnableVar(i), false);
1280 s_CfgList[USEREVENTS_FIRST_ID + i * USEREVENTS_IDS_PER_EVENT + 2] = new Cfg_Str(wxT("/UserEvents/") + CUserEvents::GetKey(i) + wxT("/CoreCommand"), CUserEvents::GetCoreCommandVar(i), wxEmptyString);
1281 s_CfgList[USEREVENTS_FIRST_ID + i * USEREVENTS_IDS_PER_EVENT + 3] = new Cfg_Bool(wxT("/UserEvents/") + CUserEvents::GetKey(i) + wxT("/GUIEnabled"), CUserEvents::GetGUIEnableVar(i), false);
1282 s_CfgList[USEREVENTS_FIRST_ID + i * USEREVENTS_IDS_PER_EVENT + 4] = new Cfg_Str(wxT("/UserEvents/") + CUserEvents::GetKey(i) + wxT("/GUICommand"), CUserEvents::GetGUICommandVar(i), wxEmptyString);
1287 void CPreferences::EraseItemList()
1289 while ( s_CfgList.begin() != s_CfgList.end() ) {
1290 delete s_CfgList.begin()->second;
1291 s_CfgList.erase( s_CfgList.begin() );
1294 CFGList::iterator it = s_MiscList.begin();
1295 for ( ; it != s_MiscList.end(); ) {
1296 delete *it;
1297 it = s_MiscList.erase( it );
1302 void CPreferences::LoadAllItems(wxConfigBase* cfg)
1304 #ifndef CLIENT_GUI
1305 // Preserve values from old config. The global config object may not be set yet
1306 // when BuildItemList() is called, so we need to provide defaults later - here.
1307 if (cfg->HasEntry(wxT("/eMule/ExecOnCompletion"))) {
1308 bool ExecOnCompletion;
1309 cfg->Read(wxT("/eMule/ExecOnCompletion"), &ExecOnCompletion, false);
1310 // Assign to core command, that's the most likely it was.
1311 static_cast<Cfg_Bool*>(s_CfgList[USEREVENTS_FIRST_ID + CUserEvents::DownloadCompleted * USEREVENTS_IDS_PER_EVENT + 1])->SetDefault(ExecOnCompletion);
1312 cfg->DeleteEntry(wxT("/eMule/ExecOnCompletion"));
1314 if (cfg->HasEntry(wxT("/eMule/ExecOnCompletionCommand"))) {
1315 wxString ExecOnCompletionCommand;
1316 cfg->Read(wxT("/eMule/ExecOnCompletionCommand"), &ExecOnCompletionCommand, wxEmptyString);
1317 static_cast<Cfg_Str*>(s_CfgList[USEREVENTS_FIRST_ID + CUserEvents::DownloadCompleted * USEREVENTS_IDS_PER_EVENT + 2])->SetDefault(ExecOnCompletionCommand);
1318 cfg->DeleteEntry(wxT("/eMule/ExecOnCompletionCommand"));
1320 #endif
1321 CFGMap::iterator it_a = s_CfgList.begin();
1322 for ( ; it_a != s_CfgList.end(); ++it_a ) {
1323 it_a->second->LoadFromFile( cfg );
1326 CFGList::iterator it_b = s_MiscList.begin();
1327 for ( ; it_b != s_MiscList.end(); ++it_b ) {
1328 (*it_b)->LoadFromFile( cfg );
1331 // Preserve old value of UDPDisable
1332 if (cfg->HasEntry(wxT("/eMule/UDPDisable"))) {
1333 bool UDPDisable;
1334 cfg->Read(wxT("/eMule/UDPDisable"), &UDPDisable, false);
1335 SetUDPDisable(UDPDisable);
1336 cfg->DeleteEntry(wxT("/eMule/UDPDisable"));
1339 // Preserve old value of UseSkinFiles
1340 if (cfg->HasEntry(wxT("/SkinGUIOptions/UseSkinFiles"))) {
1341 bool UseSkinFiles;
1342 cfg->Read(wxT("/SkinGUIOptions/UseSkinFiles"), &UseSkinFiles, false);
1343 if (!UseSkinFiles) {
1344 s_Skin.Clear();
1346 cfg->DeleteEntry(wxT("/SkinGUIOptions/UseSkinFiles"));
1349 #ifdef __DEBUG__
1350 // Load debug-categories
1351 int count = theLogger.GetDebugCategoryCount();
1353 for ( int i = 0; i < count; i++ ) {
1354 const CDebugCategory& cat = theLogger.GetDebugCategory( i );
1356 bool enabled = false;
1357 cfg->Read( wxT("/Debug/Cat_") + cat.GetName(), &enabled );
1359 theLogger.SetEnabled( cat.GetType(), enabled );
1361 #endif
1363 // Now do some post-processing / sanity checking on the values we just loaded
1364 #ifndef CLIENT_GUI
1365 CheckUlDlRatio();
1366 SetPort(s_port);
1367 if (s_byCryptTCPPaddingLength > 254) {
1368 s_byCryptTCPPaddingLength = GetRandomUint8() % 254;
1370 SetSlotAllocation(s_slotallocation);
1371 #endif
1375 void CPreferences::SaveAllItems(wxConfigBase* cfg)
1377 // Save the Cfg values
1378 CFGMap::iterator it_a = s_CfgList.begin();
1379 for ( ; it_a != s_CfgList.end(); ++it_a )
1380 it_a->second->SaveToFile( cfg );
1382 CFGList::iterator it_b = s_MiscList.begin();
1383 for ( ; it_b != s_MiscList.end(); ++it_b )
1384 (*it_b)->SaveToFile( cfg );
1387 // Save debug-categories
1388 #ifdef __DEBUG__
1389 int count = theLogger.GetDebugCategoryCount();
1391 for ( int i = 0; i < count; i++ ) {
1392 const CDebugCategory& cat = theLogger.GetDebugCategory( i );
1394 cfg->Write( wxT("/Debug/Cat_") + cat.GetName(), cat.IsEnabled() );
1396 #endif
1399 void CPreferences::SetMaxUpload(uint16 in)
1401 if ( s_maxupload != in ) {
1402 s_maxupload = in;
1404 // Ensure that the ratio is upheld
1405 CheckUlDlRatio();
1410 void CPreferences::SetMaxDownload(uint16 in)
1412 if ( s_maxdownload != in ) {
1413 s_maxdownload = in;
1415 // Ensure that the ratio is upheld
1416 CheckUlDlRatio();
1421 void CPreferences::UnsetAutoServerStart()
1423 s_autoserverlist = false;
1427 // Here we slightly limit the users' ability to be a bad citizen: for very low upload rates
1428 // we force a low download rate, so as to discourage this type of leeching.
1429 // We're Open Source, and whoever wants it can do his own mod to get around this, but the
1430 // packaged product will try to enforce good behavior.
1432 // Kry note: of course, any leecher mod will be banned asap.
1433 void CPreferences::CheckUlDlRatio()
1435 // Backwards compatibility
1436 if ( s_maxupload == 0xFFFF )
1437 s_maxupload = UNLIMITED;
1439 // Backwards compatibility
1440 if ( s_maxdownload == 0xFFFF )
1441 s_maxdownload = UNLIMITED;
1443 if ( s_maxupload == UNLIMITED )
1444 return;
1446 // Enforce the limits
1447 if ( s_maxupload < 4 ) {
1448 if ( ( s_maxupload * 3 < s_maxdownload ) || ( s_maxdownload == 0 ) )
1449 s_maxdownload = s_maxupload * 3 ;
1450 } else if ( s_maxupload < 10 ) {
1451 if ( ( s_maxupload * 4 < s_maxdownload ) || ( s_maxdownload == 0 ) )
1452 s_maxdownload = s_maxupload * 4;
1457 void CPreferences::Save()
1459 wxString fullpath(s_configDir + wxT("preferences.dat"));
1461 CFile preffile;
1462 if (!wxFileExists(fullpath)) {
1463 preffile.Create(fullpath);
1466 if (preffile.Open(fullpath, CFile::read_write)) {
1467 try {
1468 preffile.WriteUInt8(PREFFILE_VERSION);
1469 preffile.WriteHash(s_userhash);
1470 } catch (const CIOFailureException& e) {
1471 AddDebugLogLineC(logGeneral, wxT("IO failure while saving user-hash: ") + e.what());
1475 SavePreferences();
1477 #ifndef CLIENT_GUI
1478 CTextFile sdirfile;
1479 if (sdirfile.Open(s_configDir + wxT("shareddir.dat"), CTextFile::write)) {
1480 for (size_t i = 0; i < shareddir_list.size(); ++i) {
1481 sdirfile.WriteLine(shareddir_list[i].GetRaw(), wxConvUTF8);
1485 #endif
1489 CPreferences::~CPreferences()
1491 DeleteContents(m_CatList);
1495 int32 CPreferences::GetRecommendedMaxConnections()
1497 #ifndef CLIENT_GUI
1498 int iRealMax = PlatformSpecific::GetMaxConnections();
1499 if(iRealMax == -1 || iRealMax > 520) {
1500 return 500;
1502 if(iRealMax < 20) {
1503 return iRealMax;
1505 if(iRealMax <= 256) {
1506 return iRealMax - 10;
1508 return iRealMax - 20;
1509 #else
1510 return 500;
1511 #endif
1515 void CPreferences::SavePreferences()
1517 wxConfigBase* cfg = wxConfigBase::Get();
1519 cfg->Write( wxT("/eMule/AppVersion"), wxT(VERSION) );
1521 // Save the options
1522 SaveAllItems( cfg );
1524 // Ensure that the changes are saved to disk.
1525 cfg->Flush();
1529 void CPreferences::SaveCats()
1531 if ( GetCatCount() ) {
1532 wxConfigBase* cfg = wxConfigBase::Get();
1534 // Save the main cat.
1535 cfg->Write( wxT("/eMule/AllcatType"), (int)s_allcatFilter);
1537 // The first category is the default one and should not be counted
1539 cfg->Write( wxT("/General/Count"), (long)(m_CatList.size() - 1) );
1541 uint32 maxcat = m_CatList.size();
1542 for (uint32 i = 1; i < maxcat; i++) {
1543 cfg->SetPath(CFormat(wxT("/Cat#%i")) % i);
1545 cfg->Write( wxT("Title"), m_CatList[i]->title );
1546 cfg->Write( wxT("Incoming"), CPath::ToUniv(m_CatList[i]->path) );
1547 cfg->Write( wxT("Comment"), m_CatList[i]->comment );
1548 cfg->Write( wxT("Color"), wxString(CFormat(wxT("%u")) % m_CatList[i]->color));
1549 cfg->Write( wxT("Priority"), (int)m_CatList[i]->prio );
1551 // remove deleted cats from config
1552 while (cfg->DeleteGroup(CFormat(wxT("/Cat#%i")) % maxcat++)) {}
1554 cfg->Flush();
1559 void CPreferences::LoadPreferences()
1561 LoadCats();
1565 void CPreferences::LoadCats()
1567 // default cat ... Meow! =(^.^)=
1568 Category_Struct* defaultcat = new Category_Struct;
1569 defaultcat->prio = 0;
1570 defaultcat->color = 0;
1572 AddCat( defaultcat );
1574 wxConfigBase* cfg = wxConfigBase::Get();
1576 long max = cfg->Read( wxT("/General/Count"), 0l );
1578 for ( int i = 1; i <= max ; i++ ) {
1579 cfg->SetPath(CFormat(wxT("/Cat#%i")) % i);
1581 Category_Struct* newcat = new Category_Struct;
1583 newcat->title = cfg->Read( wxT("Title"), wxEmptyString );
1584 newcat->path = CPath::FromUniv(cfg->Read(wxT("Incoming"), wxEmptyString));
1586 // Some sanity checking
1587 if ( newcat->title.IsEmpty() || !newcat->path.IsOk() ) {
1588 AddLogLineN(_("Invalid category found, skipping"));
1590 delete newcat;
1591 continue;
1594 newcat->comment = cfg->Read( wxT("Comment"), wxEmptyString );
1595 newcat->prio = cfg->Read( wxT("Priority"), 0l );
1596 newcat->color = StrToULong(cfg->Read(wxT("Color"), wxT("0")));
1598 AddCat(newcat);
1600 if (!newcat->path.DirExists()) {
1601 CPath::MakeDir(newcat->path);
1607 uint16 CPreferences::GetDefaultMaxConperFive()
1609 return MAXCONPER5SEC;
1613 uint32 CPreferences::AddCat(Category_Struct* cat)
1615 m_CatList.push_back( cat );
1617 return m_CatList.size() - 1;
1621 void CPreferences::RemoveCat(size_t index)
1623 if ( index < m_CatList.size() ) {
1624 CatList::iterator it = m_CatList.begin() + index;
1626 delete *it;
1628 m_CatList.erase( it );
1630 // remove cat directory from shares
1631 theApp->sharedfiles->Reload();
1636 uint32 CPreferences::GetCatCount()
1638 return m_CatList.size();
1642 Category_Struct* CPreferences::GetCategory(size_t index)
1644 wxASSERT( index < m_CatList.size() );
1646 return m_CatList[index];
1650 const CPath& CPreferences::GetCatPath(uint8 index)
1652 wxASSERT( index < m_CatList.size() );
1654 return m_CatList[index]->path;
1658 uint32 CPreferences::GetCatColor(size_t index)
1660 wxASSERT( index < m_CatList.size() );
1662 return m_CatList[index]->color;
1665 bool CPreferences::CreateCategory(
1666 Category_Struct *& category,
1667 const wxString& name,
1668 const CPath& path,
1669 const wxString& comment,
1670 uint32 color,
1671 uint8 prio)
1673 category = new Category_Struct();
1674 category->path = thePrefs::GetIncomingDir(); // set a default in case path is invalid
1675 uint32 cat = AddCat(category);
1676 return UpdateCategory(cat, name, path, comment, color, prio);
1679 bool CPreferences::UpdateCategory(
1680 uint8 cat,
1681 const wxString& name,
1682 const CPath& path,
1683 const wxString& comment,
1684 uint32 color,
1685 uint8 prio)
1687 Category_Struct *category = m_CatList[cat];
1689 // return true if path is ok, false if not
1690 bool ret = true;
1691 if (!path.IsOk() || (!path.DirExists() && !CPath::MakeDir(path))) {
1692 ret = false;
1693 // keep path as it was
1694 } else if (category->path != path) {
1695 // path changed: reload shared files, adding files in the new path and removing those from the old path
1696 category->path = path;
1697 theApp->sharedfiles->Reload();
1699 category->title = name;
1700 category->comment = comment;
1701 category->color = color;
1702 category->prio = prio;
1704 SaveCats();
1705 return ret;
1709 wxString CPreferences::GetBrowser()
1711 wxString cmd(s_CustomBrowser);
1712 #ifndef __WINDOWS__
1713 if( s_BrowserTab ) {
1714 // This is certainly not the best way to do it, but I'm lazy
1715 if ((wxT("mozilla") == cmd.Right(7)) || (wxT("firefox") == cmd.Right(7))
1716 || (wxT("MozillaFirebird") == cmd.Right(15))) {
1717 cmd += wxT(" -remote 'openURL(%s, new-tab)'");
1719 if ((wxT("galeon") == cmd.Right(6)) || (wxT("epiphany") == cmd.Right(8))) {
1720 cmd += wxT(" -n '%s'");
1722 if (wxT("opera") == cmd.Right(5)) {
1723 cmd += wxT(" --newpage '%s'");
1725 if (wxT("netscape") == cmd.Right(8)) {
1726 cmd += wxT(" -remote 'openURLs(%s,new-tab)'");
1729 #endif /* !__WINDOWS__ */
1730 return cmd;
1733 void CPreferences::SetFilteringClients(bool val)
1735 if (val != s_IPFilterClients) {
1736 s_IPFilterClients = val;
1737 if (val) {
1738 theApp->clientlist->FilterQueues();
1743 void CPreferences::SetFilteringServers(bool val)
1745 if (val != s_IPFilterServers) {
1746 s_IPFilterServers = val;
1747 if (val) {
1748 theApp->serverlist->FilterServers();
1753 void CPreferences::SetIPFilterLevel(uint8 level)
1755 if (level != s_filterlevel) {
1756 // Set the new access-level
1757 s_filterlevel = level;
1758 #ifndef CLIENT_GUI
1759 // and reload the filter
1760 NotifyAlways_IPFilter_Reload();
1761 #endif
1765 void CPreferences::SetPort(uint16 val)
1767 // Warning: Check for +3, because server UDP is TCP+3
1769 if (val +3 > 65535) {
1770 AddLogLineC(_("TCP port can't be higher than 65532 due to server UDP socket being TCP+3"));
1771 AddLogLineN(CFormat(_("Default port will be used (%d)")) % DEFAULT_TCP_PORT);
1772 s_port = DEFAULT_TCP_PORT;
1773 } else {
1774 s_port = val;
1779 void CPreferences::ReloadSharedFolders()
1781 #ifndef CLIENT_GUI
1782 shareddir_list.clear();
1784 CTextFile file;
1785 if (file.Open(s_configDir + wxT("shareddir.dat"), CTextFile::read)) {
1786 wxArrayString lines = file.ReadLines(txtReadDefault, wxConvUTF8);
1788 for (size_t i = 0; i < lines.size(); ++i) {
1789 CPath path(lines[i]);
1791 if (path.DirExists()) {
1792 shareddir_list.push_back(path);
1793 } else {
1794 AddLogLineN(CFormat(_("Dropping non-existing shared directory: %s")) % path.GetPrintable());
1798 #endif
1802 bool CPreferences::IsMessageFiltered(const wxString& message)
1804 if (s_FilterAllMessages) {
1805 return true;
1806 } else {
1807 if (s_FilterSomeMessages) {
1808 if (s_MessageFilterString.IsSameAs(wxT("*"))){
1809 // Filter anything
1810 return true;
1811 } else {
1812 wxStringTokenizer tokenizer( s_MessageFilterString, wxT(",") );
1813 while (tokenizer.HasMoreTokens()) {
1814 if ( message.Lower().Trim(false).Trim(true).Contains(
1815 tokenizer.GetNextToken().Lower().Trim(false).Trim(true))) {
1816 return true;
1819 return false;
1821 } else {
1822 return false;
1828 bool CPreferences::IsCommentFiltered(const wxString& comment)
1830 if (s_FilterComments) {
1831 wxStringTokenizer tokenizer( s_CommentFilterString, wxT(",") );
1832 while (tokenizer.HasMoreTokens()) {
1833 if ( comment.Lower().Trim(false).Trim(true).Contains(
1834 tokenizer.GetNextToken().Lower().Trim(false).Trim(true))) {
1835 return true;
1839 return false;
1842 wxString CPreferences::GetLastHTTPDownloadURL(uint8 t)
1844 wxConfigBase* cfg = wxConfigBase::Get();
1845 wxString key = CFormat(wxT("/HTTPDownload/URL_%d")) % t;
1846 return cfg->Read(key, wxEmptyString);
1849 void CPreferences::SetLastHTTPDownloadURL(uint8 t, const wxString& val)
1851 wxConfigBase* cfg = wxConfigBase::Get();
1852 wxString key = CFormat(wxT("/HTTPDownload/URL_%d")) % t;
1853 cfg->Write(key, val);
1856 // File_checked_for_headers