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. 10// 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. 15// 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 24// 25 26#include <wx/wx.h> 27#include "Preferences.h" 28 29#include <protocol/ed2k/Constants.h> 30#include <common/Constants.h> 31#include <common/DataFileVersion.h> 32 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 39 40#include "amule.h" 41#ifdef HAVE_CONFIG_H 42 #include "config.h" // Needed for PACKAGE_STRING 43#endif 44 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> 51 52#include "UserEvents.h" 53 54#ifndef AMULE_DAEMON 55#include <wx/valgen.h> 56#include "muuli_wdr.h" 57#include "StatisticsDlg.h" 58#include "MuleColour.h" 59#endif 60 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 66 67// Needed for IP filtering prefs 68#include "ClientList.h" 69#include "ServerList.h" 70#include "GuiEvents.h" 71 72#define DEFAULT_TCP_PORT 4662 73#define DEFAULT_UDP_PORT 4672 74 75// Static variables 76unsigned long CPreferences::s_colors[cntStatColors]; 77unsigned long CPreferences::s_colors_ref[cntStatColors]; 78 79CPreferences::CFGMap CPreferences::s_CfgList; 80CPreferences::CFGList CPreferences::s_MiscList; 81 82 83/* Proxy */ 84CProxyData CPreferences::s_ProxyData; 85 86/* The rest, organize it! */ 87wxString CPreferences::s_nick; 88Cfg_Lang_Base * CPreferences::s_cfgLang; 89uint16 CPreferences::s_maxupload; 90uint16 CPreferences::s_maxdownload; 91uint16 CPreferences::s_slotallocation; 92wxString CPreferences::s_Addr; 93uint16 CPreferences::s_port; 94uint16 CPreferences::s_udpport; 95bool CPreferences::s_UDPEnable; 96uint16 CPreferences::s_maxconnections; 97bool CPreferences::s_reconnect; 98bool CPreferences::s_autoconnect; 99bool CPreferences::s_autoconnectstaticonly; 100bool CPreferences::s_UPnPEnabled; 101bool CPreferences::s_UPnPECEnabled; 102bool CPreferences::s_UPnPWebServerEnabled; 103uint16 CPreferences::s_UPnPTCPPort; 104bool CPreferences::s_autoserverlist; 105bool CPreferences::s_deadserver; 106CPath CPreferences::s_incomingdir; 107CPath CPreferences::s_tempdir; 108bool CPreferences::s_ICH; 109uint8 CPreferences::s_depth3D; 110bool CPreferences::s_scorsystem; 111bool CPreferences::s_hideonclose; 112bool CPreferences::s_mintotray; 113bool CPreferences::s_trayiconenabled; 114bool CPreferences::s_addnewfilespaused; 115bool CPreferences::s_addserversfromserver; 116bool CPreferences::s_addserversfromclient; 117uint16 CPreferences::s_maxsourceperfile; 118uint16 CPreferences::s_trafficOMeterInterval; 119uint16 CPreferences::s_statsInterval; 120uint32 CPreferences::s_maxGraphDownloadRate; 121uint32 CPreferences::s_maxGraphUploadRate; 122bool CPreferences::s_confirmExit; 123bool CPreferences::s_filterLanIP; 124bool CPreferences::s_paranoidfilter; 125bool CPreferences::s_IPFilterSys; 126bool CPreferences::s_onlineSig; 127uint16 CPreferences::s_OSUpdate; 128wxString CPreferences::s_languageID; 129uint8 CPreferences::s_iSeeShares; 130uint8 CPreferences::s_iToolDelayTime; 131uint8 CPreferences::s_splitterbarPosition; 132uint16 CPreferences::s_deadserverretries; 133uint32 CPreferences::s_dwServerKeepAliveTimeoutMins; 134uint8 CPreferences::s_statsMax; 135uint8 CPreferences::s_statsAverageMinutes; 136bool CPreferences::s_bpreviewprio; 137bool CPreferences::s_smartidcheck; 138uint8 CPreferences::s_smartidstate; 139bool CPreferences::s_safeServerConnect; 140bool CPreferences::s_startMinimized; 141uint16 CPreferences::s_MaxConperFive; 142bool CPreferences::s_checkDiskspace; 143uint32 CPreferences::s_uMinFreeDiskSpace; 144wxString CPreferences::s_yourHostname; 145bool CPreferences::s_bVerbose; 146bool CPreferences::s_bmanualhighprio; 147bool CPreferences::s_bstartnextfile; 148bool CPreferences::s_bstartnextfilesame; 149bool CPreferences::s_bstartnextfilealpha; 150bool CPreferences::s_bshowoverhead; 151bool CPreferences::s_bDAP; 152bool CPreferences::s_bUAP; 153#ifndef __SVN__ 154bool CPreferences::s_showVersionOnTitle; 155#endif 156uint8_t CPreferences::s_showRatesOnTitle; 157wxString CPreferences::s_VideoPlayer; 158bool CPreferences::s_showAllNotCats; 159bool CPreferences::s_msgonlyfriends; 160bool CPreferences::s_msgsecure; 161uint8 CPreferences::s_filterlevel; 162uint8 CPreferences::s_iFileBufferSize; 163uint8 CPreferences::s_iQueueSize; 164wxString CPreferences::s_datetimeformat; 165wxString CPreferences::s_sWebPath; 166wxString CPreferences::s_sWebPassword; 167wxString CPreferences::s_sWebLowPassword; 168uint16 CPreferences::s_nWebPort; 169uint16 CPreferences::s_nWebUPnPTCPPort; 170bool CPreferences::s_bWebEnabled; 171bool CPreferences::s_bWebUseGzip; 172uint32 CPreferences::s_nWebPageRefresh; 173bool CPreferences::s_bWebLowEnabled; 174wxString CPreferences::s_WebTemplate; 175bool CPreferences::s_showCatTabInfos; 176AllCategoryFilter CPreferences::s_allcatFilter; 177uint8 CPreferences::s_NoNeededSources; 178bool CPreferences::s_DropFullQueueSources; 179bool CPreferences::s_DropHighQueueRankingSources; 180uint32 CPreferences::s_HighQueueRanking; 181uint32 CPreferences::s_AutoDropTimer; 182bool CPreferences::s_AcceptExternalConnections; 183wxString CPreferences::s_ECAddr; 184uint32 CPreferences::s_ECPort; 185wxString CPreferences::s_ECPassword; 186bool CPreferences::s_TransmitOnlyUploadingClients; 187bool CPreferences::s_IPFilterClients; 188bool CPreferences::s_IPFilterServers; 189bool CPreferences::s_UseSrcSeeds; 190bool CPreferences::s_ProgBar; 191bool CPreferences::s_Percent; 192bool CPreferences::s_SecIdent; 193bool CPreferences::s_ExtractMetaData; 194bool CPreferences::s_allocFullFile; 195wxString CPreferences::s_CustomBrowser; 196bool CPreferences::s_BrowserTab; 197CPath CPreferences::s_OSDirectory; 198wxString CPreferences::s_Skin; 199bool CPreferences::s_FastED2KLinksHandler; 200bool CPreferences::s_ToolbarOrientation; 201bool CPreferences::s_AICHTrustEveryHash; 202wxString CPreferences::s_CommentFilterString; 203bool CPreferences::s_IPFilterAutoLoad; 204wxString CPreferences::s_IPFilterURL; 205CMD4Hash CPreferences::s_userhash; 206bool CPreferences::s_MustFilterMessages; 207wxString CPreferences::s_MessageFilterString; 208bool CPreferences::s_FilterAllMessages; 209bool CPreferences::s_FilterComments; 210bool CPreferences::s_FilterSomeMessages; 211bool CPreferences::s_ShowMessagesInLog; 212bool CPreferences::s_IsAdvancedSpamfilterEnabled; 213bool CPreferences::s_IsChatCaptchaEnabled; 214bool CPreferences::s_ShareHiddenFiles; 215bool CPreferences::s_AutoSortDownload; 216bool CPreferences::s_NewVersionCheck; 217bool CPreferences::s_ConnectToKad; 218bool CPreferences::s_ConnectToED2K; 219unsigned CPreferences::s_maxClientVersions; 220bool CPreferences::s_DropSlowSources; 221bool CPreferences::s_IsClientCryptLayerSupported; 222bool CPreferences::s_bCryptLayerRequested; 223bool CPreferences::s_IsClientCryptLayerRequired; 224uint32 CPreferences::s_dwKadUDPKey; 225uint8 CPreferences::s_byCryptTCPPaddingLength; 226 227wxString CPreferences::s_Ed2kURL; 228wxString CPreferences::s_KadURL; 229bool CPreferences::s_GeoIPEnabled; 230wxString CPreferences::s_GeoIPUpdateUrl; 231bool CPreferences::s_preventSleepWhileDownloading; 232wxString CPreferences::s_StatsServerName; 233wxString CPreferences::s_StatsServerURL; 234 235/** 236 * Template Cfg class for connecting with widgets. 237 * 238 * This template provides the base functionionality needed to syncronize a 239 * variable with a widget. However, please note that wxGenericValidator only 240 * supports a few types (int, wxString, bool and wxArrayInt), so this template 241 * can't always be used directly. 242 * 243 * Cfg_Str and Cfg_Bool are able to use this template directly, whereas Cfg_Int 244 * makes use of serveral workaround to enable it to be used with integers other 245 * than int. 246 */ 247template <typename TYPE> 248class Cfg_Tmpl : public Cfg_Base 249{ 250public: 251 /** 252 * Constructor. 253 * 254 * @param keyname 255 * @param value 256 * @param defaultVal 257 */ 258 Cfg_Tmpl( const wxString& keyname, TYPE& value, const TYPE& defaultVal ) 259 : Cfg_Base( keyname ), 260 m_value( value ), 261 m_default( defaultVal ), 262 m_widget( NULL ) 263 {} 264 265#ifndef AMULE_DAEMON 266 /** 267 * Connects the Cfg to a widget. 268 * 269 * @param id The ID of the widget to be connected. 270 * @param parent The parent of the widget. Use this to speed up searches. 271 * 272 * This function works by setting the wxValidator of the class. This however 273 * poses some restrictions on which variable types can be used for this 274 * template, as noted above. It also poses some limits on the widget types, 275 * refer to the wx documentation for those. 276 */ 277 virtual bool ConnectToWidget( int id, wxWindow* parent = NULL ) 278 { 279 if ( id ) { 280 m_widget = wxWindow::FindWindowById( id, parent ); 281 282 if ( m_widget ) { 283 wxGenericValidator validator( &m_value ); 284 285 m_widget->SetValidator( validator ); 286 287 return true; 288 } 289 } else { 290 m_widget = NULL; 291 } 292 293 return false; 294 } 295 296 297 /** Updates the assosiated variable, returning true on success. */ 298 virtual bool TransferFromWindow() 299 { 300 if ( m_widget ) { 301 wxValidator* validator = m_widget->GetValidator(); 302 303 if ( validator ) { 304 TYPE temp = m_value; 305 306 if ( validator->TransferFromWindow() ) { 307 SetChanged( temp != m_value ); 308 309 return true; 310 } 311 } 312 } 313 314 return false; 315 } 316 317 /** Updates the assosiated widget, returning true on success. */ 318 virtual bool TransferToWindow() 319 { 320 if ( m_widget ) { 321 wxValidator* validator = m_widget->GetValidator(); 322 323 if ( validator ) 324 return validator->TransferToWindow(); 325 } 326 327 return false; 328 } 329 330#endif 331 332 /** Sets the default value. */ 333 void SetDefault(const TYPE& defaultVal) 334 { 335 m_default = defaultVal; 336 } 337 338protected: 339 //! Reference to the associated variable 340 TYPE& m_value; 341 342 //! Default variable value 343 TYPE m_default; 344 345 //! Pointer to the widget assigned to the Cfg instance 346 wxWindow* m_widget; 347}; 348 349 350/** Cfg class for wxStrings. */ 351class Cfg_Str : public Cfg_Tmpl<wxString> 352{ 353public: 354 /** Constructor. */ 355 Cfg_Str( const wxString& keyname, wxString& value, const wxString& defaultVal = EmptyString ) 356 : Cfg_Tmpl<wxString>( keyname, value, defaultVal ) 357 {} 358 359 /** Loads the string, using the specified default value. */ 360 virtual void LoadFromFile(wxConfigBase* cfg) 361 { 362 cfg->Read( GetKey(), &m_value, m_default ); 363 } 364 365 366 /** Saves the string to the specified wxConfig object. */ 367 virtual void SaveToFile(wxConfigBase* cfg) 368 { 369 cfg->Write( GetKey(), m_value ); 370 } 371}; 372 373 374/** 375 * Cfg-class for encrypting strings, for example for passwords. 376 */ 377class Cfg_Str_Encrypted : public Cfg_Str 378{ 379public: 380 Cfg_Str_Encrypted( const wxString& keyname, wxString& value, const wxString& defaultVal = EmptyString ) 381 : Cfg_Str( keyname, value, defaultVal ) 382 {} 383 384#ifndef AMULE_DAEMON 385 virtual bool TransferFromWindow() 386 { 387 // Shakraw: when storing value, store it encrypted here (only if changed in prefs) 388 if ( Cfg_Str::TransferFromWindow() ) { 389 390 // Only recalucate the hash for new, non-empty passwords 391 if ( HasChanged() && !m_value.IsEmpty() ) { 392 m_value = MD5Sum( m_value ).GetHash(); 393 } 394 395 return true; 396 } 397 398 399 return false; 400 } 401#endif 402}; 403 404 405/** Cfg class for CPath. */ 406class Cfg_Path : public Cfg_Str 407{ 408public: 409 /** Constructor. */ 410 Cfg_Path(const wxString& keyname, CPath& value, const wxString& defaultVal = EmptyString ) 411 : Cfg_Str(keyname, m_temp_path, defaultVal) 412 , m_real_path(value) 413 {} 414 415 /** @see Cfg_Str::LoadFromFile. */ 416 virtual void LoadFromFile(wxConfigBase* cfg) 417 { 418 Cfg_Str::LoadFromFile(cfg); 419 420 m_real_path = CPath::FromUniv(m_temp_path); 421 } 422 423 424 /** @see Cfg_Str::SaveToFile. */ 425 virtual void SaveToFile(wxConfigBase* cfg) 426 { 427 m_temp_path = CPath::ToUniv(m_real_path); 428 429 Cfg_Str::SaveToFile(cfg); 430 } 431 432 433 /** @see Cfg_Tmpl::TransferToWindow. */ 434 virtual bool TransferToWindow() 435 { 436 m_temp_path = m_real_path.GetRaw(); 437 438 return Cfg_Str::TransferToWindow(); 439 } 440 441 /** @see Cfg_Tmpl::TransferFromWindow. */ 442 virtual bool TransferFromWindow() 443 { 444 if (Cfg_Str::TransferFromWindow()) { 445 m_real_path = CPath(m_temp_path); 446 return true; 447 } 448 449 return false; 450 } 451 452private: 453 wxString m_temp_path; 454 CPath& m_real_path; 455}; 456 457 458/** 459 * Cfg class that takes care of integer types. 460 * 461 * This template is needed since wxValidator only supports normals ints, and 462 * wxConfig for the matter only supports longs, thus some worksarounds are 463 * needed. 464 * 465 * There are two work-arounds: 466 * 1) wxValidator only supports int*, so we need a immediate variable to act 467 * as a storage. Thus we use Cfg_Tmpl<int> as base class. Thus this class 468 * contains a integer which we use to pass the value back and forth 469 * between the widgets. 470 * 471 * 2) wxConfig uses longs to save and read values, thus we need an immediate 472 * stage when loading and saving the value. 473 */ 474template <typename TYPE> 475class Cfg_Int : public Cfg_Tmpl<int> 476{ 477public: 478 Cfg_Int( const wxString& keyname, TYPE& value, int defaultVal = 0 ) 479 : Cfg_Tmpl<int>( keyname, m_temp_value, defaultVal ), 480 m_real_value( value ), 481 m_temp_value( value ) 482 {} 483 484 485 virtual void LoadFromFile(wxConfigBase* cfg) 486 { 487 long tmp = 0; 488 cfg->Read( GetKey(), &tmp, m_default ); 489 490 // Set the temp value 491 m_temp_value = (int)tmp; 492 // Set the actual value 493 m_real_value = (TYPE)tmp; 494 } 495 496 virtual void SaveToFile(wxConfigBase* cfg) 497 { 498 cfg->Write( GetKey(), (long)m_real_value ); 499 } 500 501 502#ifndef AMULE_DAEMON 503 virtual bool TransferFromWindow() 504 { 505 if ( Cfg_Tmpl<int>::TransferFromWindow() ) { 506 m_real_value = (TYPE)m_temp_value; 507 508 return true; 509 } 510 511 return false; 512 } 513 514 virtual bool TransferToWindow() 515 { 516 m_temp_value = (int)m_real_value; 517 518 if ( Cfg_Tmpl<int>::TransferToWindow() ) { 519 520 // In order to let us update labels on slider-changes, we trigger a event 521 wxSlider *slider = dynamic_cast<wxSlider *>(m_widget); 522 if (slider) { 523 int id = m_widget->GetId(); 524 int pos = slider->GetValue(); 525 wxScrollEvent evt( wxEVT_SCROLL_THUMBRELEASE, id, pos ); 526 m_widget->GetEventHandler()->ProcessEvent( evt ); 527 } 528 529 return true; 530 } 531 532 return false; 533 } 534#endif 535 536protected: 537 538 TYPE& m_real_value; 539 int m_temp_value; 540}; 541 542 543/** 544 * Helper function for creating new Cfg_Ints. 545 * 546 * @param keyname The cfg-key under which the item should be saved. 547 * @param value The variable to syncronize. The type of this variable defines the type used to create the Cfg_Int. 548 * @param defaultVal The default value if the key isn't found when loading the value. 549 * @return A pointer to the new Cfg_Int object. The caller is responsible for deleting it. 550 * 551 * This template-function returns a Cfg_Int of the appropriate type for the 552 * variable used as argument and should be used to avoid having to specify 553 * the integer type when adding a new Cfg_Int, since that's just increases 554 * the maintainence burden. 555 */ 556template <class TYPE> 557Cfg_Base* MkCfg_Int( const wxString& keyname, TYPE& value, int defaultVal ) 558{ 559 return new Cfg_Int<TYPE>( keyname, value, defaultVal ); 560} 561 562 563/** 564 * Cfg-class for bools. 565 */ 566class Cfg_Bool : public Cfg_Tmpl<bool> 567{ 568public: 569 Cfg_Bool( const wxString& keyname, bool& value, bool defaultVal ) 570 : Cfg_Tmpl<bool>( keyname, value, defaultVal ) 571 {} 572 573 574 virtual void LoadFromFile(wxConfigBase* cfg) 575 { 576 cfg->Read( GetKey(), &m_value, m_default ); 577 } 578 579 virtual void SaveToFile(wxConfigBase* cfg) 580 { 581 cfg->Write( GetKey(), m_value ); 582 } 583}; 584 585 586#ifndef AMULE_DAEMON 587 588class Cfg_Colour : public Cfg_Base 589{ 590 public: 591 Cfg_Colour(const wxString& key, wxColour& colour) 592 : Cfg_Base(key), 593 m_colour(colour), 594 m_default(CMuleColour(colour).GetULong()) 595 {} 596 597 virtual void LoadFromFile(wxConfigBase* cfg) 598 { 599 long int rgb; 600 cfg->Read(GetKey(), &rgb, m_default); 601 m_colour.Set(rgb); 602 } 603 604 virtual void SaveToFile(wxConfigBase* cfg) 605 { 606 cfg->Write(GetKey(), static_cast<long int>(CMuleColour(m_colour).GetULong())); 607 } 608 609 private: 610 wxColour& m_colour; 611 long int m_default; 612}; 613 614 615typedef struct { 616 int id; 617 bool available; 618 wxString displayname; 619 wxString name; 620} LangInfo; 621 622 623/** 624 * The languages aMule has translation for. 625 * 626 * Add new languages here. 627 * Then activate the test code in Cfg_Lang::UpdateChoice below! 628 */ 629static LangInfo aMuleLanguages[] = { 630 { wxLANGUAGE_DEFAULT, true, wxEmptyString, wxTRANSLATE("System default") }, 631 { wxLANGUAGE_ALBANIAN, false, wxEmptyString, wxTRANSLATE("Albanian") }, 632 { wxLANGUAGE_ARABIC, false, wxEmptyString, wxTRANSLATE("Arabic") }, 633 { wxLANGUAGE_ASTURIAN, false, wxEmptyString, wxTRANSLATE("Asturian") }, 634 { wxLANGUAGE_BASQUE, false, wxEmptyString, wxTRANSLATE("Basque") }, 635 { wxLANGUAGE_BULGARIAN, false, wxEmptyString, wxTRANSLATE("Bulgarian") }, 636 { wxLANGUAGE_CATALAN, false, wxEmptyString, wxTRANSLATE("Catalan") }, 637 { wxLANGUAGE_CHINESE_SIMPLIFIED, false, wxEmptyString, wxTRANSLATE("Chinese (Simplified)") }, 638 { wxLANGUAGE_CHINESE_TRADITIONAL, false, wxEmptyString, wxTRANSLATE("Chinese (Traditional)") }, 639 { wxLANGUAGE_CROATIAN, false, wxEmptyString, wxTRANSLATE("Croatian") }, 640 { wxLANGUAGE_CZECH, false, wxEmptyString, wxTRANSLATE("Czech") }, 641 { wxLANGUAGE_DANISH, false, wxEmptyString, wxTRANSLATE("Danish") }, 642 { wxLANGUAGE_DUTCH, false, wxEmptyString, wxTRANSLATE("Dutch") }, 643 { wxLANGUAGE_ENGLISH, false, wxEmptyString, wxTRANSLATE("English (U.K.)") }, 644 { wxLANGUAGE_ESTONIAN, false, wxEmptyString, wxTRANSLATE("Estonian") }, 645 { wxLANGUAGE_FINNISH, false, wxEmptyString, wxTRANSLATE("Finnish") }, 646 { wxLANGUAGE_FRENCH, false, wxEmptyString, wxTRANSLATE("French") }, 647 { wxLANGUAGE_GALICIAN, false, wxEmptyString, wxTRANSLATE("Galician") }, 648 { wxLANGUAGE_GERMAN, false, wxEmptyString, wxTRANSLATE("German") }, 649 { wxLANGUAGE_GREEK, false, wxEmptyString, wxTRANSLATE("Greek") }, 650 { wxLANGUAGE_HEBREW, false, wxEmptyString, wxTRANSLATE("Hebrew") }, 651 { wxLANGUAGE_HUNGARIAN, false, wxEmptyString, wxTRANSLATE("Hungarian") }, 652 { wxLANGUAGE_ITALIAN, false, wxEmptyString, wxTRANSLATE("Italian") }, 653 { wxLANGUAGE_ITALIAN_SWISS, false, wxEmptyString, wxTRANSLATE("Italian (Swiss)") }, 654 { wxLANGUAGE_JAPANESE, false, wxEmptyString, wxTRANSLATE("Japanese") }, 655 { wxLANGUAGE_KOREAN, false, wxEmptyString, wxTRANSLATE("Korean") }, 656 { wxLANGUAGE_LITHUANIAN, false, wxEmptyString, wxTRANSLATE("Lithuanian") }, 657 { wxLANGUAGE_NORWEGIAN_NYNORSK, false, wxEmptyString, wxTRANSLATE("Norwegian (Nynorsk)") }, 658 { wxLANGUAGE_POLISH, false, wxEmptyString, wxTRANSLATE("Polish") }, 659 { wxLANGUAGE_PORTUGUESE, false, wxEmptyString, wxTRANSLATE("Portuguese") }, 660 { wxLANGUAGE_PORTUGUESE_BRAZILIAN, false, wxEmptyString, wxTRANSLATE("Portuguese (Brazilian)") }, 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") }, 667}; 668 669 670typedef Cfg_Int<int> Cfg_PureInt; 671 672class Cfg_Lang : public Cfg_PureInt, public Cfg_Lang_Base 673{ 674public: 675 Cfg_Lang() 676 : Cfg_PureInt( wxEmptyString, m_selection, 0 ) 677 { 678 m_languagesReady = false; 679 m_changePos = 0; 680 } 681 682 virtual void LoadFromFile(wxConfigBase* WXUNUSED(cfg)) {} 683 virtual void SaveToFile(wxConfigBase* WXUNUSED(cfg)) {} 684 685 686 virtual bool TransferFromWindow() 687 { 688 if (!m_languagesReady) { 689 return true; // nothing changed, no problem 690 } 691 692 if ( Cfg_PureInt::TransferFromWindow() ) { 693 // find wx ID of selected language 694 int i = 0; 695 while (m_selection > 0) { 696 i++; 697 if (aMuleLanguages[i].available) { 698 m_selection--; 699 } 700 } 701 int id = aMuleLanguages[i].id; 702 703 // save language selection 704 thePrefs::SetLanguageID(wxLang2Str(id)); 705 706 return true; 707 } 708 709 return false; 710 } 711 712 713 virtual bool TransferToWindow() 714 { 715 m_langSelector = dynamic_cast<wxChoice*>(m_widget); // doesn't work in ctor! 716 if (m_languagesReady) { 717 FillChoice(); 718 } else { 719 int wxId = StrLang2wx(thePrefs::GetLanguageID()); 720 m_langSelector->Clear(); 721 m_selection = 0; 722 for (uint32 i = 0; i < itemsof(aMuleLanguages); i++) { 723 if ( aMuleLanguages[i].id == wxId ) { 724 m_langSelector->Append(wxString(wxGetTranslation(aMuleLanguages[i].name)) + wxT(" [") + aMuleLanguages[i].name + wxT("]")); 725 break; 726 } 727 } 728 m_langSelector->Append(_("Change Language")); 729 m_changePos = m_langSelector->GetCount() - 1; 730 } 731 732 return Cfg_PureInt::TransferToWindow(); 733 } 734 735 virtual void UpdateChoice(int pos) 736 { 737 if (!m_languagesReady && pos == m_changePos) { 738 // Find available languages and translate them. 739 // This is only done when the user selects "Change Language" 740 // Language is changed rarely, and the go-through-all locales takes a considerable 741 // time when the settings dialog is opened for the first time. 742 wxBusyCursor busyCursor; 743 aMuleLanguages[0].displayname = wxGetTranslation(aMuleLanguages[0].name); 744 745 // This supresses error-messages about invalid locales 746 for (unsigned int i = 1; i < itemsof(aMuleLanguages); ++i) { 747 if ((aMuleLanguages[i].id > wxLANGUAGE_USER_DEFINED) || wxLocale::IsAvailable(aMuleLanguages[i].id)) { 748 wxLogNull logTarget; 749 wxLocale locale_to_check; 750 InitLocale(locale_to_check, aMuleLanguages[i].id); 751 if (locale_to_check.IsOk() && locale_to_check.IsLoaded(wxT(PACKAGE))) { 752 aMuleLanguages[i].displayname = wxString(wxGetTranslation(aMuleLanguages[i].name)) + wxT(" [") + aMuleLanguages[i].name + wxT("]"); 753 aMuleLanguages[i].available = true; 754#if 0 755 // Check for language problems 756 // Activate this code temporarily after messing with the languages! 757 int wxid = StrLang2wx(wxLang2Str(aMuleLanguages[i].id)); 758 if (wxid != aMuleLanguages[i].id) { 759 AddDebugLogLineN(logGeneral, CFormat(wxT("Language problem for %s : aMule id %d != wx id %d")) 760 % aMuleLanguages[i].name % aMuleLanguages[i].id % wxid); 761 } 762#endif 763 } 764 } 765 } 766 // Restore original locale 767 wxLocale tmpLocale; 768 InitLocale(tmpLocale, theApp->m_locale.GetLanguage()); 769 FillChoice(); 770 if (m_langSelector->GetCount() == 1) { 771 wxMessageBox(_("There are no translations installed for aMule"), _("No languages available"), wxICON_INFORMATION | wxOK); 772 } 773 m_langSelector->SetSelection(m_selection); 774 m_languagesReady = true; 775 } 776 } 777 778protected: 779 int m_selection; 780 781private: 782 void FillChoice() 783 { 784 int wxId = StrLang2wx(thePrefs::GetLanguageID()); 785 m_langSelector->Clear(); 786 // Add all available languages and find the index of the selected language. 787 for ( unsigned int i = 0, j = 0; i < itemsof(aMuleLanguages); i++) { 788 if (aMuleLanguages[i].available) { 789 m_langSelector->Append(aMuleLanguages[i].displayname); 790 if ( aMuleLanguages[i].id == wxId ) { 791 m_selection = j; 792 } 793 j++; 794 } 795 } 796 } 797 798 bool m_languagesReady; // true: all translations calculated 799 int m_changePos; 800 wxChoice * m_langSelector; 801}; 802 803#endif /* ! AMULE_DAEMON */ 804 805void Cfg_Lang_Base::UpdateChoice(int) {} // dummy 806 807class Cfg_Skin : public Cfg_Str 808{ 809public: 810 Cfg_Skin( const wxString& keyname, wxString& value, const wxString& defaultVal = EmptyString ) 811 : Cfg_Str( keyname, value, defaultVal ), 812 m_is_skin(false) 813 {} 814 815#ifndef AMULE_DAEMON 816 virtual bool TransferFromWindow() 817 { 818 if ( Cfg_Str::TransferFromWindow() ) { 819 if (m_is_skin) { 820 wxChoice *skinSelector = dynamic_cast<wxChoice*>(m_widget); 821 // "- default -" is always the first 822 if (skinSelector->GetSelection() == 0) { 823 m_value.Clear(); 824 } 825 } 826 return true; 827 } 828 829 return false; 830 } 831 832 833 virtual bool TransferToWindow() 834 { 835 836 wxChoice *skinSelector = dynamic_cast<wxChoice*>(m_widget); 837 skinSelector->Clear(); 838 839 wxString folder; 840 int flags = wxDIR_DIRS; 841 wxString filespec; 842 wxString defaultSelection = _("- default -"); 843//#warning there has to be a better way... 844 if ( GetKey() == wxT("/SkinGUIOptions/Skin") ) { 845 folder = wxT("skins"); 846 m_is_skin = true; 847 flags = wxDIR_FILES; 848 filespec = wxT("*.zip"); 849 skinSelector->Append(defaultSelection); 850 } else { 851 folder = wxT("webserver"); 852 } 853 wxString dirName(JoinPaths(GetConfigDir(theApp->m_configFile), folder)); 854 wxString Filename; 855 wxDir d; 856 857 if (wxDir::Exists(dirName) && 858 d.Open(dirName) && 859 d.GetFirst(& Filename, filespec, flags) 860 ) 861 { 862 do 863 { 864 if (m_is_skin) { 865 Filename = wxT("User:") + Filename; 866 } 867 skinSelector->Append(Filename); 868 } 869 while (d.GetNext(&Filename)); 870 } 871 872 wxString dataDir; 873 if (m_is_skin) { 874 dataDir = wxStandardPaths::Get().GetDataDir(); 875 } else { 876 dataDir = wxStandardPaths::Get().GetResourcesDir(); 877 } 878#if !defined(__WXMSW__) && !defined(__WXMAC__) 879 dataDir = dataDir.BeforeLast(wxT('/')) + wxT("/amule"); 880#endif 881 wxString systemDir(JoinPaths(dataDir,folder)); 882 883 if (wxDir::Exists(systemDir) && 884 d.Open(systemDir) && 885 d.GetFirst(& Filename, filespec, flags) 886 ) 887 { 888 do 889 { 890 if (m_is_skin) { 891 Filename = wxT("System:") + Filename; 892 } 893 // avoid duplicates for webserver templates 894 if (skinSelector->FindString(Filename) == wxNOT_FOUND) { 895 skinSelector->Append(Filename); 896 } 897 } 898 while (d.GetNext(&Filename)); 899 } 900 901 if ( skinSelector->GetCount() == 0 ) { 902 skinSelector->Append(_("no options available")); 903 } 904 905 int id = skinSelector->FindString(m_value); 906 if ( id == wxNOT_FOUND ) { 907 id = 0; 908 if (m_is_skin) { 909 m_value = defaultSelection; 910 } 911 } 912 skinSelector->SetSelection(id); 913 914 return Cfg_Str::TransferToWindow(); 915 } 916#endif /* ! AMULE_DAEMON */ 917 918 protected: 919 bool m_is_skin; 920}; 921 922 923/// new implementation 924CPreferences::CPreferences() 925{ 926 srand( wxGetLocalTimeMillis().GetLo() ); // we need random numbers sometimes 927 928 // load preferences.dat or set standard values 929 wxString fullpath(theApp->ConfigDir + wxT("preferences.dat")); 930 CFile preffile; 931 if (wxFileExists(fullpath)) { 932 if (preffile.Open(fullpath, CFile::read)) { 933 try { 934 preffile.ReadUInt8(); // Version. Value is not used. 935 s_userhash = preffile.ReadHash(); 936 } catch (const CSafeIOException& e) { 937 AddDebugLogLineC(logGeneral, 938 wxT("Error while reading userhash: ") + e.what()); 939 } 940 } 941 } 942 943 if (s_userhash.IsEmpty()) { 944 for (int i = 0; i < 8; i++) { 945 RawPokeUInt16(s_userhash.GetHash() + (i * 2), rand()); 946 } 947 948 Save(); 949 } 950 951 // Mark hash as an eMule-type hash 952 // See also CUpDownClient::GetHashType 953 s_userhash[5] = 14; 954 s_userhash[14] = 111; 955 956#ifndef CLIENT_GUI 957 LoadPreferences(); 958 ReloadSharedFolders(); 959 960 // serverlist adresses 961 CTextFile slistfile; 962 if (slistfile.Open(theApp->ConfigDir + wxT("addresses.dat"), CTextFile::read)) { 963 adresses_list = slistfile.ReadLines(); 964 } 965#endif 966} 967 968// 969// Gets called at init time 970// 971void CPreferences::BuildItemList( const wxString& appdir ) 972{ 973#ifndef AMULE_DAEMON 974 #define NewCfgItem(ID, COMMAND) s_CfgList[ID] = COMMAND 975#else 976 int current_id = 0; 977 #define NewCfgItem(ID, COMMAND) s_CfgList[++current_id] = COMMAND 978#endif /* AMULE_DAEMON */ 979 980 /** 981 * User settings 982 **/ 983 NewCfgItem(IDC_NICK, (new Cfg_Str( wxT("/eMule/Nick"), s_nick, wxT("http://www.aMule.org") ))); 984#ifndef AMULE_DAEMON 985 Cfg_Lang * cfgLang = new Cfg_Lang(); 986 s_cfgLang = cfgLang; 987 NewCfgItem(IDC_LANGUAGE, cfgLang); 988#endif 989 990 /** 991 * Browser options 992 **/ 993 #ifdef __WXMAC__ 994 wxString customBrowser = wxT("/usr/bin/open"); 995 #else 996 wxString customBrowser; // left empty 997 #endif 998 999 NewCfgItem(IDC_BROWSERTABS, (new Cfg_Bool( wxT("/Browser/OpenPageInTab"), s_BrowserTab, true ))); 1000 NewCfgItem(IDC_BROWSERSELF, (new Cfg_Str( wxT("/Browser/CustomBrowserString"), s_CustomBrowser, customBrowser ))); 1001 1002 1003 /** 1004 * Misc 1005 **/ 1006 NewCfgItem(IDC_QUEUESIZE, (MkCfg_Int( wxT("/eMule/QueueSizePref"), s_iQueueSize, 50 ))); 1007 1008 1009#ifdef __DEBUG__ 1010 /** 1011 * Debugging 1012 **/ 1013 NewCfgItem(ID_VERBOSEDEBUG, (new Cfg_Bool( wxT("/eMule/VerboseDebug"), s_bVerbose, false ))); 1014#endif 1015 1016 /** 1017 * Connection settings 1018 **/ 1019 NewCfgItem(IDC_MAXUP, (MkCfg_Int( wxT("/eMule/MaxUpload"), s_maxupload, 0 ))); 1020 NewCfgItem(IDC_MAXDOWN, (MkCfg_Int( wxT("/eMule/MaxDownload"), s_maxdownload, 0 ))); 1021 NewCfgItem(IDC_SLOTALLOC, (MkCfg_Int( wxT("/eMule/SlotAllocation"), s_slotallocation, 2 ))); 1022 NewCfgItem(IDC_PORT, (MkCfg_Int( wxT("/eMule/Port"), s_port, DEFAULT_TCP_PORT ))); 1023 NewCfgItem(IDC_UDPPORT, (MkCfg_Int( wxT("/eMule/UDPPort"), s_udpport, DEFAULT_UDP_PORT ))); 1024 NewCfgItem(IDC_UDPENABLE, (new Cfg_Bool( wxT("/eMule/UDPEnable"), s_UDPEnable, true ))); 1025 NewCfgItem(IDC_ADDRESS, (new Cfg_Str( wxT("/eMule/Address"), s_Addr, wxEmptyString))); 1026 NewCfgItem(IDC_AUTOCONNECT, (new Cfg_Bool( wxT("/eMule/Autoconnect"), s_autoconnect, true ))); 1027 NewCfgItem(IDC_MAXSOURCEPERFILE, (MkCfg_Int( wxT("/eMule/MaxSourcesPerFile"), s_maxsourceperfile, 300 ))); 1028 NewCfgItem(IDC_MAXCON, (MkCfg_Int( wxT("/eMule/MaxConnections"), s_maxconnections, GetRecommendedMaxConnections() ))); 1029 NewCfgItem(IDC_MAXCON5SEC, (MkCfg_Int( wxT("/eMule/MaxConnectionsPerFiveSeconds"), s_MaxConperFive, 20 ))); 1030 1031 /** 1032 * Proxy 1033 **/ 1034 NewCfgItem(ID_PROXY_ENABLE_PROXY, (new Cfg_Bool( wxT("/Proxy/ProxyEnableProxy"), s_ProxyData.m_proxyEnable, false ))); 1035 NewCfgItem(ID_PROXY_TYPE, (MkCfg_Int( wxT("/Proxy/ProxyType"), s_ProxyData.m_proxyType, 0 ))); 1036 NewCfgItem(ID_PROXY_NAME, (new Cfg_Str( wxT("/Proxy/ProxyName"), s_ProxyData.m_proxyHostName, wxEmptyString ))); 1037 NewCfgItem(ID_PROXY_PORT, (MkCfg_Int( wxT("/Proxy/ProxyPort"), s_ProxyData.m_proxyPort, 1080 ))); 1038 NewCfgItem(ID_PROXY_ENABLE_PASSWORD, (new Cfg_Bool( wxT("/Proxy/ProxyEnablePassword"), s_ProxyData.m_enablePassword, false ))); 1039 NewCfgItem(ID_PROXY_USER, (new Cfg_Str( wxT("/Proxy/ProxyUser"), s_ProxyData.m_userName, wxEmptyString ))); 1040 NewCfgItem(ID_PROXY_PASSWORD, (new Cfg_Str( wxT("/Proxy/ProxyPassword"), s_ProxyData.m_password, wxEmptyString ))); 1041// These were copied from eMule config file, maybe someone with windows can complete this? 1042// NewCfgItem(ID_PROXY_AUTO_SERVER_CONNECT_WITHOUT_PROXY, (new Cfg_Bool( wxT("/Proxy/Proxy????"), s_Proxy????, false ))); 1043 1044 /** 1045 * Servers 1046 **/ 1047 NewCfgItem(IDC_REMOVEDEAD, (new Cfg_Bool( wxT("/eMule/RemoveDeadServer"), s_deadserver, 1 ))); 1048 NewCfgItem(IDC_SERVERRETRIES, (MkCfg_Int( wxT("/eMule/DeadServerRetry"), s_deadserverretries, 3 ))); 1049 NewCfgItem(IDC_SERVERKEEPALIVE, (MkCfg_Int( wxT("/eMule/ServerKeepAliveTimeout"), s_dwServerKeepAliveTimeoutMins, 0 ))); 1050 NewCfgItem(IDC_RECONN, (new Cfg_Bool( wxT("/eMule/Reconnect"), s_reconnect, true ))); 1051 NewCfgItem(IDC_SCORE, (new Cfg_Bool( wxT("/eMule/Scoresystem"), s_scorsystem, true ))); 1052 NewCfgItem(IDC_AUTOSERVER, (new Cfg_Bool( wxT("/eMule/Serverlist"), s_autoserverlist, false ))); 1053 NewCfgItem(IDC_UPDATESERVERCONNECT, (new Cfg_Bool( wxT("/eMule/AddServerListFromServer"), s_addserversfromserver, false))); 1054 NewCfgItem(IDC_UPDATESERVERCLIENT, (new Cfg_Bool( wxT("/eMule/AddServerListFromClient"), s_addserversfromclient, false ))); 1055 NewCfgItem(IDC_SAFESERVERCONNECT, (new Cfg_Bool( wxT("/eMule/SafeServerConnect"), s_safeServerConnect, false ))); 1056 NewCfgItem(IDC_AUTOCONNECTSTATICONLY, (new Cfg_Bool( wxT("/eMule/AutoConnectStaticOnly"), s_autoconnectstaticonly, false ))); 1057 NewCfgItem(IDC_UPNP_ENABLED, (new Cfg_Bool( wxT("/eMule/UPnPEnabled"), s_UPnPEnabled, false ))); 1058 NewCfgItem(IDC_UPNPTCPPORT, (MkCfg_Int( wxT("/eMule/UPnPTCPPort"), s_UPnPTCPPort, 50000 ))); 1059 NewCfgItem(IDC_SMARTIDCHECK, (new Cfg_Bool( wxT("/eMule/SmartIdCheck"), s_smartidcheck, true ))); 1060 // Enabled networks 1061 NewCfgItem( IDC_NETWORKKAD, (new Cfg_Bool( wxT("/eMule/ConnectToKad"), s_ConnectToKad, true )) ); 1062 NewCfgItem( IDC_NETWORKED2K, ( new Cfg_Bool( wxT("/eMule/ConnectToED2K"), s_ConnectToED2K, true ) )); 1063 1064 1065 /** 1066 * Files 1067 **/ 1068 NewCfgItem(IDC_TEMPFILES, (new Cfg_Path( wxT("/eMule/TempDir"), s_tempdir, appdir + wxT("Temp") ))); 1069 1070 #if defined(__WXMAC__) || defined(__WXMSW__) 1071 wxString incpath = wxStandardPaths::Get().GetDocumentsDir(); 1072 if (incpath.IsEmpty()) { 1073 // There is a built-in possibility for this call to fail, though I can't imagine a reason for that. 1074 incpath = appdir + wxT("Incoming"); 1075 } else { 1076 incpath = JoinPaths(incpath, wxT("aMule Downloads")); 1077 } 1078 #else 1079 wxString incpath = appdir + wxT("Incoming"); 1080 #endif 1081 NewCfgItem(IDC_INCFILES, (new Cfg_Path( wxT("/eMule/IncomingDir"), s_incomingdir, incpath ))); 1082 1083 NewCfgItem(IDC_ICH, (new Cfg_Bool( wxT("/eMule/ICH"), s_ICH, true ))); 1084 NewCfgItem(IDC_AICHTRUST, (new Cfg_Bool( wxT("/eMule/AICHTrust"), s_AICHTrustEveryHash, false ))); 1085 NewCfgItem(IDC_CHECKDISKSPACE, (new Cfg_Bool( wxT("/eMule/CheckDiskspace"), s_checkDiskspace, true ))); 1086 NewCfgItem(IDC_MINDISKSPACE, (MkCfg_Int( wxT("/eMule/MinFreeDiskSpace"), s_uMinFreeDiskSpace, 1 ))); 1087 NewCfgItem(IDC_ADDNEWFILESPAUSED, (new Cfg_Bool( wxT("/eMule/AddNewFilesPaused"), s_addnewfilespaused, false ))); 1088 NewCfgItem(IDC_PREVIEWPRIO, (new Cfg_Bool( wxT("/eMule/PreviewPrio"), s_bpreviewprio, false ))); 1089 NewCfgItem(IDC_MANUALSERVERHIGHPRIO, (new Cfg_Bool( wxT("/eMule/ManualHighPrio"), s_bmanualhighprio, false ))); 1090 NewCfgItem(IDC_STARTNEXTFILE, (new Cfg_Bool( wxT("/eMule/StartNextFile"), s_bstartnextfile, false ))); 1091 NewCfgItem(IDC_STARTNEXTFILE_SAME, (new Cfg_Bool( wxT("/eMule/StartNextFileSameCat"), s_bstartnextfilesame, false ))); 1092 NewCfgItem(IDC_STARTNEXTFILE_ALPHA, (new Cfg_Bool( wxT("/eMule/StartNextFileAlpha"), s_bstartnextfilealpha, false ))); 1093 NewCfgItem(IDC_SRCSEEDS, (new Cfg_Bool( wxT("/ExternalConnect/UseSrcSeeds"), s_UseSrcSeeds, false ))); 1094 NewCfgItem(IDC_FILEBUFFERSIZE, (MkCfg_Int( wxT("/eMule/FileBufferSizePref"), s_iFileBufferSize, 16 ))); 1095 NewCfgItem(IDC_DAP, (new Cfg_Bool( wxT("/eMule/DAPPref"), s_bDAP, true ))); 1096 NewCfgItem(IDC_UAP, (new Cfg_Bool( wxT("/eMule/UAPPref"), s_bUAP, true ))); 1097 NewCfgItem(IDC_ALLOCFULLFILE, (new Cfg_Bool( wxT("/eMule/AllocateFullFile"), s_allocFullFile, false ))); 1098 1099 /** 1100 * Web Server 1101 */ 1102 NewCfgItem(IDC_OSDIR, (new Cfg_Path( wxT("/eMule/OSDirectory"), s_OSDirectory, appdir ))); 1103 NewCfgItem(IDC_ONLINESIG, (new Cfg_Bool( wxT("/eMule/OnlineSignature"), s_onlineSig, false ))); 1104 NewCfgItem(IDC_OSUPDATE, (MkCfg_Int( wxT("/eMule/OnlineSignatureUpdate"), s_OSUpdate, 5 ))); 1105 NewCfgItem(IDC_ENABLE_WEB, (new Cfg_Bool( wxT("/WebServer/Enabled"), s_bWebEnabled, false ))); 1106 NewCfgItem(IDC_WEB_PASSWD, (new Cfg_Str_Encrypted( wxT("/WebServer/Password"), s_sWebPassword ))); 1107 NewCfgItem(IDC_WEB_PASSWD_LOW, (new Cfg_Str_Encrypted( wxT("/WebServer/PasswordLow"), s_sWebLowPassword ))); 1108 NewCfgItem(IDC_WEB_PORT, (MkCfg_Int( wxT("/WebServer/Port"), s_nWebPort, 4711 ))); 1109 NewCfgItem(IDC_WEBUPNPTCPPORT, (MkCfg_Int( wxT("/WebServer/WebUPnPTCPPort"), s_nWebUPnPTCPPort, 50001 ))); 1110 NewCfgItem(IDC_UPNP_WEBSERVER_ENABLED, 1111 (new Cfg_Bool( wxT("/WebServer/UPnPWebServerEnabled"), s_UPnPWebServerEnabled, false ))); 1112 NewCfgItem(IDC_WEB_GZIP, (new Cfg_Bool( wxT("/WebServer/UseGzip"), s_bWebUseGzip, true ))); 1113 NewCfgItem(IDC_ENABLE_WEB_LOW, (new Cfg_Bool( wxT("/WebServer/UseLowRightsUser"), s_bWebLowEnabled, false ))); 1114 NewCfgItem(IDC_WEB_REFRESH_TIMEOUT, (MkCfg_Int( wxT("/WebServer/PageRefreshTime"), s_nWebPageRefresh, 120 ))); 1115 NewCfgItem(IDC_WEBTEMPLATE, (new Cfg_Skin( wxT("/WebServer/Template"), s_WebTemplate, wxEmptyString ))); 1116 1117 /** 1118 * External Connections 1119 */ 1120 NewCfgItem(IDC_EXT_CONN_ACCEPT, (new Cfg_Bool( wxT("/ExternalConnect/AcceptExternalConnections"), s_AcceptExternalConnections, false ))); 1121 NewCfgItem(IDC_EXT_CONN_IP, (new Cfg_Str( wxT("/ExternalConnect/ECAddress"), s_ECAddr, wxEmptyString ))); 1122 NewCfgItem(IDC_EXT_CONN_TCP_PORT, (MkCfg_Int( wxT("/ExternalConnect/ECPort"), s_ECPort, 4712 ))); 1123 NewCfgItem(IDC_EXT_CONN_PASSWD, (new Cfg_Str_Encrypted( wxT("/ExternalConnect/ECPassword"), s_ECPassword, wxEmptyString ))); 1124 NewCfgItem(IDC_UPNP_EC_ENABLED, (new Cfg_Bool( wxT("/ExternalConnect/UPnPECEnabled"), s_UPnPECEnabled, false ))); 1125 1126 /** 1127 * GUI behavior 1128 **/ 1129 NewCfgItem(IDC_MACHIDEONCLOSE, (new Cfg_Bool( wxT("/GUI/HideOnClose"), s_hideonclose, false ))); 1130 NewCfgItem(IDC_ENABLETRAYICON, (new Cfg_Bool( wxT("/eMule/EnableTrayIcon"), s_trayiconenabled, false ))); 1131 NewCfgItem(IDC_MINTRAY, (new Cfg_Bool( wxT("/eMule/MinToTray"), s_mintotray, false ))); 1132 NewCfgItem(IDC_EXIT, (new Cfg_Bool( wxT("/eMule/ConfirmExit"), s_confirmExit, true ))); 1133 NewCfgItem(IDC_STARTMIN, (new Cfg_Bool( wxT("/eMule/StartupMinimized"), s_startMinimized, false ))); 1134 1135 /** 1136 * GUI appearence 1137 **/ 1138 NewCfgItem(IDC_3DDEPTH, (MkCfg_Int( wxT("/eMule/3DDepth"), s_depth3D, 10 ))); 1139 NewCfgItem(IDC_TOOLTIPDELAY, (MkCfg_Int( wxT("/eMule/ToolTipDelay"), s_iToolDelayTime, 1 ))); 1140 NewCfgItem(IDC_SHOWOVERHEAD, (new Cfg_Bool( wxT("/eMule/ShowOverhead"), s_bshowoverhead, false ))); 1141 NewCfgItem(IDC_EXTCATINFO, (new Cfg_Bool( wxT("/eMule/ShowInfoOnCatTabs"), s_showCatTabInfos, true ))); 1142 NewCfgItem(IDC_FED2KLH, (new Cfg_Bool( wxT("/Razor_Preferences/FastED2KLinksHandler"), s_FastED2KLinksHandler, true ))); 1143 NewCfgItem(IDC_PROGBAR, (new Cfg_Bool( wxT("/ExternalConnect/ShowProgressBar"), s_ProgBar, true ))); 1144 NewCfgItem(IDC_PERCENT, (new Cfg_Bool( wxT("/ExternalConnect/ShowPercent"), s_Percent, true ))); 1145 NewCfgItem(IDC_SKIN, (new Cfg_Skin( wxT("/SkinGUIOptions/Skin"), s_Skin, wxEmptyString ))); 1146 NewCfgItem(IDC_VERTTOOLBAR, (new Cfg_Bool( wxT("/eMule/VerticalToolbar"), s_ToolbarOrientation, false ))); 1147 NewCfgItem(IDC_SHOW_COUNTRY_FLAGS, (new Cfg_Bool( wxT("/eMule/GeoIPEnabled"), s_GeoIPEnabled, true ))); 1148#ifndef __SVN__ 1149 NewCfgItem(IDC_SHOWVERSIONONTITLE, (new Cfg_Bool( wxT("/eMule/ShowVersionOnTitle"), s_showVersionOnTitle, false ))); 1150#endif 1151 1152 /** 1153 * External Apps 1154 */ 1155 NewCfgItem(IDC_VIDEOPLAYER, (new Cfg_Str( wxT("/eMule/VideoPlayer"), s_VideoPlayer, wxEmptyString ))); 1156 1157 /** 1158 * Statistics 1159 **/ 1160 NewCfgItem(IDC_SLIDER, (MkCfg_Int( wxT("/eMule/StatGraphsInterval"), s_trafficOMeterInterval, 3 ))); 1161 NewCfgItem(IDC_SLIDER2, (MkCfg_Int( wxT("/eMule/statsInterval"), s_statsInterval, 30 ))); 1162 NewCfgItem(IDC_DOWNLOAD_CAP, (MkCfg_Int( wxT("/eMule/DownloadCapacity"), s_maxGraphDownloadRate, 300 ))); 1163 NewCfgItem(IDC_UPLOAD_CAP, (MkCfg_Int( wxT("/eMule/UploadCapacity"), s_maxGraphUploadRate, 100 ))); 1164 NewCfgItem(IDC_SLIDER3, (MkCfg_Int( wxT("/eMule/StatsAverageMinutes"), s_statsAverageMinutes, 5 ))); 1165 NewCfgItem(IDC_SLIDER4, (MkCfg_Int( wxT("/eMule/VariousStatisticsMaxValue"), s_statsMax, 100 ))); 1166 NewCfgItem(IDC_CLIENTVERSIONS, (MkCfg_Int( wxT("/Statistics/MaxClientVersions"), s_maxClientVersions, 0 ))); 1167 1168 /** 1169 * Security 1170 **/ 1171 NewCfgItem(IDC_SEESHARES, (MkCfg_Int( wxT("/eMule/SeeShare"), s_iSeeShares, 2 ))); 1172 NewCfgItem(IDC_SECIDENT, (new Cfg_Bool( wxT("/ExternalConnect/UseSecIdent"), s_SecIdent, true ))); 1173 NewCfgItem(IDC_IPFCLIENTS, (new Cfg_Bool( wxT("/ExternalConnect/IpFilterClients"), s_IPFilterClients, true ))); 1174 NewCfgItem(IDC_IPFSERVERS, (new Cfg_Bool( wxT("/ExternalConnect/IpFilterServers"), s_IPFilterServers, true ))); 1175 NewCfgItem(IDC_FILTERLAN, (new Cfg_Bool( wxT("/eMule/FilterLanIPs"), s_filterLanIP, true ))); 1176 NewCfgItem(IDC_PARANOID, (new Cfg_Bool( wxT("/eMule/ParanoidFiltering"), s_paranoidfilter, true ))); 1177 NewCfgItem(IDC_AUTOIPFILTER, (new Cfg_Bool( wxT("/eMule/IPFilterAutoLoad"), s_IPFilterAutoLoad, true ))); 1178 NewCfgItem(IDC_IPFILTERURL, (new Cfg_Str( wxT("/eMule/IPFilterURL"), s_IPFilterURL, wxEmptyString ))); 1179 NewCfgItem(ID_IPFILTERLEVEL, (MkCfg_Int( wxT("/eMule/FilterLevel"), s_filterlevel, 127 ))); 1180 NewCfgItem(IDC_IPFILTERSYS, (new Cfg_Bool( wxT("/eMule/IPFilterSystem"), s_IPFilterSys, false ))); 1181 1182 /** 1183 * Message Filter 1184 **/ 1185 NewCfgItem(IDC_MSGFILTER, (new Cfg_Bool( wxT("/eMule/FilterMessages"), s_MustFilterMessages, true ))); 1186 NewCfgItem(IDC_MSGFILTER_ALL, (new Cfg_Bool( wxT("/eMule/FilterAllMessages"), s_FilterAllMessages, false ))); 1187 NewCfgItem(IDC_MSGFILTER_NONFRIENDS, (new Cfg_Bool( wxT("/eMule/MessagesFromFriendsOnly"), s_msgonlyfriends, false ))); 1188 NewCfgItem(IDC_MSGFILTER_NONSECURE, (new Cfg_Bool( wxT("/eMule/MessageFromValidSourcesOnly"), s_msgsecure, true ))); 1189 NewCfgItem(IDC_MSGFILTER_WORD, (new Cfg_Bool( wxT("/eMule/FilterWordMessages"), s_FilterSomeMessages, false ))); 1190 NewCfgItem(IDC_MSGWORD, (new Cfg_Str( wxT("/eMule/MessageFilter"), s_MessageFilterString, wxEmptyString ))); 1191 NewCfgItem(IDC_MSGLOG, (new Cfg_Bool( wxT("/eMule/ShowMessagesInLog"), s_ShowMessagesInLog, true ))); 1192 //Todo NewCfgItem(IDC_MSGADVSPAM, (new Cfg_Bool( wxT("/eMule/AdvancedSpamFilter"), s_IsAdvancedSpamfilterEnabled, true ))); 1193 //Todo NewCfgItem(IDC_MSGCAPTCHA, (new Cfg_Bool( wxT("/eMule/MessageUseCaptchas"), s_IsChatCaptchaEnabled, true ))); 1194 s_MiscList.push_back( new Cfg_Bool( wxT("/eMule/AdvancedSpamFilter"), s_IsAdvancedSpamfilterEnabled, true ) ); 1195 s_MiscList.push_back( new Cfg_Bool( wxT("/eMule/MessageUseCaptchas"), s_IsChatCaptchaEnabled, true ) ); 1196 1197 NewCfgItem(IDC_FILTERCOMMENTS, (new Cfg_Bool( wxT("/eMule/FilterComments"), s_FilterComments, false ))); 1198 NewCfgItem(IDC_COMMENTWORD, (new Cfg_Str( wxT("/eMule/CommentFilter"), s_CommentFilterString, wxEmptyString ))); 1199 1200 /** 1201 * Hidden files sharing 1202 **/ 1203 NewCfgItem(IDC_SHAREHIDDENFILES, (new Cfg_Bool( wxT("/eMule/ShareHiddenFiles"), s_ShareHiddenFiles, false ))); 1204 1205 /** 1206 * Auto-Sorting of downloads 1207 **/ 1208 NewCfgItem(IDC_AUTOSORT, (new Cfg_Bool( wxT("/eMule/AutoSortDownloads"), s_AutoSortDownload, false ))); 1209 1210 /** 1211 * Version check 1212 **/ 1213 NewCfgItem(IDC_NEWVERSION, (new Cfg_Bool( wxT("/eMule/NewVersionCheck"), s_NewVersionCheck, true ))); 1214 1215 /** 1216 * Obfuscation 1217 **/ 1218 NewCfgItem( IDC_SUPPORT_PO, ( new Cfg_Bool( wxT("/Obfuscation/IsClientCryptLayerSupported"), s_IsClientCryptLayerSupported, true ))); 1219 NewCfgItem( IDC_ENABLE_PO_OUTGOING, ( new Cfg_Bool( wxT("/Obfuscation/IsCryptLayerRequested"), s_bCryptLayerRequested, true ))); 1220 NewCfgItem( IDC_ENFORCE_PO_INCOMING, ( new Cfg_Bool( wxT("/Obfuscation/IsClientCryptLayerRequired"), s_IsClientCryptLayerRequired, false ))); 1221#ifndef CLIENT_GUI 1222 // There is no need for GUI items for this two. 1223 s_MiscList.push_back( MkCfg_Int( wxT("/Obfuscation/CryptoPaddingLenght"), s_byCryptTCPPaddingLength, 254 ) ); 1224 s_MiscList.push_back( MkCfg_Int( wxT("/Obfuscation/CryptoKadUDPKey"), s_dwKadUDPKey, GetRandomUint32() ) ); 1225#endif 1226 1227 /** 1228 * Power management 1229 **/ 1230 NewCfgItem( IDC_PREVENT_SLEEP, ( new Cfg_Bool( wxT("/PowerManagement/PreventSleepWhileDownloading"), s_preventSleepWhileDownloading, false ))); 1231 1232 /** 1233 * The following doesn't have an associated widget or section 1234 **/ 1235 s_MiscList.push_back( new Cfg_Str( wxT("/eMule/Language"), s_languageID ) ); 1236 s_MiscList.push_back( MkCfg_Int( wxT("/eMule/SplitterbarPosition"), s_splitterbarPosition, 75 ) ); 1237 s_MiscList.push_back( new Cfg_Str( wxT("/eMule/YourHostname"), s_yourHostname, wxEmptyString ) ); 1238 s_MiscList.push_back( new Cfg_Str( wxT("/eMule/DateTimeFormat"), s_datetimeformat, wxT("%A, %x, %X") ) ); 1239 1240 s_MiscList.push_back( MkCfg_Int( wxT("/eMule/AllcatType"), s_allcatFilter, 0 ) ); 1241 s_MiscList.push_back( new Cfg_Bool( wxT("/eMule/ShowAllNotCats"), s_showAllNotCats, false ) ); 1242 1243 s_MiscList.push_back( MkCfg_Int( wxT("/eMule/SmartIdState"), s_smartidstate, 0 ) ); 1244 1245 s_MiscList.push_back( new Cfg_Bool( wxT("/eMule/DropSlowSources"), s_DropSlowSources, false ) ); 1246 1247 s_MiscList.push_back( new Cfg_Str( wxT("/eMule/KadNodesUrl"), s_KadURL, wxT("http://download.tuxfamily.org/technosalad/utils/nodes.dat") ) ); 1248 s_MiscList.push_back( new Cfg_Str( wxT("/eMule/Ed2kServersUrl"), s_Ed2kURL, wxT("http://gruk.org/server.met.gz") ) ); 1249 s_MiscList.push_back( MkCfg_Int( wxT("/eMule/ShowRatesOnTitle"), s_showRatesOnTitle, 0 )); 1250 1251 s_MiscList.push_back( new Cfg_Str( wxT("/eMule/GeoLiteCountryUpdateUrl"), s_GeoIPUpdateUrl, wxT("http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz") ) ); 1252 wxConfigBase::Get()->DeleteEntry(wxT("/eMule/GeoIPUpdateUrl")); // get rid of the old one for a while 1253 1254 s_MiscList.push_back( new Cfg_Str( wxT("/WebServer/Path"), s_sWebPath, wxT("amuleweb") ) ); 1255 1256 s_MiscList.push_back( new Cfg_Str( wxT("/eMule/StatsServerName"), s_StatsServerName, wxT("Shorty's ED2K stats") ) ); 1257 s_MiscList.push_back( new Cfg_Str( wxT("/eMule/StatsServerURL"), s_StatsServerURL, wxT("http://ed2k.shortypower.dyndns.org/?hash=") ) ); 1258 1259 s_MiscList.push_back( new Cfg_Bool( wxT("/ExternalConnect/TransmitOnlyUploadingClients"), s_TransmitOnlyUploadingClients, false ) ); 1260 1261#ifndef AMULE_DAEMON 1262 // Colors have been moved from global prefs to CStatisticsDlg 1263 for ( int i = 0; i < cntStatColors; i++ ) { 1264 wxString str = CFormat(wxT("/eMule/StatColor%i")) % i; 1265 s_MiscList.push_back( new Cfg_Colour( str, CStatisticsDlg::acrStat[i] ) ); 1266 } 1267#endif 1268 1269 // User events 1270 for (unsigned int i = 0; i < CUserEvents::GetCount(); ++i) { 1271 // We can't use NewCfgItem here, because we need to find these items 1272 // later, which would be impossible in amuled with NewCfgItem. 1273 // The IDs we assign here are high enough to not cause any collision 1274 // even on the daemon. 1275 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); 1276 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); 1277 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); 1278 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); 1279 } 1280} 1281 1282 1283void CPreferences::EraseItemList() 1284{ 1285 while ( s_CfgList.begin() != s_CfgList.end() ) { 1286 delete s_CfgList.begin()->second; 1287 s_CfgList.erase( s_CfgList.begin() ); 1288 } 1289 1290 CFGList::iterator it = s_MiscList.begin(); 1291 for ( ; it != s_MiscList.end(); ) { 1292 delete *it; 1293 it = s_MiscList.erase( it ); 1294 } 1295} 1296 1297 1298void CPreferences::LoadAllItems(wxConfigBase* cfg) 1299{ 1300#ifndef CLIENT_GUI 1301 // Preserve values from old config. The global config object may not be set yet 1302 // when BuildItemList() is called, so we need to provide defaults later - here. 1303 if (cfg->HasEntry(wxT("/eMule/ExecOnCompletion"))) { 1304 bool ExecOnCompletion; 1305 cfg->Read(wxT("/eMule/ExecOnCompletion"), &ExecOnCompletion, false); 1306 // Assign to core command, that's the most likely it was. 1307 static_cast<Cfg_Bool*>(s_CfgList[USEREVENTS_FIRST_ID + CUserEvents::DownloadCompleted * USEREVENTS_IDS_PER_EVENT + 1])->SetDefault(ExecOnCompletion); 1308 cfg->DeleteEntry(wxT("/eMule/ExecOnCompletion")); 1309 } 1310 if (cfg->HasEntry(wxT("/eMule/ExecOnCompletionCommand"))) { 1311 wxString ExecOnCompletionCommand; 1312 cfg->Read(wxT("/eMule/ExecOnCompletionCommand"), &ExecOnCompletionCommand, wxEmptyString); 1313 static_cast<Cfg_Str*>(s_CfgList[USEREVENTS_FIRST_ID + CUserEvents::DownloadCompleted * USEREVENTS_IDS_PER_EVENT + 2])->SetDefault(ExecOnCompletionCommand); 1314 cfg->DeleteEntry(wxT("/eMule/ExecOnCompletionCommand")); 1315 } 1316#endif 1317 CFGMap::iterator it_a = s_CfgList.begin(); 1318 for ( ; it_a != s_CfgList.end(); ++it_a ) { 1319 it_a->second->LoadFromFile( cfg ); 1320 } 1321 1322 CFGList::iterator it_b = s_MiscList.begin(); 1323 for ( ; it_b != s_MiscList.end(); ++it_b ) { 1324 (*it_b)->LoadFromFile( cfg ); 1325 } 1326 1327 // Preserve old value of UDPDisable 1328 if (cfg->HasEntry(wxT("/eMule/UDPDisable"))) { 1329 bool UDPDisable; 1330 cfg->Read(wxT("/eMule/UDPDisable"), &UDPDisable, false); 1331 SetUDPDisable(UDPDisable); 1332 cfg->DeleteEntry(wxT("/eMule/UDPDisable")); 1333 } 1334 1335 // Preserve old value of UseSkinFiles 1336 if (cfg->HasEntry(wxT("/SkinGUIOptions/UseSkinFiles"))) { 1337 bool UseSkinFiles; 1338 cfg->Read(wxT("/SkinGUIOptions/UseSkinFiles"), &UseSkinFiles, false); 1339 if (!UseSkinFiles) { 1340 s_Skin.Clear(); 1341 } 1342 cfg->DeleteEntry(wxT("/SkinGUIOptions/UseSkinFiles")); 1343 } 1344 1345#ifdef __DEBUG__ 1346 // Load debug-categories 1347 int count = theLogger.GetDebugCategoryCount(); 1348 1349 for ( int i = 0; i < count; i++ ) { 1350 const CDebugCategory& cat = theLogger.GetDebugCategory( i ); 1351 1352 bool enabled = false; 1353 cfg->Read( wxT("/Debug/Cat_") + cat.GetName(), &enabled ); 1354 1355 theLogger.SetEnabled( cat.GetType(), enabled ); 1356 } 1357#endif 1358 1359 // Now do some post-processing / sanity checking on the values we just loaded 1360#ifndef CLIENT_GUI 1361 CheckUlDlRatio(); 1362 SetPort(s_port); 1363 if (s_byCryptTCPPaddingLength > 254) { 1364 s_byCryptTCPPaddingLength = GetRandomUint8() % 254; 1365 } 1366 SetSlotAllocation(s_slotallocation); 1367#endif 1368} 1369 1370 1371void CPreferences::SaveAllItems(wxConfigBase* cfg) 1372{ 1373 // Save the Cfg values 1374 CFGMap::iterator it_a = s_CfgList.begin(); 1375 for ( ; it_a != s_CfgList.end(); ++it_a ) 1376 it_a->second->SaveToFile( cfg ); 1377 1378 CFGList::iterator it_b = s_MiscList.begin(); 1379 for ( ; it_b != s_MiscList.end(); ++it_b ) 1380 (*it_b)->SaveToFile( cfg ); 1381 1382 1383// Save debug-categories 1384#ifdef __DEBUG__ 1385 int count = theLogger.GetDebugCategoryCount(); 1386 1387 for ( int i = 0; i < count; i++ ) { 1388 const CDebugCategory& cat = theLogger.GetDebugCategory( i ); 1389 1390 cfg->Write( wxT("/Debug/Cat_") + cat.GetName(), cat.IsEnabled() ); 1391 } 1392#endif 1393} 1394 1395void CPreferences::SetMaxUpload(uint16 in) 1396{ 1397 if ( s_maxupload != in ) { 1398 s_maxupload = in; 1399 1400 // Ensure that the ratio is upheld 1401 CheckUlDlRatio(); 1402 } 1403} 1404 1405 1406void CPreferences::SetMaxDownload(uint16 in) 1407{ 1408 if ( s_maxdownload != in ) { 1409 s_maxdownload = in; 1410 1411 // Ensure that the ratio is upheld 1412 CheckUlDlRatio(); 1413 } 1414} 1415 1416 1417void CPreferences::UnsetAutoServerStart() 1418{ 1419 s_autoserverlist = false; 1420} 1421 1422 1423// Here we slightly limit the users' ability to be a bad citizen: for very low upload rates 1424// we force a low download rate, so as to discourage this type of leeching. 1425// We're Open Source, and whoever wants it can do his own mod to get around this, but the 1426// packaged product will try to enforce good behavior. 1427// 1428// Kry note: of course, any leecher mod will be banned asap. 1429void CPreferences::CheckUlDlRatio() 1430{ 1431 // Backwards compatibility 1432 if ( s_maxupload == 0xFFFF ) 1433 s_maxupload = UNLIMITED; 1434 1435 // Backwards compatibility 1436 if ( s_maxdownload == 0xFFFF ) 1437 s_maxdownload = UNLIMITED; 1438 1439 if ( s_maxupload == UNLIMITED ) 1440 return; 1441 1442 // Enforce the limits 1443 if ( s_maxupload < 4 ) { 1444 if ( ( s_maxupload * 3 < s_maxdownload ) || ( s_maxdownload == 0 ) ) 1445 s_maxdownload = s_maxupload * 3 ; 1446 } else if ( s_maxupload < 10 ) { 1447 if ( ( s_maxupload * 4 < s_maxdownload ) || ( s_maxdownload == 0 ) ) 1448 s_maxdownload = s_maxupload * 4; 1449 } 1450} 1451 1452 1453void CPreferences::Save() 1454{ 1455 wxString fullpath(theApp->ConfigDir + wxT("preferences.dat")); 1456 1457 CFile preffile; 1458 if (!wxFileExists(fullpath)) { 1459 preffile.Create(fullpath); 1460 } 1461 1462 if (preffile.Open(fullpath, CFile::read_write)) { 1463 try { 1464 preffile.WriteUInt8(PREFFILE_VERSION); 1465 preffile.WriteHash(s_userhash); 1466 } catch (const CIOFailureException& e) { 1467 AddDebugLogLineC(logGeneral, wxT("IO failure while saving user-hash: ") + e.what()); 1468 } 1469 } 1470 1471 SavePreferences(); 1472 1473 #ifndef CLIENT_GUI 1474 CTextFile sdirfile; 1475 if (sdirfile.Open(theApp->ConfigDir + wxT("shareddir.dat"), CTextFile::write)) { 1476 for (size_t i = 0; i < shareddir_list.size(); ++i) { 1477 sdirfile.WriteLine(CPath::ToUniv(shareddir_list[i]), wxConvUTF8); 1478 } 1479 1480 } 1481 #endif 1482} 1483 1484 1485CPreferences::~CPreferences() 1486{ 1487 DeleteContents(m_CatList); 1488} 1489 1490 1491int32 CPreferences::GetRecommendedMaxConnections() 1492{ 1493#ifndef CLIENT_GUI 1494 int iRealMax = PlatformSpecific::GetMaxConnections(); 1495 if(iRealMax == -1 || iRealMax > 520) { 1496 return 500; 1497 } 1498 if(iRealMax < 20) { 1499 return iRealMax; 1500 } 1501 if(iRealMax <= 256) { 1502 return iRealMax - 10; 1503 } 1504 return iRealMax - 20; 1505#else 1506 return 500; 1507#endif 1508} 1509 1510 1511void CPreferences::SavePreferences() 1512{ 1513 wxConfigBase* cfg = wxConfigBase::Get(); 1514 1515 cfg->Write( wxT("/eMule/AppVersion"), wxT(VERSION) ); 1516 1517 // Save the options 1518 SaveAllItems( cfg ); 1519 1520 // Ensure that the changes are saved to disk. 1521 cfg->Flush(); 1522} 1523 1524 1525void CPreferences::SaveCats() 1526{ 1527 if ( GetCatCount() ) { 1528 wxConfigBase* cfg = wxConfigBase::Get(); 1529 1530 // Save the main cat. 1531 cfg->Write( wxT("/eMule/AllcatType"), (int)s_allcatFilter); 1532 1533 // The first category is the default one and should not be counted 1534 1535 cfg->Write( wxT("/General/Count"), (long)(m_CatList.size() - 1) ); 1536 1537 uint32 maxcat = m_CatList.size(); 1538 for (uint32 i = 1; i < maxcat; i++) { 1539 cfg->SetPath(CFormat(wxT("/Cat#%i")) % i); 1540 1541 cfg->Write( wxT("Title"), m_CatList[i]->title ); 1542 cfg->Write( wxT("Incoming"), CPath::ToUniv(m_CatList[i]->path) ); 1543 cfg->Write( wxT("Comment"), m_CatList[i]->comment ); 1544 cfg->Write( wxT("Color"), wxString(CFormat(wxT("%u")) % m_CatList[i]->color)); 1545 cfg->Write( wxT("Priority"), (int)m_CatList[i]->prio ); 1546 } 1547 // remove deleted cats from config 1548 while (cfg->DeleteGroup(CFormat(wxT("/Cat#%i")) % maxcat++)) {} 1549 1550 cfg->Flush(); 1551 } 1552} 1553 1554 1555void CPreferences::LoadPreferences() 1556{ 1557 LoadCats(); 1558} 1559 1560 1561void CPreferences::LoadCats() 1562{ 1563 // default cat ... Meow! =(^.^)= 1564 Category_Struct* defaultcat = new Category_Struct; 1565 defaultcat->prio = 0; 1566 defaultcat->color = 0; 1567 1568 AddCat( defaultcat ); 1569 1570 wxConfigBase* cfg = wxConfigBase::Get(); 1571 1572 long max = cfg->Read( wxT("/General/Count"), 0l ); 1573 1574 for ( int i = 1; i <= max ; i++ ) { 1575 cfg->SetPath(CFormat(wxT("/Cat#%i")) % i); 1576 1577 Category_Struct* newcat = new Category_Struct; 1578 1579 newcat->title = cfg->Read( wxT("Title"), wxEmptyString ); 1580 newcat->path = CPath::FromUniv(cfg->Read(wxT("Incoming"), wxEmptyString)); 1581 1582 // Some sanity checking 1583 if ( newcat->title.IsEmpty() || !newcat->path.IsOk() ) { 1584 AddLogLineN(_("Invalid category found, skipping")); 1585 1586 delete newcat; 1587 continue; 1588 } 1589 1590 newcat->comment = cfg->Read( wxT("Comment"), wxEmptyString ); 1591 newcat->prio = cfg->Read( wxT("Priority"), 0l ); 1592 newcat->color = StrToULong(cfg->Read(wxT("Color"), wxT("0"))); 1593 1594 AddCat(newcat); 1595 1596 if (!newcat->path.DirExists()) { 1597 CPath::MakeDir(newcat->path); 1598 } 1599 } 1600} 1601 1602 1603uint16 CPreferences::GetDefaultMaxConperFive() 1604{ 1605 return MAXCONPER5SEC; 1606} 1607 1608 1609uint32 CPreferences::AddCat(Category_Struct* cat) 1610{ 1611 m_CatList.push_back( cat ); 1612 1613 return m_CatList.size() - 1; 1614} 1615 1616 1617void CPreferences::RemoveCat(size_t index) 1618{ 1619 if ( index < m_CatList.size() ) { 1620 CatList::iterator it = m_CatList.begin() + index; 1621 1622 delete *it; 1623 1624 m_CatList.erase( it ); 1625 1626 // remove cat directory from shares 1627 theApp->sharedfiles->Reload(); 1628 } 1629} 1630 1631 1632uint32 CPreferences::GetCatCount() 1633{ 1634 return m_CatList.size(); 1635} 1636 1637 1638Category_Struct* CPreferences::GetCategory(size_t index) 1639{ 1640 wxASSERT( index < m_CatList.size() ); 1641 1642 return m_CatList[index]; 1643} 1644 1645 1646const CPath& CPreferences::GetCatPath(uint8 index) 1647{ 1648 wxASSERT( index < m_CatList.size() ); 1649 1650 return m_CatList[index]->path; 1651} 1652 1653 1654uint32 CPreferences::GetCatColor(size_t index) 1655{ 1656 wxASSERT( index < m_CatList.size() ); 1657 1658 return m_CatList[index]->color; 1659} 1660 1661bool CPreferences::CreateCategory( 1662 Category_Struct *& category, 1663 const wxString& name, 1664 const CPath& path, 1665 const wxString& comment, 1666 uint32 color, 1667 uint8 prio) 1668{ 1669 category = new Category_Struct(); 1670 category->path = thePrefs::GetIncomingDir(); // set a default in case path is invalid 1671 uint32 cat = AddCat(category); 1672 return UpdateCategory(cat, name, path, comment, color, prio); 1673} 1674 1675bool CPreferences::UpdateCategory( 1676 uint8 cat, 1677 const wxString& name, 1678 const CPath& path, 1679 const wxString& comment, 1680 uint32 color, 1681 uint8 prio) 1682{ 1683 Category_Struct *category = m_CatList[cat]; 1684 1685 // return true if path is ok, false if not 1686 bool ret = true; 1687 if (!path.IsOk() || (!path.DirExists() && !CPath::MakeDir(path))) { 1688 ret = false; 1689 // keep path as it was 1690 } else if (category->path != path) { 1691 // path changed: reload shared files, adding files in the new path and removing those from the old path 1692 category->path = path; 1693 theApp->sharedfiles->Reload(); 1694 } 1695 category->title = name; 1696 category->comment = comment; 1697 category->color = color; 1698 category->prio = prio; 1699 1700 SaveCats(); 1701 return ret; 1702} 1703 1704 1705wxString CPreferences::GetBrowser() 1706{ 1707 wxString cmd(s_CustomBrowser); 1708#ifndef __WXMSW__ 1709 if( s_BrowserTab ) { 1710 // This is certainly not the best way to do it, but I'm lazy 1711 if ((wxT("mozilla") == cmd.Right(7)) || (wxT("firefox") == cmd.Right(7)) 1712 || (wxT("MozillaFirebird") == cmd.Right(15))) { 1713 cmd += wxT(" -remote 'openURL(%s, new-tab)'"); 1714 } 1715 if ((wxT("galeon") == cmd.Right(6)) || (wxT("epiphany") == cmd.Right(8))) { 1716 cmd += wxT(" -n '%s'"); 1717 } 1718 if (wxT("opera") == cmd.Right(5)) { 1719 cmd += wxT(" --newpage '%s'"); 1720 } 1721 if (wxT("netscape") == cmd.Right(8)) { 1722 cmd += wxT(" -remote 'openURLs(%s,new-tab)'"); 1723 } 1724 } 1725#endif /* !__WXMSW__ */ 1726 return cmd; 1727} 1728 1729void CPreferences::SetFilteringClients(bool val) 1730{ 1731 if (val != s_IPFilterClients) { 1732 s_IPFilterClients = val; 1733 if (val) { 1734 theApp->clientlist->FilterQueues(); 1735 } 1736 } 1737} 1738 1739void CPreferences::SetFilteringServers(bool val) 1740{ 1741 if (val != s_IPFilterServers) { 1742 s_IPFilterServers = val; 1743 if (val) { 1744 theApp->serverlist->FilterServers(); 1745 } 1746 } 1747} 1748 1749void CPreferences::SetIPFilterLevel(uint8 level) 1750{ 1751 if (level != s_filterlevel) { 1752 // Set the new access-level 1753 s_filterlevel = level; 1754#ifndef CLIENT_GUI 1755 // and reload the filter 1756 NotifyAlways_IPFilter_Reload(); 1757#endif 1758 } 1759} 1760 1761void CPreferences::SetPort(uint16 val) 1762{ 1763 // Warning: Check for +3, because server UDP is TCP+3 1764 1765 if (val +3 > 65535) { 1766 AddLogLineC(_("TCP port can't be higher than 65532 due to server UDP socket being TCP+3")); 1767 AddLogLineN(CFormat(_("Default port will be used (%d)")) % DEFAULT_TCP_PORT); 1768 s_port = DEFAULT_TCP_PORT; 1769 } else { 1770 s_port = val; 1771 } 1772} 1773 1774 1775void CPreferences::ReloadSharedFolders() 1776{ 1777#ifndef CLIENT_GUI 1778 shareddir_list.clear(); 1779 1780 CTextFile file; 1781 if (file.Open(theApp->ConfigDir + wxT("shareddir.dat"), CTextFile::read)) { 1782 wxArrayString lines = file.ReadLines(txtReadDefault, wxConvUTF8); 1783 1784 for (size_t i = 0; i < lines.size(); ++i) { 1785 CPath path = CPath::FromUniv(lines[i]); 1786 1787 if (path.DirExists()) { 1788 shareddir_list.push_back(path); 1789 } else { 1790 AddLogLineN(CFormat(_("Dropping non-existing shared directory: %s")) % path.GetRaw()); 1791 } 1792 } 1793 } 1794#endif 1795} 1796 1797 1798bool CPreferences::IsMessageFiltered(const wxString& message) 1799{ 1800 if (s_FilterAllMessages) { 1801 return true; 1802 } else { 1803 if (s_FilterSomeMessages) { 1804 if (s_MessageFilterString.IsSameAs(wxT("*"))){ 1805 // Filter anything 1806 return true; 1807 } else { 1808 wxStringTokenizer tokenizer( s_MessageFilterString, wxT(",") ); 1809 while (tokenizer.HasMoreTokens()) { 1810 if ( message.Lower().Trim(false).Trim(true).Contains( 1811 tokenizer.GetNextToken().Lower().Trim(false).Trim(true))) { 1812 return true; 1813 } 1814 } 1815 return false; 1816 } 1817 } else { 1818 return false; 1819 } 1820 } 1821} 1822 1823 1824bool CPreferences::IsCommentFiltered(const wxString& comment) 1825{ 1826 if (s_FilterComments) { 1827 wxStringTokenizer tokenizer( s_CommentFilterString, wxT(",") ); 1828 while (tokenizer.HasMoreTokens()) { 1829 if ( comment.Lower().Trim(false).Trim(true).Contains( 1830 tokenizer.GetNextToken().Lower().Trim(false).Trim(true))) { 1831 return true; 1832 } 1833 } 1834 } 1835 return false; 1836} 1837 1838wxString CPreferences::GetLastHTTPDownloadURL(uint8 t) 1839{ 1840 wxConfigBase* cfg = wxConfigBase::Get(); 1841 wxString key = CFormat(wxT("/HTTPDownload/URL_%d")) % t; 1842 return cfg->Read(key, wxEmptyString); 1843} 1844 1845void CPreferences::SetLastHTTPDownloadURL(uint8 t, const wxString& val) 1846{ 1847 wxConfigBase* cfg = wxConfigBase::Get(); 1848 wxString key = CFormat(wxT("/HTTPDownload/URL_%d")) % t; 1849 cfg->Write(key, val); 1850} 1851 1852// File_checked_for_headers 1853