Upstream tarball 9656
[amule.git] / src / Preferences.cpp
blob1e154de1d0d8069453ddc75c145a1139b9d9d55d
1 //
2 // This file is part of the aMule Project.
3 //
4 // Copyright (c) 2003-2008 aMule Team ( admin@amule.org / http://www.amule.org )
5 // Copyright (c) 2002-2008 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.
20 //
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>
39 #include "amule.h"
40 #ifdef HAVE_CONFIG_H
41 #include "config.h" // Needed for PACKAGE_STRING
42 #endif
44 #include "CFile.h"
45 #include <common/MD5Sum.h>
46 #include "Logger.h"
47 #include <common/Format.h> // Needed for CFormat
48 #include <common/TextFile.h> // Needed for CTextFile
49 #include <common/ClientVersion.h>
51 #include "UserEvents.h"
53 #ifndef AMULE_DAEMON
54 #include <wx/valgen.h>
55 #include "muuli_wdr.h"
56 #include "StatisticsDlg.h"
57 #include "MuleColour.h"
58 #endif
60 #include "RandomFunctions.h"
61 #ifndef CLIENT_GUI
62 #include "PlatformSpecific.h" // Needed for PlatformSpecific::GetMaxConnections()
63 #endif
65 #define DEFAULT_TCP_PORT 4662
66 #define DEFAULT_UDP_PORT 4672
68 // Static variables
69 unsigned long CPreferences::s_colors[cntStatColors];
70 unsigned long CPreferences::s_colors_ref[cntStatColors];
72 CPreferences::CFGMap CPreferences::s_CfgList;
73 CPreferences::CFGList CPreferences::s_MiscList;
76 /* Proxy */
77 CProxyData CPreferences::s_ProxyData;
79 /* The rest, organize it! */
80 wxString CPreferences::s_nick;
81 uint16 CPreferences::s_maxupload;
82 uint16 CPreferences::s_maxdownload;
83 uint16 CPreferences::s_slotallocation;
84 wxString CPreferences::s_Addr;
85 uint16 CPreferences::s_port;
86 uint16 CPreferences::s_udpport;
87 bool CPreferences::s_UDPEnable;
88 uint16 CPreferences::s_maxconnections;
89 bool CPreferences::s_reconnect;
90 bool CPreferences::s_autoconnect;
91 bool CPreferences::s_autoconnectstaticonly;
92 bool CPreferences::s_UPnPEnabled;
93 bool CPreferences::s_UPnPECEnabled;
94 bool CPreferences::s_UPnPWebServerEnabled;
95 uint16 CPreferences::s_UPnPTCPPort;
96 bool CPreferences::s_autoserverlist;
97 bool CPreferences::s_deadserver;
98 CPath CPreferences::s_incomingdir;
99 CPath CPreferences::s_tempdir;
100 bool CPreferences::s_ICH;
101 uint8 CPreferences::s_depth3D;
102 bool CPreferences::s_scorsystem;
103 bool CPreferences::s_mintotray;
104 bool CPreferences::s_trayiconenabled;
105 bool CPreferences::s_addnewfilespaused;
106 bool CPreferences::s_addserversfromserver;
107 bool CPreferences::s_addserversfromclient;
108 uint16 CPreferences::s_maxsourceperfile;
109 uint16 CPreferences::s_trafficOMeterInterval;
110 uint16 CPreferences::s_statsInterval;
111 uint32 CPreferences::s_maxGraphDownloadRate;
112 uint32 CPreferences::s_maxGraphUploadRate;
113 bool CPreferences::s_confirmExit;
114 bool CPreferences::s_filterLanIP;
115 bool CPreferences::s_paranoidfilter;
116 bool CPreferences::s_IPFilterSys;
117 bool CPreferences::s_onlineSig;
118 uint16 CPreferences::s_OSUpdate;
119 uint64 CPreferences::s_totalDownloadedBytes;
120 uint64 CPreferences::s_totalUploadedBytes;
121 wxString CPreferences::s_languageID;
122 uint8 CPreferences::s_iSeeShares;
123 uint8 CPreferences::s_iToolDelayTime;
124 uint8 CPreferences::s_splitterbarPosition;
125 uint16 CPreferences::s_deadserverretries;
126 uint32 CPreferences::s_dwServerKeepAliveTimeoutMins;
127 uint8 CPreferences::s_statsMax;
128 uint8 CPreferences::s_statsAverageMinutes;
129 bool CPreferences::s_bpreviewprio;
130 bool CPreferences::s_smartidcheck;
131 uint8 CPreferences::s_smartidstate;
132 bool CPreferences::s_safeServerConnect;
133 bool CPreferences::s_startMinimized;
134 uint16 CPreferences::s_MaxConperFive;
135 bool CPreferences::s_checkDiskspace;
136 uint32 CPreferences::s_uMinFreeDiskSpace;
137 wxString CPreferences::s_yourHostname;
138 bool CPreferences::s_bVerbose;
139 bool CPreferences::s_bmanualhighprio;
140 bool CPreferences::s_btransferfullchunks;
141 bool CPreferences::s_bstartnextfile;
142 bool CPreferences::s_bstartnextfilesame;
143 bool CPreferences::s_bshowoverhead;
144 bool CPreferences::s_bDAP;
145 bool CPreferences::s_bUAP;
146 uint8_t CPreferences::s_showRatesOnTitle;
147 wxString CPreferences::s_VideoPlayer;
148 bool CPreferences::s_moviePreviewBackup;
149 bool CPreferences::s_showAllNotCats;
150 bool CPreferences::s_msgonlyfriends;
151 bool CPreferences::s_msgsecure;
152 uint8 CPreferences::s_filterlevel;
153 uint8 CPreferences::s_iFileBufferSize;
154 uint8 CPreferences::s_iQueueSize;
155 wxString CPreferences::s_datetimeformat;
156 wxString CPreferences::s_sWebPassword;
157 wxString CPreferences::s_sWebLowPassword;
158 uint16 CPreferences::s_nWebPort;
159 uint16 CPreferences::s_nWebUPnPTCPPort;
160 bool CPreferences::s_bWebEnabled;
161 bool CPreferences::s_bWebUseGzip;
162 uint32 CPreferences::s_nWebPageRefresh;
163 bool CPreferences::s_bWebLowEnabled;
164 wxString CPreferences::s_WebTemplate;
165 bool CPreferences::s_showCatTabInfos;
166 uint32 CPreferences::s_allcatType;
167 uint8 CPreferences::s_NoNeededSources;
168 bool CPreferences::s_DropFullQueueSources;
169 bool CPreferences::s_DropHighQueueRankingSources;
170 uint32 CPreferences::s_HighQueueRanking;
171 uint32 CPreferences::s_AutoDropTimer;
172 bool CPreferences::s_AcceptExternalConnections;
173 wxString CPreferences::s_ECAddr;
174 uint32 CPreferences::s_ECPort;
175 wxString CPreferences::s_ECPassword;
176 bool CPreferences::s_IPFilterClients;
177 bool CPreferences::s_IPFilterServers;
178 bool CPreferences::s_UseSrcSeeds;
179 bool CPreferences::s_ProgBar;
180 bool CPreferences::s_Percent;
181 bool CPreferences::s_SecIdent;
182 bool CPreferences::s_ExtractMetaData;
183 bool CPreferences::s_allocFullFile;
184 wxString CPreferences::s_CustomBrowser;
185 bool CPreferences::s_BrowserTab;
186 CPath CPreferences::s_OSDirectory;
187 wxString CPreferences::s_Skin;
188 bool CPreferences::s_FastED2KLinksHandler;
189 bool CPreferences::s_ToolbarOrientation;
190 bool CPreferences::s_AICHTrustEveryHash;
191 wxString CPreferences::s_CommentFilterString;
192 bool CPreferences::s_IPFilterAutoLoad;
193 wxString CPreferences::s_IPFilterURL;
194 CMD4Hash CPreferences::s_userhash;
195 bool CPreferences::s_MustFilterMessages;
196 wxString CPreferences::s_MessageFilterString;
197 bool CPreferences::s_FilterAllMessages;
198 bool CPreferences::s_FilterComments;
199 bool CPreferences::s_FilterSomeMessages;
200 bool CPreferences::s_ShowMessagesInLog;
201 bool CPreferences::s_IsAdvancedSpamfilterEnabled;
202 bool CPreferences::s_IsChatCaptchaEnabled;
203 bool CPreferences::s_ShareHiddenFiles;
204 bool CPreferences::s_AutoSortDownload;
205 bool CPreferences::s_NewVersionCheck;
206 bool CPreferences::s_ConnectToKad;
207 bool CPreferences::s_ConnectToED2K;
208 unsigned CPreferences::s_maxClientVersions;
209 bool CPreferences::s_DropSlowSources;
210 bool CPreferences::s_IsClientCryptLayerSupported;
211 bool CPreferences::s_bCryptLayerRequested;
212 bool CPreferences::s_IsClientCryptLayerRequired;
213 uint32 CPreferences::s_dwKadUDPKey;
214 uint8 CPreferences::s_byCryptTCPPaddingLength;
216 wxString CPreferences::s_Ed2kURL;
217 wxString CPreferences::s_KadURL;
218 bool CPreferences::s_GeoIPEnabled;
219 wxString CPreferences::s_GeoIPUpdateUrl;
223 * Template Cfg class for connecting with widgets.
225 * This template provides the base functionionality needed to syncronize a
226 * variable with a widget. However, please note that wxGenericValidator only
227 * supports a few types (int, wxString, bool and wxArrayInt), so this template
228 * can't always be used directly.
230 * Cfg_Str and Cfg_Bool are able to use this template directly, whereas Cfg_Int
231 * makes use of serveral workaround to enable it to be used with integers other
232 * than int.
234 template <typename TYPE>
235 class Cfg_Tmpl : public Cfg_Base
237 public:
239 * Constructor.
241 * @param keyname
242 * @param value
243 * @param defaultVal
245 Cfg_Tmpl( const wxString& keyname, TYPE& value, const TYPE& defaultVal )
246 : Cfg_Base( keyname ),
247 m_value( value ),
248 m_default( defaultVal ),
249 m_widget( NULL )
252 #ifndef AMULE_DAEMON
254 * Connects the Cfg to a widget.
256 * @param id The ID of the widget to be connected.
257 * @param parent The parent of the widget. Use this to speed up searches.
259 * This function works by setting the wxValidator of the class. This however
260 * poses some restrictions on which variable types can be used for this
261 * template, as noted above. It also poses some limits on the widget types,
262 * refer to the wx documentation for those.
264 virtual bool ConnectToWidget( int id, wxWindow* parent = NULL )
266 if ( id ) {
267 m_widget = wxWindow::FindWindowById( id, parent );
269 if ( m_widget ) {
270 wxGenericValidator validator( &m_value );
272 m_widget->SetValidator( validator );
274 return true;
276 } else {
277 m_widget = NULL;
280 return false;
284 /** Updates the assosiated variable, returning true on success. */
285 virtual bool TransferFromWindow()
287 if ( m_widget ) {
288 wxValidator* validator = m_widget->GetValidator();
290 if ( validator ) {
291 TYPE temp = m_value;
293 if ( validator->TransferFromWindow() ) {
294 SetChanged( temp != m_value );
296 return true;
301 return false;
304 /** Updates the assosiated widget, returning true on success. */
305 virtual bool TransferToWindow()
307 if ( m_widget ) {
308 wxValidator* validator = m_widget->GetValidator();
310 if ( validator )
311 return validator->TransferToWindow();
314 return false;
317 #endif
319 /** Sets the default value. */
320 void SetDefault(const TYPE& defaultVal)
322 m_default = defaultVal;
325 protected:
326 //! Reference to the associated variable
327 TYPE& m_value;
329 //! Default variable value
330 TYPE m_default;
332 //! Pointer to the widget assigned to the Cfg instance
333 wxWindow* m_widget;
337 /** Cfg class for wxStrings. */
338 class Cfg_Str : public Cfg_Tmpl<wxString>
340 public:
341 /** Constructor. */
342 Cfg_Str( const wxString& keyname, wxString& value, const wxString& defaultVal = wxEmptyString )
343 : Cfg_Tmpl<wxString>( keyname, value, defaultVal )
346 /** Loads the string, using the specified default value. */
347 virtual void LoadFromFile(wxConfigBase* cfg)
349 cfg->Read( GetKey(), &m_value, m_default );
353 /** Saves the string to the specified wxConfig object. */
354 virtual void SaveToFile(wxConfigBase* cfg)
356 cfg->Write( GetKey(), m_value );
362 * Cfg-class for encrypting strings, for example for passwords.
364 class Cfg_Str_Encrypted : public Cfg_Str
366 public:
367 Cfg_Str_Encrypted( const wxString& keyname, wxString& value, const wxString& defaultVal = wxEmptyString )
368 : Cfg_Str( keyname, value, defaultVal )
371 #ifndef AMULE_DAEMON
372 virtual bool TransferFromWindow()
374 // Shakraw: when storing value, store it encrypted here (only if changed in prefs)
375 if ( Cfg_Str::TransferFromWindow() ) {
377 // Only recalucate the hash for new, non-empty passwords
378 if ( HasChanged() && !m_value.IsEmpty() ) {
379 m_value = MD5Sum( m_value ).GetHash();
382 return true;
386 return false;
388 #endif
392 /** Cfg class for CPath. */
393 class Cfg_Path : public Cfg_Str
395 public:
396 /** Constructor. */
397 Cfg_Path(const wxString& keyname, CPath& value, const wxString& defaultVal = wxEmptyString )
398 : Cfg_Str(keyname, m_temp_path, defaultVal)
399 , m_real_path(value)
402 /** @see Cfg_Str::LoadFromFile. */
403 virtual void LoadFromFile(wxConfigBase* cfg)
405 Cfg_Str::LoadFromFile(cfg);
407 m_real_path = CPath::FromUniv(m_temp_path);
411 /** @see Cfg_Str::SaveToFile. */
412 virtual void SaveToFile(wxConfigBase* cfg)
414 m_temp_path = CPath::ToUniv(m_real_path);
416 Cfg_Str::SaveToFile(cfg);
420 /** @see Cfg_Tmpl::TransferToWindow. */
421 virtual bool TransferToWindow()
423 m_temp_path = m_real_path.GetRaw();
425 return Cfg_Str::TransferToWindow();
428 /** @see Cfg_Tmpl::TransferFromWindow. */
429 virtual bool TransferFromWindow()
431 if (Cfg_Str::TransferFromWindow()) {
432 m_real_path = CPath(m_temp_path);
433 return true;
436 return false;
439 private:
440 wxString m_temp_path;
441 CPath& m_real_path;
446 * Cfg class that takes care of integer types.
448 * This template is needed since wxValidator only supports normals ints, and
449 * wxConfig for the matter only supports longs, thus some worksarounds are
450 * needed.
452 * There are two work-arounds:
453 * 1) wxValidator only supports int*, so we need a immediate variable to act
454 * as a storage. Thus we use Cfg_Tmpl<int> as base class. Thus this class
455 * contains a integer which we use to pass the value back and forth
456 * between the widgets.
458 * 2) wxConfig uses longs to save and read values, thus we need an immediate
459 * stage when loading and saving the value.
461 template <typename TYPE>
462 class Cfg_Int : public Cfg_Tmpl<int>
464 public:
465 Cfg_Int( const wxString& keyname, TYPE& value, int defaultVal = 0 )
466 : Cfg_Tmpl<int>( keyname, m_temp_value, defaultVal ),
467 m_real_value( value ),
468 m_temp_value( value )
472 virtual void LoadFromFile(wxConfigBase* cfg)
474 long tmp = 0;
475 cfg->Read( GetKey(), &tmp, m_default );
477 // Set the temp value
478 m_temp_value = (int)tmp;
479 // Set the actual value
480 m_real_value = (TYPE)tmp;
483 virtual void SaveToFile(wxConfigBase* cfg)
485 cfg->Write( GetKey(), (long)m_real_value );
489 #ifndef AMULE_DAEMON
490 virtual bool TransferFromWindow()
492 if ( Cfg_Tmpl<int>::TransferFromWindow() ) {
493 m_real_value = (TYPE)m_temp_value;
495 return true;
498 return false;
501 virtual bool TransferToWindow()
503 m_temp_value = (int)m_real_value;
505 if ( Cfg_Tmpl<int>::TransferToWindow() ) {
507 // In order to let us update labels on slider-changes, we trigger a event
508 wxSlider *slider = dynamic_cast<wxSlider *>(m_widget);
509 if (slider) {
510 int id = m_widget->GetId();
511 int pos = slider->GetValue();
512 wxScrollEvent evt( wxEVT_SCROLL_THUMBRELEASE, id, pos );
513 m_widget->GetEventHandler()->ProcessEvent( evt );
516 return true;
519 return false;
521 #endif
523 protected:
525 TYPE& m_real_value;
526 int m_temp_value;
531 * Helper function for creating new Cfg_Ints.
533 * @param keyname The cfg-key under which the item should be saved.
534 * @param value The variable to syncronize. The type of this variable defines the type used to create the Cfg_Int.
535 * @param defaultVal The default value if the key isn't found when loading the value.
536 * @return A pointer to the new Cfg_Int object. The caller is responsible for deleting it.
538 * This template-function returns a Cfg_Int of the appropriate type for the
539 * variable used as argument and should be used to avoid having to specify
540 * the integer type when adding a new Cfg_Int, since that's just increases
541 * the maintainence burden.
543 template <class TYPE>
544 Cfg_Base* MkCfg_Int( const wxString& keyname, TYPE& value, int defaultVal )
546 return new Cfg_Int<TYPE>( keyname, value, defaultVal );
551 * Cfg-class for bools.
553 class Cfg_Bool : public Cfg_Tmpl<bool>
555 public:
556 Cfg_Bool( const wxString& keyname, bool& value, bool defaultVal )
557 : Cfg_Tmpl<bool>( keyname, value, defaultVal )
561 virtual void LoadFromFile(wxConfigBase* cfg)
563 cfg->Read( GetKey(), &m_value, m_default );
566 virtual void SaveToFile(wxConfigBase* cfg)
568 cfg->Write( GetKey(), m_value );
574 * Cfg-class for uint64s, with no associated widgets.
576 class Cfg_Counter : public Cfg_Base
578 public:
579 Cfg_Counter( const wxString& keyname, uint64& value )
580 : Cfg_Base( keyname ),
581 m_value( value )
584 virtual void LoadFromFile(wxConfigBase* cfg)
586 wxString buffer;
588 cfg->Read( GetKey(), &buffer, wxT("0") );
590 uint64 tmp = 0;
591 for (unsigned int i = 0; i < buffer.Length(); ++i) {
592 if ((buffer[i] >= wxChar('0')) &&(buffer[i] <= wxChar('9'))) {
593 tmp = tmp * 10 + (buffer[i] - wxChar('0'));
594 } else {
595 tmp = 0;
596 break;
599 m_value = tmp;
602 virtual void SaveToFile(wxConfigBase* cfg)
604 wxString str = CFormat( wxT("%llu") ) % m_value;
606 cfg->Write( GetKey(), str );
610 protected:
611 uint64& m_value;
615 #ifndef AMULE_DAEMON
617 class Cfg_Colour : public Cfg_Base
619 public:
620 Cfg_Colour(const wxString& key, wxColour& colour)
621 : Cfg_Base(key),
622 m_colour(colour),
623 m_default(CMuleColour(colour).GetULong())
626 virtual void LoadFromFile(wxConfigBase* cfg)
628 long int rgb;
629 cfg->Read(GetKey(), &rgb, m_default);
630 m_colour.Set(rgb);
633 virtual void SaveToFile(wxConfigBase* cfg)
635 cfg->Write(GetKey(), static_cast<long int>(CMuleColour(m_colour).GetULong()));
638 private:
639 wxColour& m_colour;
640 long int m_default;
644 typedef struct {
645 int id;
646 bool available;
647 wxString displayname;
648 wxString name;
649 } LangInfo;
653 * The languages aMule has translation for.
655 * Add new languages here, as this list overrides the one defined in muuli.wdr
657 static LangInfo aMuleLanguages[] = {
658 { wxLANGUAGE_DEFAULT, true, wxEmptyString, wxTRANSLATE("System default") },
659 { wxLANGUAGE_ALBANIAN, true, wxEmptyString, wxTRANSLATE("Albanian") },
660 { wxLANGUAGE_ARABIC, true, wxEmptyString, wxTRANSLATE("Arabic") },
661 { wxLANGUAGE_ASTURIAN, true, wxEmptyString, wxTRANSLATE("Asturian") },
662 { wxLANGUAGE_BASQUE, true, wxEmptyString, wxTRANSLATE("Basque") },
663 { wxLANGUAGE_BULGARIAN, true, wxEmptyString, wxTRANSLATE("Bulgarian") },
664 { wxLANGUAGE_CATALAN, true, wxEmptyString, wxTRANSLATE("Catalan") },
665 { wxLANGUAGE_CHINESE_SIMPLIFIED, true, wxEmptyString, wxTRANSLATE("Chinese (Simplified)") },
666 { wxLANGUAGE_CHINESE_TRADITIONAL, true, wxEmptyString, wxTRANSLATE("Chinese (Traditional)") },
667 { wxLANGUAGE_CROATIAN, true, wxEmptyString, wxTRANSLATE("Croatian") },
668 { wxLANGUAGE_CZECH, true, wxEmptyString, wxTRANSLATE("Czech") },
669 { wxLANGUAGE_DANISH, true, wxEmptyString, wxTRANSLATE("Danish") },
670 { wxLANGUAGE_DUTCH, true, wxEmptyString, wxTRANSLATE("Dutch") },
671 { wxLANGUAGE_ENGLISH_UK, true, wxEmptyString, wxTRANSLATE("English (U.K.)") },
672 { wxLANGUAGE_ESTONIAN, true, wxEmptyString, wxTRANSLATE("Estonian") },
673 { wxLANGUAGE_FINNISH, true, wxEmptyString, wxTRANSLATE("Finnish") },
674 { wxLANGUAGE_FRENCH, true, wxEmptyString, wxTRANSLATE("French") },
675 { wxLANGUAGE_GALICIAN, true, wxEmptyString, wxTRANSLATE("Galician") },
676 { wxLANGUAGE_GERMAN, true, wxEmptyString, wxTRANSLATE("German") },
677 { wxLANGUAGE_GREEK, true, wxEmptyString, wxTRANSLATE("Greek") },
678 { wxLANGUAGE_HEBREW, true, wxEmptyString, wxTRANSLATE("Hebrew") },
679 { wxLANGUAGE_HUNGARIAN, true, wxEmptyString, wxTRANSLATE("Hungarian") },
680 { wxLANGUAGE_ITALIAN, true, wxEmptyString, wxTRANSLATE("Italian") },
681 { wxLANGUAGE_ITALIAN_SWISS, true, wxEmptyString, wxTRANSLATE("Italian (Swiss)") },
682 { wxLANGUAGE_JAPANESE, true, wxEmptyString, wxTRANSLATE("Japanese") },
683 { wxLANGUAGE_KOREAN, true, wxEmptyString, wxTRANSLATE("Korean") },
684 { wxLANGUAGE_LITHUANIAN, true, wxEmptyString, wxTRANSLATE("Lithuanian") },
685 { wxLANGUAGE_NORWEGIAN_NYNORSK, true, wxEmptyString, wxTRANSLATE("Norwegian (Nynorsk)") },
686 { wxLANGUAGE_POLISH, true, wxEmptyString, wxTRANSLATE("Polish") },
687 { wxLANGUAGE_PORTUGUESE, true, wxEmptyString, wxTRANSLATE("Portuguese") },
688 { wxLANGUAGE_PORTUGUESE_BRAZILIAN, true, wxEmptyString, wxTRANSLATE("Portuguese (Brazilian)") },
689 { wxLANGUAGE_RUSSIAN, true, wxEmptyString, wxTRANSLATE("Russian") },
690 { wxLANGUAGE_SLOVENIAN, true, wxEmptyString, wxTRANSLATE("Slovenian") },
691 { wxLANGUAGE_SPANISH, true, wxEmptyString, wxTRANSLATE("Spanish") },
692 { wxLANGUAGE_SWEDISH, true, wxEmptyString, wxTRANSLATE("Swedish") },
693 { wxLANGUAGE_TURKISH, true, wxEmptyString, wxTRANSLATE("Turkish") },
694 { wxLANGUAGE_UKRAINIAN, true, wxEmptyString, wxTRANSLATE("Ukrainian") },
698 typedef Cfg_Int<int> Cfg_PureInt;
700 class Cfg_Lang : public Cfg_PureInt
702 public:
703 Cfg_Lang()
704 : Cfg_PureInt( wxEmptyString, m_selection, 0 )
708 virtual void LoadFromFile(wxConfigBase* WXUNUSED(cfg)) {}
709 virtual void SaveToFile(wxConfigBase* WXUNUSED(cfg)) {}
712 virtual bool TransferFromWindow()
714 if ( Cfg_PureInt::TransferFromWindow() ) {
715 // find wx ID of selected language
716 int i = 0;
717 while (m_selection > 0) {
718 i++;
719 if (aMuleLanguages[i].available) {
720 m_selection--;
723 int id = aMuleLanguages[i].id;
725 // save language selection
726 thePrefs::SetLanguageID(wxLang2Str(id));
728 return true;
731 return false;
735 virtual bool TransferToWindow()
737 wxChoice *langSelector = dynamic_cast<wxChoice*>(m_widget);
738 // clear existing list
739 langSelector->Clear();
741 m_selection = 0;
742 int wxId = StrLang2wx(thePrefs::GetLanguageID());
744 // Find available languages and translate them
745 aMuleLanguages[0].displayname = wxGetTranslation(aMuleLanguages[0].name);
746 for (unsigned int i = 1; i < itemsof(aMuleLanguages); ++i)
748 // This supresses error-messages about invalid locales.
749 wxLogNull logTarget;
750 wxLocale locale_to_check;
752 InitLocale(locale_to_check, aMuleLanguages[i].id);
753 if (locale_to_check.IsOk() && locale_to_check.IsLoaded(wxT(PACKAGE))) {
754 aMuleLanguages[i].displayname = wxString(wxGetTranslation(aMuleLanguages[i].name)) + wxT(" [") + aMuleLanguages[i].name + wxT("]");
755 } else {
756 aMuleLanguages[i].available = false;
760 // Add all available languages and find the index of the selected language.
761 for ( unsigned int i = 0, j = 0; i < itemsof(aMuleLanguages); i++) {
762 if (aMuleLanguages[i].available) {
763 langSelector->Append(aMuleLanguages[i].displayname);
764 if ( aMuleLanguages[i].id == wxId ) {
765 m_selection = j;
767 j++;
771 // Restore original locale
773 wxLocale tmpLocale;
774 InitLocale(tmpLocale, theApp->m_locale.GetLanguage());
777 return Cfg_PureInt::TransferToWindow();
781 protected:
782 int m_selection;
785 #endif /* ! AMULE_DAEMON */
787 class Cfg_Skin : public Cfg_Str
789 public:
790 Cfg_Skin( const wxString& keyname, wxString& value, const wxString& defaultVal = wxEmptyString )
791 : Cfg_Str( keyname, value, defaultVal ),
792 m_is_skin(false)
795 #ifndef AMULE_DAEMON
796 virtual bool TransferFromWindow()
798 if ( Cfg_Str::TransferFromWindow() ) {
799 if (m_is_skin) {
800 wxChoice *skinSelector = dynamic_cast<wxChoice*>(m_widget);
801 // "- default -" is always the first
802 if (skinSelector->GetSelection() == 0) {
803 m_value.Clear();
806 return true;
809 return false;
813 virtual bool TransferToWindow()
816 wxChoice *skinSelector = dynamic_cast<wxChoice*>(m_widget);
817 skinSelector->Clear();
819 wxString folder;
820 int flags = wxDIR_DIRS;
821 wxString filespec = wxEmptyString;
822 //#warning there has to be a better way...
823 if ( GetKey() == wxT("/SkinGUIOptions/Skin") ) {
824 folder = wxT("skins");
825 m_is_skin = true;
826 flags = wxDIR_FILES;
827 filespec = wxT("*.zip");
828 skinSelector->Append(_("- default -"));
829 } else {
830 folder = wxT("webserver");
832 wxString dirName(JoinPaths(GetConfigDir(), folder));
833 wxString Filename;
834 wxDir d;
836 if (wxDir::Exists(dirName) &&
837 d.Open(dirName) &&
838 d.GetFirst(& Filename, filespec, flags)
843 if (m_is_skin) {
844 Filename = wxT("User:") + Filename;
846 skinSelector->Append(Filename);
848 while (d.GetNext(&Filename));
851 wxString dataDir;
852 if (m_is_skin) {
853 dataDir = wxStandardPaths::Get().GetDataDir();
854 } else {
855 dataDir = wxStandardPaths::Get().GetResourcesDir();
857 #if !defined(__WXMSW__) && !defined(__WXMAC__)
858 dataDir = dataDir.BeforeLast(wxT('/')) + wxT("/amule");
859 #endif
860 wxString systemDir(JoinPaths(dataDir,folder));
862 if (wxDir::Exists(systemDir) &&
863 d.Open(systemDir) &&
864 d.GetFirst(& Filename, filespec, flags)
869 if (m_is_skin) {
870 Filename = wxT("System:") + Filename;
872 // avoid duplicates for webserver templates
873 if (skinSelector->FindString(Filename) == wxNOT_FOUND) {
874 skinSelector->Append(Filename);
877 while (d.GetNext(&Filename));
880 if ( skinSelector->GetCount() == 0 ) {
881 skinSelector->Append(_("no options available"));
884 int id = skinSelector->FindString(m_value);
885 if ( id == wxNOT_FOUND ) {
886 id = 0;
888 skinSelector->SetSelection(id);
890 return Cfg_Str::TransferToWindow();
892 #endif /* ! AMULE_DAEMON */
894 protected:
895 bool m_is_skin;
899 /// new implementation
900 CPreferences::CPreferences()
902 srand( wxGetLocalTimeMillis().GetLo() ); // we need random numbers sometimes
904 // load preferences.dat or set standart values
905 wxString fullpath(theApp->ConfigDir + wxT("preferences.dat"));
906 CFile preffile;
907 if (wxFileExists(fullpath)) {
908 if (preffile.Open(fullpath, CFile::read)) {
909 try {
910 preffile.ReadUInt8(); // Version. Value is not used.
911 s_userhash = preffile.ReadHash();
912 } catch (const CSafeIOException& e) {
913 AddDebugLogLineM(true, logGeneral,
914 wxT("Error while reading userhash: ") + e.what());
919 if (s_userhash.IsEmpty()) {
920 for (int i = 0; i < 8; i++) {
921 RawPokeUInt16(s_userhash.GetHash() + (i * 2), rand());
924 Save();
927 // Mark hash as an eMule-type hash
928 // See also CUpDownClient::GetHashType
929 s_userhash[5] = 14;
930 s_userhash[14] = 111;
932 #ifndef CLIENT_GUI
933 LoadPreferences();
934 ReloadSharedFolders();
936 // serverlist adresses
937 CTextFile slistfile;
938 if (slistfile.Open(theApp->ConfigDir + wxT("addresses.dat"), CTextFile::read)) {
939 adresses_list = slistfile.ReadLines();
941 #endif
945 // Gets called at init time
947 void CPreferences::BuildItemList( const wxString& appdir )
949 #ifndef AMULE_DAEMON
950 #define NewCfgItem(ID, COMMAND) s_CfgList[ID] = COMMAND
951 #else
952 int current_id = 0;
953 #define NewCfgItem(ID, COMMAND) s_CfgList[++current_id] = COMMAND
954 #endif /* AMULE_DAEMON */
957 * User settings
959 NewCfgItem(IDC_NICK, (new Cfg_Str( wxT("/eMule/Nick"), s_nick, wxT("http://www.aMule.org") )));
960 #ifndef AMULE_DAEMON
961 NewCfgItem(IDC_LANGUAGE, (new Cfg_Lang()));
962 #endif
965 * Browser options
967 #ifdef __WXMAC__
968 wxString customBrowser = wxT("/usr/bin/open");
969 #else
970 wxString customBrowser; // left empty
971 #endif
973 NewCfgItem(IDC_BROWSERTABS, (new Cfg_Bool( wxT("/Browser/OpenPageInTab"), s_BrowserTab, true )));
974 NewCfgItem(IDC_BROWSERSELF, (new Cfg_Str( wxT("/Browser/CustomBrowserString"), s_CustomBrowser, customBrowser )));
978 * Misc
980 NewCfgItem(IDC_QUEUESIZE, (MkCfg_Int( wxT("/eMule/QueueSizePref"), s_iQueueSize, 50 )));
983 #ifdef __DEBUG__
985 * Debugging
987 NewCfgItem(ID_VERBOSEDEBUG, (new Cfg_Bool( wxT("/eMule/VerboseDebug"), s_bVerbose, false )));
988 #endif
991 * Connection settings
993 NewCfgItem(IDC_MAXUP, (MkCfg_Int( wxT("/eMule/MaxUpload"), s_maxupload, 0 )));
994 NewCfgItem(IDC_MAXDOWN, (MkCfg_Int( wxT("/eMule/MaxDownload"), s_maxdownload, 0 )));
995 NewCfgItem(IDC_SLOTALLOC, (MkCfg_Int( wxT("/eMule/SlotAllocation"), s_slotallocation, 2 )));
996 NewCfgItem(IDC_PORT, (MkCfg_Int( wxT("/eMule/Port"), s_port, DEFAULT_TCP_PORT )));
997 NewCfgItem(IDC_UDPPORT, (MkCfg_Int( wxT("/eMule/UDPPort"), s_udpport, DEFAULT_UDP_PORT )));
998 NewCfgItem(IDC_UDPENABLE, (new Cfg_Bool( wxT("/eMule/UDPEnable"), s_UDPEnable, true )));
999 NewCfgItem(IDC_ADDRESS, (new Cfg_Str( wxT("/eMule/Address"), s_Addr, wxEmptyString)));
1000 NewCfgItem(IDC_AUTOCONNECT, (new Cfg_Bool( wxT("/eMule/Autoconnect"), s_autoconnect, true )));
1001 NewCfgItem(IDC_MAXSOURCEPERFILE, (MkCfg_Int( wxT("/eMule/MaxSourcesPerFile"), s_maxsourceperfile, 300 )));
1002 NewCfgItem(IDC_MAXCON, (MkCfg_Int( wxT("/eMule/MaxConnections"), s_maxconnections, GetRecommendedMaxConnections() )));
1003 NewCfgItem(IDC_MAXCON5SEC, (MkCfg_Int( wxT("/eMule/MaxConnectionsPerFiveSeconds"), s_MaxConperFive, 20 )));
1006 * Proxy
1008 NewCfgItem(ID_PROXY_ENABLE_PROXY, (new Cfg_Bool( wxT("/Proxy/ProxyEnableProxy"), s_ProxyData.m_proxyEnable, false )));
1009 NewCfgItem(ID_PROXY_TYPE, (MkCfg_Int( wxT("/Proxy/ProxyType"), s_ProxyData.m_proxyType, 0 )));
1010 NewCfgItem(ID_PROXY_NAME, (new Cfg_Str( wxT("/Proxy/ProxyName"), s_ProxyData.m_proxyHostName, wxEmptyString )));
1011 NewCfgItem(ID_PROXY_PORT, (MkCfg_Int( wxT("/Proxy/ProxyPort"), s_ProxyData.m_proxyPort, 1080 )));
1012 NewCfgItem(ID_PROXY_ENABLE_PASSWORD, (new Cfg_Bool( wxT("/Proxy/ProxyEnablePassword"), s_ProxyData.m_enablePassword, false )));
1013 NewCfgItem(ID_PROXY_USER, (new Cfg_Str( wxT("/Proxy/ProxyUser"), s_ProxyData.m_userName, wxEmptyString )));
1014 NewCfgItem(ID_PROXY_PASSWORD, (new Cfg_Str( wxT("/Proxy/ProxyPassword"), s_ProxyData.m_password, wxEmptyString )));
1015 // These were copied from eMule config file, maybe someone with windows can complete this?
1016 // NewCfgItem(ID_PROXY_AUTO_SERVER_CONNECT_WITHOUT_PROXY, (new Cfg_Bool( wxT("/Proxy/Proxy????"), s_Proxy????, false )));
1019 * Servers
1020 **/
1021 NewCfgItem(IDC_REMOVEDEAD, (new Cfg_Bool( wxT("/eMule/RemoveDeadServer"), s_deadserver, 1 )));
1022 NewCfgItem(IDC_SERVERRETRIES, (MkCfg_Int( wxT("/eMule/DeadServerRetry"), s_deadserverretries, 3 )));
1023 NewCfgItem(IDC_SERVERKEEPALIVE, (MkCfg_Int( wxT("/eMule/ServerKeepAliveTimeout"), s_dwServerKeepAliveTimeoutMins, 0 )));
1024 NewCfgItem(IDC_RECONN, (new Cfg_Bool( wxT("/eMule/Reconnect"), s_reconnect, true )));
1025 NewCfgItem(IDC_SCORE, (new Cfg_Bool( wxT("/eMule/Scoresystem"), s_scorsystem, true )));
1026 NewCfgItem(IDC_AUTOSERVER, (new Cfg_Bool( wxT("/eMule/Serverlist"), s_autoserverlist, false )));
1027 NewCfgItem(IDC_UPDATESERVERCONNECT, (new Cfg_Bool( wxT("/eMule/AddServerListFromServer"), s_addserversfromserver, false)));
1028 NewCfgItem(IDC_UPDATESERVERCLIENT, (new Cfg_Bool( wxT("/eMule/AddServerListFromClient"), s_addserversfromclient, false )));
1029 NewCfgItem(IDC_SAFESERVERCONNECT, (new Cfg_Bool( wxT("/eMule/SafeServerConnect"), s_safeServerConnect, false )));
1030 NewCfgItem(IDC_AUTOCONNECTSTATICONLY, (new Cfg_Bool( wxT("/eMule/AutoConnectStaticOnly"), s_autoconnectstaticonly, false )));
1031 NewCfgItem(IDC_UPNP_ENABLED, (new Cfg_Bool( wxT("/eMule/UPnPEnabled"), s_UPnPEnabled, false )));
1032 NewCfgItem(IDC_UPNPTCPPORT, (MkCfg_Int( wxT("/eMule/UPnPTCPPort"), s_UPnPTCPPort, 50000 )));
1033 NewCfgItem(IDC_SMARTIDCHECK, (new Cfg_Bool( wxT("/eMule/SmartIdCheck"), s_smartidcheck, true )));
1034 // Enabled networks
1035 NewCfgItem( IDC_NETWORKKAD, (new Cfg_Bool( wxT("/eMule/ConnectToKad"), s_ConnectToKad, true )) );
1036 NewCfgItem( IDC_NETWORKED2K, ( new Cfg_Bool( wxT("/eMule/ConnectToED2K"), s_ConnectToED2K, true ) ));
1040 * Files
1042 NewCfgItem(IDC_TEMPFILES, (new Cfg_Path( wxT("/eMule/TempDir"), s_tempdir, appdir + wxT("Temp") )));
1044 #if defined(__WXMAC__) || defined(__WXMSW__)
1045 wxString incpath = wxStandardPaths::Get().GetDocumentsDir();
1046 if (incpath.IsEmpty()) {
1047 // There is a built-in possibility for this call to fail, though I can't imagine a reason for that.
1048 incpath = appdir + wxT("Incoming");
1049 } else {
1050 incpath = JoinPaths(incpath, wxT("aMule Downloads"));
1052 #else
1053 wxString incpath = appdir + wxT("Incoming");
1054 #endif
1055 NewCfgItem(IDC_INCFILES, (new Cfg_Path( wxT("/eMule/IncomingDir"), s_incomingdir, incpath )));
1057 NewCfgItem(IDC_ICH, (new Cfg_Bool( wxT("/eMule/ICH"), s_ICH, true )));
1058 NewCfgItem(IDC_AICHTRUST, (new Cfg_Bool( wxT("/eMule/AICHTrust"), s_AICHTrustEveryHash, false )));
1059 NewCfgItem(IDC_CHECKDISKSPACE, (new Cfg_Bool( wxT("/eMule/CheckDiskspace"), s_checkDiskspace, true )));
1060 NewCfgItem(IDC_MINDISKSPACE, (MkCfg_Int( wxT("/eMule/MinFreeDiskSpace"), s_uMinFreeDiskSpace, 1 )));
1061 NewCfgItem(IDC_ADDNEWFILESPAUSED, (new Cfg_Bool( wxT("/eMule/AddNewFilesPaused"), s_addnewfilespaused, false )));
1062 NewCfgItem(IDC_PREVIEWPRIO, (new Cfg_Bool( wxT("/eMule/PreviewPrio"), s_bpreviewprio, false )));
1063 NewCfgItem(IDC_MANUALSERVERHIGHPRIO, (new Cfg_Bool( wxT("/eMule/ManualHighPrio"), s_bmanualhighprio, false )));
1064 NewCfgItem(IDC_FULLCHUNKTRANS, (new Cfg_Bool( wxT("/eMule/FullChunkTransfers"), s_btransferfullchunks, true )));
1065 NewCfgItem(IDC_STARTNEXTFILE, (new Cfg_Bool( wxT("/eMule/StartNextFile"), s_bstartnextfile, false )));
1066 NewCfgItem(IDC_STARTNEXTFILE_SAME, (new Cfg_Bool( wxT("/eMule/StartNextFileSameCat"), s_bstartnextfilesame, false )));
1067 NewCfgItem(IDC_SRCSEEDS, (new Cfg_Bool( wxT("/ExternalConnect/UseSrcSeeds"), s_UseSrcSeeds, false )));
1068 NewCfgItem(IDC_FILEBUFFERSIZE, (MkCfg_Int( wxT("/eMule/FileBufferSizePref"), s_iFileBufferSize, 16 )));
1069 NewCfgItem(IDC_DAP, (new Cfg_Bool( wxT("/eMule/DAPPref"), s_bDAP, true )));
1070 NewCfgItem(IDC_UAP, (new Cfg_Bool( wxT("/eMule/UAPPref"), s_bUAP, true )));
1071 NewCfgItem(IDC_ALLOCFULLFILE, (new Cfg_Bool( wxT("/eMule/AllocateFullFile"), s_allocFullFile, false )));
1074 * Web Server
1076 NewCfgItem(IDC_OSDIR, (new Cfg_Path( wxT("/eMule/OSDirectory"), s_OSDirectory, appdir )));
1077 NewCfgItem(IDC_ONLINESIG, (new Cfg_Bool( wxT("/eMule/OnlineSignature"), s_onlineSig, false )));
1078 NewCfgItem(IDC_OSUPDATE, (MkCfg_Int( wxT("/eMule/OnlineSignatureUpdate"), s_OSUpdate, 5 )));
1079 NewCfgItem(IDC_ENABLE_WEB, (new Cfg_Bool( wxT("/WebServer/Enabled"), s_bWebEnabled, false )));
1080 NewCfgItem(IDC_WEB_PASSWD, (new Cfg_Str_Encrypted( wxT("/WebServer/Password"), s_sWebPassword )));
1081 NewCfgItem(IDC_WEB_PASSWD_LOW, (new Cfg_Str_Encrypted( wxT("/WebServer/PasswordLow"), s_sWebLowPassword )));
1082 NewCfgItem(IDC_WEB_PORT, (MkCfg_Int( wxT("/WebServer/Port"), s_nWebPort, 4711 )));
1083 NewCfgItem(IDC_WEBUPNPTCPPORT, (MkCfg_Int( wxT("/WebServer/WebUPnPTCPPort"), s_nWebUPnPTCPPort, 50001 )));
1084 NewCfgItem(IDC_UPNP_WEBSERVER_ENABLED,
1085 (new Cfg_Bool( wxT("/WebServer/UPnPWebServerEnabled"), s_UPnPWebServerEnabled, false )));
1086 NewCfgItem(IDC_WEB_GZIP, (new Cfg_Bool( wxT("/WebServer/UseGzip"), s_bWebUseGzip, true )));
1087 NewCfgItem(IDC_ENABLE_WEB_LOW, (new Cfg_Bool( wxT("/WebServer/UseLowRightsUser"), s_bWebLowEnabled, false )));
1088 NewCfgItem(IDC_WEB_REFRESH_TIMEOUT, (MkCfg_Int( wxT("/WebServer/PageRefreshTime"), s_nWebPageRefresh, 120 )));
1089 NewCfgItem(IDC_WEBTEMPLATE, (new Cfg_Skin( wxT("/WebServer/Template"), s_WebTemplate, wxEmptyString )));
1092 * External Connections
1094 NewCfgItem(IDC_EXT_CONN_ACCEPT, (new Cfg_Bool( wxT("/ExternalConnect/AcceptExternalConnections"), s_AcceptExternalConnections, false )));
1095 NewCfgItem(IDC_EXT_CONN_IP, (new Cfg_Str( wxT("/ExternalConnect/ECAddress"), s_ECAddr, wxEmptyString )));
1096 NewCfgItem(IDC_EXT_CONN_TCP_PORT, (MkCfg_Int( wxT("/ExternalConnect/ECPort"), s_ECPort, 4712 )));
1097 NewCfgItem(IDC_EXT_CONN_PASSWD, (new Cfg_Str_Encrypted( wxT("/ExternalConnect/ECPassword"), s_ECPassword, wxEmptyString )));
1098 NewCfgItem(IDC_UPNP_EC_ENABLED, (new Cfg_Bool( wxT("/ExternalConnect/UPnPECEnabled"), s_UPnPECEnabled, false )));
1101 * GUI behavior
1103 NewCfgItem(IDC_ENABLETRAYICON, (new Cfg_Bool( wxT("/eMule/EnableTrayIcon"), s_trayiconenabled, false )));
1104 NewCfgItem(IDC_MINTRAY, (new Cfg_Bool( wxT("/eMule/MinToTray"), s_mintotray, false )));
1105 NewCfgItem(IDC_EXIT, (new Cfg_Bool( wxT("/eMule/ConfirmExit"), s_confirmExit, true )));
1106 NewCfgItem(IDC_STARTMIN, (new Cfg_Bool( wxT("/eMule/StartupMinimized"), s_startMinimized, false )));
1109 * GUI appearence
1111 NewCfgItem(IDC_3DDEPTH, (MkCfg_Int( wxT("/eMule/3DDepth"), s_depth3D, 10 )));
1112 NewCfgItem(IDC_TOOLTIPDELAY, (MkCfg_Int( wxT("/eMule/ToolTipDelay"), s_iToolDelayTime, 1 )));
1113 NewCfgItem(IDC_SHOWOVERHEAD, (new Cfg_Bool( wxT("/eMule/ShowOverhead"), s_bshowoverhead, false )));
1114 NewCfgItem(IDC_EXTCATINFO, (new Cfg_Bool( wxT("/eMule/ShowInfoOnCatTabs"), s_showCatTabInfos, true )));
1115 NewCfgItem(IDC_FED2KLH, (new Cfg_Bool( wxT("/Razor_Preferences/FastED2KLinksHandler"), s_FastED2KLinksHandler, true )));
1116 NewCfgItem(IDC_PROGBAR, (new Cfg_Bool( wxT("/ExternalConnect/ShowProgressBar"), s_ProgBar, true )));
1117 NewCfgItem(IDC_PERCENT, (new Cfg_Bool( wxT("/ExternalConnect/ShowPercent"), s_Percent, true )));
1118 NewCfgItem(IDC_SKIN, (new Cfg_Skin( wxT("/SkinGUIOptions/Skin"), s_Skin, wxEmptyString )));
1119 NewCfgItem(IDC_VERTTOOLBAR, (new Cfg_Bool( wxT("/eMule/VerticalToolbar"), s_ToolbarOrientation, false )));
1122 * External Apps
1124 NewCfgItem(IDC_VIDEOPLAYER, (new Cfg_Str( wxT("/eMule/VideoPlayer"), s_VideoPlayer, wxEmptyString )));
1125 NewCfgItem(IDC_VIDEOBACKUP, (new Cfg_Bool( wxT("/eMule/VideoPreviewBackupped"), s_moviePreviewBackup, true )));
1128 * Statistics
1130 NewCfgItem(IDC_SLIDER, (MkCfg_Int( wxT("/eMule/StatGraphsInterval"), s_trafficOMeterInterval, 3 )));
1131 NewCfgItem(IDC_SLIDER2, (MkCfg_Int( wxT("/eMule/statsInterval"), s_statsInterval, 30 )));
1132 NewCfgItem(IDC_DOWNLOAD_CAP, (MkCfg_Int( wxT("/eMule/DownloadCapacity"), s_maxGraphDownloadRate, 300 )));
1133 NewCfgItem(IDC_UPLOAD_CAP, (MkCfg_Int( wxT("/eMule/UploadCapacity"), s_maxGraphUploadRate, 100 )));
1134 NewCfgItem(IDC_SLIDER3, (MkCfg_Int( wxT("/eMule/StatsAverageMinutes"), s_statsAverageMinutes, 5 )));
1135 NewCfgItem(IDC_SLIDER4, (MkCfg_Int( wxT("/eMule/VariousStatisticsMaxValue"), s_statsMax, 100 )));
1136 NewCfgItem(IDC_CLIENTVERSIONS, (MkCfg_Int( wxT("/Statistics/MaxClientVersions"), s_maxClientVersions, 0 )));
1139 * Security
1141 NewCfgItem(IDC_SEESHARES, (MkCfg_Int( wxT("/eMule/SeeShare"), s_iSeeShares, 2 )));
1142 NewCfgItem(IDC_SECIDENT, (new Cfg_Bool( wxT("/ExternalConnect/UseSecIdent"), s_SecIdent, true )));
1143 NewCfgItem(IDC_IPFCLIENTS, (new Cfg_Bool( wxT("/ExternalConnect/IpFilterClients"), s_IPFilterClients, true )));
1144 NewCfgItem(IDC_IPFSERVERS, (new Cfg_Bool( wxT("/ExternalConnect/IpFilterServers"), s_IPFilterServers, true )));
1145 NewCfgItem(IDC_FILTERLAN, (new Cfg_Bool( wxT("/eMule/FilterLanIPs"), s_filterLanIP, true )));
1146 NewCfgItem(IDC_PARANOID, (new Cfg_Bool( wxT("/eMule/ParanoidFiltering"), s_paranoidfilter, true )));
1147 NewCfgItem(IDC_AUTOIPFILTER, (new Cfg_Bool( wxT("/eMule/IPFilterAutoLoad"), s_IPFilterAutoLoad, true )));
1148 NewCfgItem(IDC_IPFILTERURL, (new Cfg_Str( wxT("/eMule/IPFilterURL"), s_IPFilterURL, wxEmptyString )));
1149 NewCfgItem(ID_IPFILTERLEVEL, (MkCfg_Int( wxT("/eMule/FilterLevel"), s_filterlevel, 127 )));
1150 NewCfgItem(IDC_IPFILTERSYS, (new Cfg_Bool( wxT("/eMule/IPFilterSystem"), s_IPFilterSys, false )));
1152 /**
1153 * Message Filter
1155 NewCfgItem(IDC_MSGFILTER, (new Cfg_Bool( wxT("/eMule/FilterMessages"), s_MustFilterMessages, true )));
1156 NewCfgItem(IDC_MSGFILTER_ALL, (new Cfg_Bool( wxT("/eMule/FilterAllMessages"), s_FilterAllMessages, false )));
1157 NewCfgItem(IDC_MSGFILTER_NONFRIENDS, (new Cfg_Bool( wxT("/eMule/MessagesFromFriendsOnly"), s_msgonlyfriends, false )));
1158 NewCfgItem(IDC_MSGFILTER_NONSECURE, (new Cfg_Bool( wxT("/eMule/MessageFromValidSourcesOnly"), s_msgsecure, true )));
1159 NewCfgItem(IDC_MSGFILTER_WORD, (new Cfg_Bool( wxT("/eMule/FilterWordMessages"), s_FilterSomeMessages, false )));
1160 NewCfgItem(IDC_MSGWORD, (new Cfg_Str( wxT("/eMule/MessageFilter"), s_MessageFilterString, wxEmptyString )));
1161 NewCfgItem(IDC_MSGLOG, (new Cfg_Bool( wxT("/eMule/ShowMessagesInLog"), s_ShowMessagesInLog, true )));
1162 //Todo NewCfgItem(IDC_MSGADVSPAM, (new Cfg_Bool( wxT("/eMule/AdvancedSpamFilter"), s_IsAdvancedSpamfilterEnabled, true )));
1163 //Todo NewCfgItem(IDC_MSGCAPTCHA, (new Cfg_Bool( wxT("/eMule/MessageUseCaptchas"), s_IsChatCaptchaEnabled, true )));
1164 s_MiscList.push_back( new Cfg_Bool( wxT("/eMule/AdvancedSpamFilter"), s_IsAdvancedSpamfilterEnabled, true ) );
1165 s_MiscList.push_back( new Cfg_Bool( wxT("/eMule/MessageUseCaptchas"), s_IsChatCaptchaEnabled, true ) );
1167 NewCfgItem(IDC_FILTERCOMMENTS, (new Cfg_Bool( wxT("/eMule/FilterComments"), s_FilterComments, false )));
1168 NewCfgItem(IDC_COMMENTWORD, (new Cfg_Str( wxT("/eMule/CommentFilter"), s_CommentFilterString, wxEmptyString )));
1171 * Hidden files sharing
1172 **/
1173 NewCfgItem(IDC_SHAREHIDDENFILES, (new Cfg_Bool( wxT("/eMule/ShareHiddenFiles"), s_ShareHiddenFiles, false )));
1176 * Auto-Sorting of downloads
1178 NewCfgItem(IDC_AUTOSORT, (new Cfg_Bool( wxT("/eMule/AutoSortDownloads"), s_AutoSortDownload, false )));
1181 * Version check
1183 NewCfgItem(IDC_NEWVERSION, (new Cfg_Bool( wxT("/eMule/NewVersionCheck"), s_NewVersionCheck, true )));
1186 * Obfuscation
1189 NewCfgItem( IDC_SUPPORT_PO, ( new Cfg_Bool( wxT("/Obfuscation/IsClientCryptLayerSupported"), s_IsClientCryptLayerSupported, true )));
1190 NewCfgItem( IDC_ENABLE_PO_OUTGOING, ( new Cfg_Bool( wxT("/Obfuscation/IsCryptLayerRequested"), s_bCryptLayerRequested, true )));
1191 NewCfgItem( IDC_ENFORCE_PO_INCOMING, ( new Cfg_Bool( wxT("/Obfuscation/IsClientCryptLayerRequired"), s_IsClientCryptLayerRequired, false )));
1192 // There is no need for GUI items for this two.
1193 s_MiscList.push_back( MkCfg_Int( wxT("/Obfuscation/CryptoPaddingLenght"), s_byCryptTCPPaddingLength, 254 ) );
1194 s_MiscList.push_back( MkCfg_Int( wxT("/Obfuscation/CryptoKadUDPKey"), s_dwKadUDPKey, GetRandomUint32() ) );
1197 * The following doesn't have an associated widget or section
1199 s_MiscList.push_back( new Cfg_Str( wxT("/eMule/Language"), s_languageID ) );
1200 s_MiscList.push_back( new Cfg_Counter( wxT("/Statistics/TotalDownloadedBytes"), s_totalDownloadedBytes ) );
1201 s_MiscList.push_back( new Cfg_Counter( wxT("/Statistics/TotalUploadedBytes"), s_totalUploadedBytes ) );
1202 s_MiscList.push_back( MkCfg_Int( wxT("/eMule/SplitterbarPosition"), s_splitterbarPosition, 75 ) );
1203 s_MiscList.push_back( new Cfg_Str( wxT("/eMule/YourHostname"), s_yourHostname, wxEmptyString ) );
1204 s_MiscList.push_back( new Cfg_Str( wxT("/eMule/DateTimeFormat"), s_datetimeformat, wxT("%A, %x, %X") ) );
1206 s_MiscList.push_back( MkCfg_Int( wxT("/eMule/AllcatType"), s_allcatType, 0 ) );
1207 s_MiscList.push_back( new Cfg_Bool( wxT("/eMule/ShowAllNotCats"), s_showAllNotCats, false ) );
1209 s_MiscList.push_back( MkCfg_Int( wxT("/eMule/SmartIdState"), s_smartidstate, 0 ) );
1211 s_MiscList.push_back( new Cfg_Bool( wxT("/eMule/DropSlowSources"), s_DropSlowSources, false ) );
1213 s_MiscList.push_back( new Cfg_Str( wxT("/eMule/KadNodesUrl"), s_KadURL, wxT("http://emule-inside.net/nodes.dat") ) );
1214 s_MiscList.push_back( new Cfg_Str( wxT("/eMule/Ed2kServersUrl"), s_Ed2kURL, wxT("http://gruk.org/server.met.gz") ) );
1215 s_MiscList.push_back( MkCfg_Int( wxT("/eMule/ShowRatesOnTitle"), s_showRatesOnTitle, 0 ));
1217 s_MiscList.push_back( new Cfg_Bool( wxT("/eMule/GeoIPEnabled"), s_GeoIPEnabled, true ) );
1218 s_MiscList.push_back( new Cfg_Str( wxT("/eMule/GeoLiteCountryUpdateUrl"), s_GeoIPUpdateUrl, wxT("http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz") ) );
1219 wxConfigBase::Get()->DeleteEntry(wxT("/eMule/GeoIPUpdateUrl")); // get rid of the old one for a while
1221 #ifndef AMULE_DAEMON
1222 // Colors have been moved from global prefs to CStatisticsDlg
1223 for ( int i = 0; i < cntStatColors; i++ ) {
1224 wxString str = wxString::Format(wxT("/eMule/StatColor%i"),i);
1225 s_MiscList.push_back( new Cfg_Colour( str, CStatisticsDlg::acrStat[i] ) );
1227 #endif
1229 // User events
1230 for (unsigned int i = 0; i < CUserEvents::GetCount(); ++i) {
1231 // We can't use NewCfgItem here, because we need to find these items
1232 // later, which would be impossible in amuled with NewCfgItem.
1233 // The IDs we assign here are high enough to not cause any collision
1234 // even on the daemon.
1235 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);
1236 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);
1237 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);
1238 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);
1243 void CPreferences::EraseItemList()
1245 while ( s_CfgList.begin() != s_CfgList.end() ) {
1246 delete s_CfgList.begin()->second;
1247 s_CfgList.erase( s_CfgList.begin() );
1250 CFGList::iterator it = s_MiscList.begin();
1251 for ( ; it != s_MiscList.end(); ) {
1252 delete *it;
1253 it = s_MiscList.erase( it );
1258 void CPreferences::LoadAllItems(wxConfigBase* cfg)
1260 #ifndef CLIENT_GUI
1261 // Preserve values from old config. The global config object may not be set yet
1262 // when BuildItemList() is called, so we need to provide defaults later - here.
1263 if (cfg->HasEntry(wxT("/eMule/ExecOnCompletion"))) {
1264 bool ExecOnCompletion;
1265 cfg->Read(wxT("/eMule/ExecOnCompletion"), &ExecOnCompletion, false);
1266 // Assign to core command, that's the most likely it was.
1267 static_cast<Cfg_Bool*>(s_CfgList[USEREVENTS_FIRST_ID + CUserEvents::DownloadCompleted * USEREVENTS_IDS_PER_EVENT + 1])->SetDefault(ExecOnCompletion);
1268 cfg->DeleteEntry(wxT("/eMule/ExecOnCompletion"));
1270 if (cfg->HasEntry(wxT("/eMule/ExecOnCompletionCommand"))) {
1271 wxString ExecOnCompletionCommand;
1272 cfg->Read(wxT("/eMule/ExecOnCompletionCommand"), &ExecOnCompletionCommand, wxEmptyString);
1273 static_cast<Cfg_Str*>(s_CfgList[USEREVENTS_FIRST_ID + CUserEvents::DownloadCompleted * USEREVENTS_IDS_PER_EVENT + 2])->SetDefault(ExecOnCompletionCommand);
1274 cfg->DeleteEntry(wxT("/eMule/ExecOnCompletionCommand"));
1276 #endif
1277 CFGMap::iterator it_a = s_CfgList.begin();
1278 for ( ; it_a != s_CfgList.end(); ++it_a ) {
1279 it_a->second->LoadFromFile( cfg );
1282 CFGList::iterator it_b = s_MiscList.begin();
1283 for ( ; it_b != s_MiscList.end(); ++it_b ) {
1284 (*it_b)->LoadFromFile( cfg );
1287 // Preserve old value of UDPDisable
1288 if (cfg->HasEntry(wxT("/eMule/UDPDisable"))) {
1289 bool UDPDisable;
1290 cfg->Read(wxT("/eMule/UDPDisable"), &UDPDisable, false);
1291 SetUDPDisable(UDPDisable);
1292 cfg->DeleteEntry(wxT("/eMule/UDPDisable"));
1295 // Preserve old value of UseSkinFiles
1296 if (cfg->HasEntry(wxT("/SkinGUIOptions/UseSkinFiles"))) {
1297 bool UseSkinFiles;
1298 cfg->Read(wxT("/SkinGUIOptions/UseSkinFiles"), &UseSkinFiles, false);
1299 if (!UseSkinFiles) {
1300 s_Skin.Clear();
1302 cfg->DeleteEntry(wxT("/SkinGUIOptions/UseSkinFiles"));
1305 #ifdef __DEBUG__
1306 // Load debug-categories
1307 int count = theLogger.GetDebugCategoryCount();
1309 for ( int i = 0; i < count; i++ ) {
1310 const CDebugCategory& cat = theLogger.GetDebugCategory( i );
1312 bool enabled = false;
1313 cfg->Read( wxT("/Debug/Cat_") + cat.GetName(), &enabled );
1315 theLogger.SetEnabled( cat.GetType(), enabled );
1317 #endif
1319 // Now do some post-processing / sanity checking on the values we just loaded
1320 CheckUlDlRatio();
1321 SetPort(s_port);
1322 if (s_byCryptTCPPaddingLength > 254) {
1323 s_byCryptTCPPaddingLength = GetRandomUint8() % 254;
1325 SetSlotAllocation(s_slotallocation);
1329 void CPreferences::SaveAllItems(wxConfigBase* cfg)
1331 // Save the Cfg values
1332 CFGMap::iterator it_a = s_CfgList.begin();
1333 for ( ; it_a != s_CfgList.end(); ++it_a )
1334 it_a->second->SaveToFile( cfg );
1336 CFGList::iterator it_b = s_MiscList.begin();
1337 for ( ; it_b != s_MiscList.end(); ++it_b )
1338 (*it_b)->SaveToFile( cfg );
1341 // Save debug-categories
1342 #ifdef __DEBUG__
1343 int count = theLogger.GetDebugCategoryCount();
1345 for ( int i = 0; i < count; i++ ) {
1346 const CDebugCategory& cat = theLogger.GetDebugCategory( i );
1348 cfg->Write( wxT("/Debug/Cat_") + cat.GetName(), cat.IsEnabled() );
1350 #endif
1353 void CPreferences::SetMaxUpload(uint16 in)
1355 if ( s_maxupload != in ) {
1356 s_maxupload = in;
1358 // Ensure that the ratio is upheld
1359 CheckUlDlRatio();
1364 void CPreferences::SetMaxDownload(uint16 in)
1366 if ( s_maxdownload != in ) {
1367 s_maxdownload = in;
1369 // Ensure that the ratio is upheld
1370 CheckUlDlRatio();
1375 void CPreferences::UnsetAutoServerStart()
1377 s_autoserverlist = false;
1381 // Here we slightly limit the users' ability to be a bad citizen: for very low upload rates
1382 // we force a low download rate, so as to discourage this type of leeching.
1383 // We're Open Source, and whoever wants it can do his own mod to get around this, but the
1384 // packaged product will try to enforce good behavior.
1386 // Kry note: of course, any leecher mod will be banned asap.
1387 void CPreferences::CheckUlDlRatio()
1389 // Backwards compatibility
1390 if ( s_maxupload == 0xFFFF )
1391 s_maxupload = UNLIMITED;
1393 // Backwards compatibility
1394 if ( s_maxdownload == 0xFFFF )
1395 s_maxdownload = UNLIMITED;
1397 if ( s_maxupload == UNLIMITED )
1398 return;
1400 // Enforce the limits
1401 if ( s_maxupload < 4 ) {
1402 if ( ( s_maxupload * 3 < s_maxdownload ) || ( s_maxdownload == 0 ) )
1403 s_maxdownload = s_maxupload * 3 ;
1404 } else if ( s_maxupload < 10 ) {
1405 if ( ( s_maxupload * 4 < s_maxdownload ) || ( s_maxdownload == 0 ) )
1406 s_maxdownload = s_maxupload * 4;
1411 void CPreferences::Save()
1413 wxString fullpath(theApp->ConfigDir + wxT("preferences.dat"));
1415 CFile preffile;
1416 if (!wxFileExists(fullpath)) {
1417 preffile.Create(fullpath);
1420 if (preffile.Open(fullpath, CFile::read_write)) {
1421 try {
1422 preffile.WriteUInt8(PREFFILE_VERSION);
1423 preffile.WriteHash(s_userhash);
1424 } catch (const CIOFailureException& e) {
1425 AddDebugLogLineM(true, logGeneral, wxT("IO failure while saving user-hash: ") + e.what());
1429 SavePreferences();
1431 #ifndef CLIENT_GUI
1432 CTextFile sdirfile;
1433 if (sdirfile.Open(theApp->ConfigDir + wxT("shareddir.dat"), CTextFile::write)) {
1434 for (size_t i = 0; i < shareddir_list.size(); ++i) {
1435 sdirfile.WriteLine(CPath::ToUniv(shareddir_list[i]), wxConvUTF8);
1439 #endif
1443 CPreferences::~CPreferences()
1445 while ( !m_CatList.empty() ) {
1446 delete m_CatList.front();
1447 m_CatList.erase( m_CatList.begin() );
1450 m_CatList.clear();
1454 int32 CPreferences::GetRecommendedMaxConnections()
1456 #ifndef CLIENT_GUI
1457 int iRealMax = PlatformSpecific::GetMaxConnections();
1458 if(iRealMax == -1 || iRealMax > 520) {
1459 return 500;
1461 if(iRealMax < 20) {
1462 return iRealMax;
1464 if(iRealMax <= 256) {
1465 return iRealMax - 10;
1467 return iRealMax - 20;
1468 #else
1469 return 500;
1470 #endif
1474 void CPreferences::SavePreferences()
1476 wxConfigBase* cfg = wxConfigBase::Get();
1478 cfg->Write( wxT("/eMule/AppVersion"), wxT(VERSION) );
1480 // Save the options
1481 SaveAllItems( cfg );
1483 // Ensure that the changes are saved to disk.
1484 cfg->Flush();
1488 void CPreferences::SaveCats()
1490 if ( GetCatCount() ) {
1491 wxConfigBase* cfg = wxConfigBase::Get();
1493 // Save the main cat.
1494 cfg->Write( wxT("/eMule/AllcatType"), (int)s_allcatType);
1496 // The first category is the default one and should not be counted
1498 cfg->Write( wxT("/General/Count"), (long)(m_CatList.size() - 1) );
1500 for ( size_t i = 1; i < m_CatList.size(); i++ ) {
1501 cfg->SetPath( wxString::Format(wxT("/Cat#%i"), i) );
1503 cfg->Write( wxT("Title"), m_CatList[i]->title );
1504 cfg->Write( wxT("Incoming"), CPath::ToUniv(m_CatList[i]->path) );
1505 cfg->Write( wxT("Comment"), m_CatList[i]->comment );
1506 cfg->Write( wxT("Color"), wxString::Format(wxT("%u"), m_CatList[i]->color) );
1507 cfg->Write( wxT("Priority"), (int)m_CatList[i]->prio );
1510 cfg->Flush();
1515 void CPreferences::LoadPreferences()
1517 LoadCats();
1521 void CPreferences::LoadCats()
1523 // default cat ... Meow! =(^.^)=
1524 Category_Struct* defaultcat = new Category_Struct;
1525 defaultcat->prio = 0;
1526 defaultcat->color = 0;
1528 AddCat( defaultcat );
1530 wxConfigBase* cfg = wxConfigBase::Get();
1532 long max = cfg->Read( wxT("/General/Count"), 0l );
1534 for ( int i = 1; i <= max ; i++ ) {
1535 cfg->SetPath( wxString::Format(wxT("/Cat#%i"), i) );
1537 Category_Struct* newcat = new Category_Struct;
1539 newcat->title = cfg->Read( wxT("Title"), wxEmptyString );
1540 newcat->path = CPath::FromUniv(cfg->Read(wxT("Incoming"), wxEmptyString));
1542 // Some sainity checking
1543 if ( newcat->title.IsEmpty() || !newcat->path.IsOk() ) {
1544 AddLogLineN(_("Invalid category found, skipping"));
1546 delete newcat;
1547 continue;
1550 newcat->comment = cfg->Read( wxT("Comment"), wxEmptyString );
1551 newcat->prio = cfg->Read( wxT("Priority"), 0l );
1552 newcat->color = StrToULong(cfg->Read(wxT("Color"), wxT("0")));
1554 AddCat(newcat);
1556 if (!newcat->path.DirExists()) {
1557 CPath::MakeDir(newcat->path);
1563 uint16 CPreferences::GetDefaultMaxConperFive()
1565 return MAXCONPER5SEC;
1569 uint32 CPreferences::AddCat(Category_Struct* cat)
1571 m_CatList.push_back( cat );
1573 return m_CatList.size() - 1;
1577 void CPreferences::RemoveCat(size_t index)
1579 if ( index < m_CatList.size() ) {
1580 CatList::iterator it = m_CatList.begin() + index;
1582 delete *it;
1584 m_CatList.erase( it );
1589 uint32 CPreferences::GetCatCount()
1591 return m_CatList.size();
1595 Category_Struct* CPreferences::GetCategory(size_t index)
1597 wxASSERT( index < m_CatList.size() );
1599 return m_CatList[index];
1603 const CPath& CPreferences::GetCatPath(uint8 index)
1605 wxASSERT( index < m_CatList.size() );
1607 return m_CatList[index]->path;
1611 uint32 CPreferences::GetCatColor(size_t index)
1613 wxASSERT( index < m_CatList.size() );
1615 return m_CatList[index]->color;
1618 Category_Struct *CPreferences::CreateCategory(
1619 const wxString& name,
1620 const CPath& path,
1621 const wxString& comment,
1622 uint32 color,
1623 uint8 prio)
1625 Category_Struct *category = new Category_Struct();
1626 category->path = path;
1627 category->title = name;
1628 category->comment = comment;
1629 category->color = color;
1630 category->prio = prio;
1632 AddCat(category);
1634 SaveCats();
1636 return category;
1639 void CPreferences::UpdateCategory(
1640 uint8 cat,
1641 const wxString& name,
1642 const CPath& path,
1643 const wxString& comment,
1644 uint32 color,
1645 uint8 prio)
1647 Category_Struct *category = m_CatList[cat];
1649 category->path = path;
1650 category->title = name;
1651 category->comment = comment;
1652 category->color = color;
1653 category->prio = prio;
1655 SaveCats();
1659 wxString CPreferences::GetBrowser()
1661 wxString cmd(s_CustomBrowser);
1662 #ifndef __WXMSW__
1663 if( s_BrowserTab ) {
1664 // This is certainly not the best way to do it, but I'm lazy
1665 if ((wxT("mozilla") == cmd.Right(7)) || (wxT("firefox") == cmd.Right(7))
1666 || (wxT("MozillaFirebird") == cmd.Right(15))) {
1667 cmd += wxT(" -remote 'openURL(%s, new-tab)'");
1669 if ((wxT("galeon") == cmd.Right(6)) || (wxT("epiphany") == cmd.Right(8))) {
1670 cmd += wxT(" -n '%s'");
1672 if (wxT("opera") == cmd.Right(5)) {
1673 cmd += wxT(" --newpage '%s'");
1675 if (wxT("netscape") == cmd.Right(8)) {
1676 cmd += wxT(" -remote 'openURLs(%s,new-tab)'");
1679 #endif /* !__WXMSW__ */
1680 return cmd;
1684 #include "ClientList.h"
1685 #include "ServerList.h"
1686 void CPreferences::SetIPFilterLevel(uint8 level)
1688 if (level != s_filterlevel) {
1689 // We only need to recheck if the new level is more restrictive
1690 bool filter = level > s_filterlevel;
1692 // Set the new access-level
1693 s_filterlevel = level;
1695 if ( filter ) {
1696 theApp->clientlist->FilterQueues();
1697 theApp->serverlist->FilterServers();
1703 void CPreferences::SetPort(uint16 val)
1705 // Warning: Check for +3, because server UDP is TCP+3
1707 if (val +3 > 65535) {
1708 AddLogLineM(true, _("TCP port can't be higher than 65532 due to server UDP socket being TCP+3"));
1709 AddLogLineM(false, wxString::Format(_("Default port will be used (%d)"),DEFAULT_TCP_PORT));
1710 s_port = DEFAULT_TCP_PORT;
1711 } else {
1712 s_port = val;
1717 void CPreferences::ReloadSharedFolders()
1719 #ifndef CLIENT_GUI
1720 shareddir_list.clear();
1722 CTextFile file;
1723 if (file.Open(theApp->ConfigDir + wxT("shareddir.dat"), CTextFile::read)) {
1724 wxArrayString lines = file.ReadLines(txtReadDefault, wxConvUTF8);
1726 for (size_t i = 0; i < lines.size(); ++i) {
1727 CPath path = CPath::FromUniv(lines[i]);
1729 if (path.DirExists()) {
1730 shareddir_list.push_back(path);
1731 } else {
1732 AddLogLineN(CFormat(_("Dropping non-existing shared directory: %s")) % path.GetRaw());
1736 #endif
1740 bool CPreferences::IsMessageFiltered(const wxString& message)
1742 if (s_FilterAllMessages) {
1743 return true;
1744 } else {
1745 if (s_FilterSomeMessages) {
1746 if (s_MessageFilterString.IsSameAs(wxT("*"))){
1747 // Filter anything
1748 return true;
1749 } else {
1750 wxStringTokenizer tokenizer( s_MessageFilterString, wxT(",") );
1751 while (tokenizer.HasMoreTokens()) {
1752 if ( message.Lower().Trim(false).Trim(true).Contains(
1753 tokenizer.GetNextToken().Lower().Trim(false).Trim(true))) {
1754 return true;
1757 return false;
1759 } else {
1760 return false;
1766 bool CPreferences::IsCommentFiltered(const wxString& comment)
1768 if (s_FilterComments) {
1769 wxStringTokenizer tokenizer( s_CommentFilterString, wxT(",") );
1770 while (tokenizer.HasMoreTokens()) {
1771 if ( comment.Lower().Trim(false).Trim(true).Contains(
1772 tokenizer.GetNextToken().Lower().Trim(false).Trim(true))) {
1773 return true;
1777 return false;
1780 // File_checked_for_headers