1 2// 3// This file is part of the aMule Project. 4// 5// Copyright (c) 2003-2011 aMule Team ( admin@amule.org / http://www.amule.org ) 6// Copyright (c) 2002-2011 Merkur ( devs@emule-project.net / http://www.emule-project.net ) 7// 8// Any parts of this program derived from the xMule, lMule or eMule project, 9// or contributed by third-party developers are copyrighted by their 10// respective authors. 11// 12// This program is free software; you can redistribute it and/or modify 13// it under the terms of the GNU General Public License as published by 14// the Free Software Foundation; either version 2 of the License, or 15// (at your option) any later version. 16// 17// This program is distributed in the hope that it will be useful, 18// but WITHOUT ANY WARRANTY; without even the implied warranty of 19// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20// GNU General Public License for more details. 21// 22// You should have received a copy of the GNU General Public License 23// along with this program; if not, write to the Free Software 24// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 25// 26 27#include <wx/app.h> 28 29#include <wx/archive.h> 30#include <wx/config.h> // Do_not_auto_remove (MacOS 10.3, wx 2.7) 31#include <wx/confbase.h> // Do_not_auto_remove (MacOS 10.3, wx 2.7) 32#include <wx/html/htmlwin.h> 33#include <wx/mimetype.h> // Do_not_auto_remove (win32) 34#include <wx/stattext.h> 35#include <wx/stdpaths.h> 36#include <wx/textfile.h> // Do_not_auto_remove (win32) 37#include <wx/tokenzr.h> 38#include <wx/wfstream.h> 39#include <wx/zipstrm.h> 40#include <wx/sysopt.h> 41#include <wx/wupdlock.h> // Needed for wxWindowUpdateLocker 42 43#include <common/EventIDs.h> 44 45#ifdef HAVE_CONFIG_H 46#include "config.h" // Needed for SVNDATE, PACKAGE, VERSION 47#else 48#include <common/ClientVersion.h> 49#endif // HAVE_CONFIG_H 50 51#include "amuleDlg.h" // Interface declarations. 52 53#include <common/Format.h> // Needed for CFormat 54#include "amule.h" // Needed for theApp 55#include "ChatWnd.h" // Needed for CChatWnd 56#include "SourceListCtrl.h" // Needed for CSourceListCtrl 57#include "DownloadListCtrl.h" // Needed for CDownloadListCtrl 58#include "DownloadQueue.h" // Needed for CDownloadQueue 59#include "KadDlg.h" // Needed for CKadDlg 60#include "Logger.h" 61#include "MuleTrayIcon.h" 62#include "muuli_wdr.h" // Needed for ID_BUTTON* 63#include "Preferences.h" // Needed for CPreferences 64#include "PrefsUnifiedDlg.h" 65#include "SearchDlg.h" // Needed for CSearchDlg 66#include "Server.h" // Needed for CServer 67#include "ServerConnect.h" // Needed for CServerConnect 68#include "ServerWnd.h" // Needed for CServerWnd 69#include "SharedFilesWnd.h" // Needed for CSharedFilesWnd 70#include "SharedFilePeersListCtrl.h" // Needed for CSharedFilePeersListCtrl 71#include "Statistics.h" // Needed for theStats 72#include "StatisticsDlg.h" // Needed for CStatisticsDlg 73#include "TerminationProcess.h" // Needed for CTerminationProcess 74#include "TransferWnd.h" // Needed for CTransferWnd 75#ifndef CLIENT_GUI 76#include "PartFileConvertDlg.h" 77#endif 78#include "IPFilter.h" 79 80#ifndef __WXMSW__ 81#include "aMule.xpm" 82#endif 83 84#include "kademlia/kademlia/Kademlia.h" 85 86#ifdef ENABLE_IP2COUNTRY 87#include "IP2Country.h" // Needed for IP2Country 88#endif 89 90#ifdef ENABLE_IP2COUNTRY // That's no bug. MSVC has ENABLE_IP2COUNTRY always on, 91 // but dummy GeoIP.h turns ENABLE_IP2COUNTRY off again. 92void CamuleDlg::IP2CountryDownloadFinished(uint32 result) 93{ 94 m_IP2Country->DownloadFinished(result); 95} 96 97void CamuleDlg::EnableIP2Country() 98{ 99 if (thePrefs::IsGeoIPEnabled()) { 100 m_IP2Country->Enable(); 101 } 102} 103 104#else 105 106void CamuleDlg::IP2CountryDownloadFinished(uint32){} 107void CamuleDlg::EnableIP2Country(){} 108 109#endif 110 111BEGIN_EVENT_TABLE(CamuleDlg, wxFrame) 112 113 EVT_TOOL(ID_BUTTONNETWORKS, CamuleDlg::OnToolBarButton) 114 EVT_TOOL(ID_BUTTONSEARCH, CamuleDlg::OnToolBarButton) 115 EVT_TOOL(ID_BUTTONDOWNLOADS, CamuleDlg::OnToolBarButton) 116 EVT_TOOL(ID_BUTTONSHARED, CamuleDlg::OnToolBarButton) 117 EVT_TOOL(ID_BUTTONMESSAGES, CamuleDlg::OnToolBarButton) 118 EVT_TOOL(ID_BUTTONSTATISTICS, CamuleDlg::OnToolBarButton) 119 EVT_TOOL(ID_ABOUT, CamuleDlg::OnAboutButton) 120 121 EVT_TOOL(ID_BUTTONNEWPREFERENCES, CamuleDlg::OnPrefButton) 122 EVT_TOOL(ID_BUTTONIMPORT, CamuleDlg::OnImportButton) 123 124 EVT_TOOL(ID_BUTTONCONNECT, CamuleDlg::OnBnConnect) 125 126 EVT_CLOSE(CamuleDlg::OnClose) 127 EVT_ICONIZE(CamuleDlg::OnMinimize) 128 129 EVT_BUTTON(ID_BUTTON_FAST, CamuleDlg::OnBnClickedFast) 130 131 EVT_TIMER(ID_GUI_TIMER_EVENT, CamuleDlg::OnGUITimer) 132 133 EVT_SIZE(CamuleDlg::OnMainGUISizeChange) 134 135 EVT_KEY_UP(CamuleDlg::OnKeyPressed) 136 137 EVT_MENU(wxID_EXIT, CamuleDlg::OnExit) 138 139END_EVENT_TABLE() 140 141#ifndef wxCLOSE_BOX 142 #define wxCLOSE_BOX 0 143#endif 144 145CamuleDlg::CamuleDlg( 146 wxWindow* pParent, 147 const wxString &title, 148 wxPoint where, 149 wxSize dlg_size) 150: 151wxFrame( 152 pParent, -1, title, where, dlg_size, 153 wxCAPTION|wxRESIZE_BORDER|wxSYSTEM_MENU|wxDIALOG_NO_PARENT| 154 wxRESIZE_BORDER|wxMINIMIZE_BOX|wxMAXIMIZE_BOX|wxCLOSE_BOX, 155 wxT("aMule")), 156m_activewnd(NULL), 157m_transferwnd(NULL), 158m_serverwnd(NULL), 159m_sharedfileswnd(NULL), 160m_searchwnd(NULL), 161m_chatwnd(NULL), 162m_statisticswnd(NULL), 163m_kademliawnd(NULL), 164m_prefsDialog(NULL), 165m_srv_split_pos(0), 166m_imagelist(16,16), 167m_tblist(32,32), 168m_prefsVisible(false), 169m_wndToolbar(NULL), 170m_wndTaskbarNotifier(NULL), 171m_nActiveDialog(DT_NETWORKS_WND), 172m_is_safe_state(false), 173m_BlinkMessages(false), 174m_CurrentBlinkBitmap(24), 175m_last_iconizing(0), 176m_skinFileName(), 177m_clientSkinNames(CLIENT_SKIN_SIZE) 178{ 179 // Initialize skin names 180 m_clientSkinNames[Client_Green_Smiley] = wxT("Transfer"); 181 m_clientSkinNames[Client_Red_Smiley] = wxT("Connecting"); 182 m_clientSkinNames[Client_Yellow_Smiley] = wxT("OnQueue"); 183 m_clientSkinNames[Client_Grey_Smiley] = wxT("A4AFNoNeededPartsQueueFull"); 184 m_clientSkinNames[Client_White_Smiley] = wxT("StatusUnknown"); 185 m_clientSkinNames[Client_ExtendedProtocol_Smiley] = wxT("ExtendedProtocol"); 186 m_clientSkinNames[Client_SecIdent_Smiley] = wxT("SecIdent"); 187 m_clientSkinNames[Client_BadGuy_Smiley] = wxT("BadGuy"); 188 m_clientSkinNames[Client_CreditsGrey_Smiley] = wxT("CreditsGrey"); 189 m_clientSkinNames[Client_CreditsYellow_Smiley] = wxT("CreditsYellow"); 190 m_clientSkinNames[Client_Upload_Smiley] = wxT("Upload"); 191 m_clientSkinNames[Client_Friend_Smiley] = wxT("Friend"); 192 m_clientSkinNames[Client_eMule_Smiley] = wxT("eMule"); 193 m_clientSkinNames[Client_mlDonkey_Smiley] = wxT("mlDonkey"); 194 m_clientSkinNames[Client_eDonkeyHybrid_Smiley] = wxT("eDonkeyHybrid"); 195 m_clientSkinNames[Client_aMule_Smiley] = wxT("aMule"); 196 m_clientSkinNames[Client_lphant_Smiley] = wxT("lphant"); 197 m_clientSkinNames[Client_Shareaza_Smiley] = wxT("Shareaza"); 198 m_clientSkinNames[Client_xMule_Smiley] = wxT("xMule"); 199 m_clientSkinNames[Client_Unknown] = wxT("Unknown"); 200 m_clientSkinNames[Client_InvalidRating_Smiley] = wxT("InvalidRatingOnFile"); 201 m_clientSkinNames[Client_PoorRating_Smiley] = wxT("PoorRatingOnFile"); 202 m_clientSkinNames[Client_GoodRating_Smiley] = wxT("GoodRatingOnFile"); 203 m_clientSkinNames[Client_FairRating_Smiley] = wxT("FairRatingOnFile"); 204 m_clientSkinNames[Client_ExcellentRating_Smiley] = wxT("ExcellentRatingOnFile"); 205 m_clientSkinNames[Client_CommentOnly_Smiley] = wxT("CommentOnly"); 206 m_clientSkinNames[Client_Encryption_Smiley] = wxT("Encrypted"); 207 208 // wxWidgets send idle events to ALL WINDOWS by default... *SIGH* 209 wxIdleEvent::SetMode(wxIDLE_PROCESS_SPECIFIED); 210 wxUpdateUIEvent::SetMode(wxUPDATE_UI_PROCESS_SPECIFIED); 211 wxInitAllImageHandlers(); 212 Apply_Clients_Skin(); 213 214#ifdef __WXMSW__ 215 wxSystemOptions::SetOption(wxT("msw.remap"), 0); 216#endif 217 218#if !(wxCHECK_VERSION(2, 9, 0) && defined(__WXMAC__)) 219 // this crashes on Mac with wx 2.9 220 SetIcon(wxICON(aMule)); 221#endif 222 223 srand(time(NULL)); 224 225 // Create new sizer and stuff a wxPanel in there. 226 wxFlexGridSizer *s_main = new wxFlexGridSizer(1); 227 s_main->AddGrowableCol(0); 228 s_main->AddGrowableRow(0); 229 230 wxPanel* p_cnt = new wxPanel(this, -1, wxDefaultPosition, wxDefaultSize); 231 s_main->Add(p_cnt, 0, wxGROW|wxEXPAND, 0); 232 muleDlg(p_cnt, false, true); 233 SetSizer(s_main, true); 234 235 m_serverwnd = new CServerWnd(p_cnt, m_srv_split_pos); 236 AddLogLineN(wxEmptyString); 237 AddLogLineN(wxT(" - ") + 238 CFormat(_("This is aMule %s based on eMule.")) % GetMuleVersion()); 239 AddLogLineN(wxT(" ") + 240 CFormat(_("Running on %s")) % wxGetOsDescription()); 241 AddLogLineN(wxT(" - ") + 242 wxString(_("Visit http://www.amule.org to check if a new version is available."))); 243 AddLogLineN(wxEmptyString); 244 245#ifdef ENABLE_IP2COUNTRY 246 m_GeoIPavailable = true; 247 m_IP2Country = new CIP2Country(theApp->ConfigDir); 248#else 249 m_GeoIPavailable = false; 250#endif 251 m_searchwnd = new CSearchDlg(p_cnt); 252 m_transferwnd = new CTransferWnd(p_cnt); 253 m_sharedfileswnd = new CSharedFilesWnd(p_cnt); 254 m_statisticswnd = new CStatisticsDlg(p_cnt, theApp->m_statistics); 255 m_chatwnd = new CChatWnd(p_cnt); 256 m_kademliawnd = CastChild(wxT("kadWnd"), CKadDlg); 257 258 m_serverwnd->Show(false); 259 m_searchwnd->Show(false); 260 m_transferwnd->Show(false); 261 m_sharedfileswnd->Show(false); 262 m_statisticswnd->Show(false); 263 m_chatwnd->Show(false); 264 265 // Create the GUI timer 266 gui_timer=new wxTimer(this,ID_GUI_TIMER_EVENT); 267 if (!gui_timer) { 268 AddLogLineN(_("FATAL ERROR: Failed to create Timer")); 269 exit(1); 270 } 271 272 // Set transfers as active window 273 Create_Toolbar(thePrefs::VerticalToolbar()); 274 SetActiveDialog(DT_TRANSFER_WND, m_transferwnd); 275 m_wndToolbar->ToggleTool(ID_BUTTONDOWNLOADS, true ); 276 277 bool override_where = (where != wxDefaultPosition); 278 bool override_size = ( 279 (dlg_size.x != DEFAULT_SIZE_X) || 280 (dlg_size.y != DEFAULT_SIZE_Y) ); 281 if (!LoadGUIPrefs(override_where, override_size)) { 282 // Prefs not loaded for some reason, exit 283 AddLogLineC(wxT("Error! Unable to load Preferences") ); 284 return; 285 } 286 287 // Prepare the dialog, sets the splitter-position (AFTER window size is set) 288 m_transferwnd->Prepare(); 289 290 m_is_safe_state = true; 291 292 // Init statistics stuff, better do it asap 293 m_statisticswnd->Init(); 294 m_kademliawnd->Init(); 295 m_searchwnd->UpdateCatChoice(); 296 297 if (thePrefs::UseTrayIcon()) { 298 CreateSystray(); 299 } 300 301 Show(true); 302 // Must we start minimized? 303 if (thePrefs::GetStartMinimized()) { 304 DoIconize(true); 305 } 306 307 // Set shortcut keys 308 wxAcceleratorEntry entries[] = { 309 wxAcceleratorEntry(wxACCEL_CTRL, wxT('Q'), wxID_EXIT) 310 }; 311 312 SetAcceleratorTable(wxAcceleratorTable(itemsof(entries), entries)); 313 ShowED2KLinksHandler( thePrefs::GetFED2KLH() ); 314 315 wxNotebook* logs_notebook = CastChild( ID_SRVLOG_NOTEBOOK, wxNotebook); 316 wxNotebook* networks_notebook = CastChild( ID_NETNOTEBOOK, wxNotebook); 317 318 wxASSERT(logs_notebook->GetPageCount() == 4); 319 wxASSERT(networks_notebook->GetPageCount() == 2); 320 321 for (uint32 i = 0; i < logs_notebook->GetPageCount(); ++i) { 322 m_logpages[i].page = logs_notebook->GetPage(i); 323 m_logpages[i].name = logs_notebook->GetPageText(i); 324 } 325 326 for (uint32 i = 0; i < networks_notebook->GetPageCount(); ++i) { 327 m_networkpages[i].page = networks_notebook->GetPage(i); 328 m_networkpages[i].name = networks_notebook->GetPageText(i); 329 } 330 331 DoNetworkRearrange(); 332} 333 334 335// Madcat - Sets Fast ED2K Links Handler on/off. 336void CamuleDlg::ShowED2KLinksHandler( bool show ) 337{ 338 // Errorchecking in case the pointer becomes invalid ... 339 if (s_fed2klh == NULL) { 340 wxLogWarning(wxT("Unable to find Fast ED2K Links handler sizer! Hiding FED2KLH aborted.")); 341 return; 342 } 343 344 s_dlgcnt->Show( s_fed2klh, show ); 345 s_dlgcnt->Layout(); 346} 347 348// Toogles ed2k link handler. 349void CamuleDlg::ToogleED2KLinksHandler() 350{ 351 // Errorchecking in case the pointer becomes invalid ... 352 if (s_fed2klh == NULL) { 353 wxLogWarning(wxT("Unable to find Fast ED2K Links handler sizer! Toogling FED2KLH aborted.")); 354 return; 355 } 356 ShowED2KLinksHandler(!s_dlgcnt->IsShown(s_fed2klh)); 357} 358 359void CamuleDlg::SetActiveDialog(DialogType type, wxWindow* dlg) 360{ 361 m_nActiveDialog = type; 362 363 if ( type == DT_TRANSFER_WND ) { 364 if (thePrefs::ShowCatTabInfos()) { 365 m_transferwnd->UpdateCatTabTitles(); 366 } 367 } 368 369 if ( m_activewnd ) { 370 m_activewnd->Show(false); 371 contentSizer->Detach(m_activewnd); 372 } 373 374 contentSizer->Add(dlg, 1, wxALIGN_LEFT|wxEXPAND); 375 dlg->Show(true); 376 m_activewnd=dlg; 377 s_dlgcnt->Layout(); 378 379 // Since we might be suspending redrawing while hiding the dialog 380 // we have to refresh it once it is visible again 381 dlg->Refresh( true ); 382 dlg->SetFocus(); 383 384 if ( type == DT_SHARED_WND ) { 385 // set up splitter now that window sizes are defined 386 m_sharedfileswnd->Prepare(); 387 } 388} 389 390 391void CamuleDlg::UpdateTrayIcon(int percent) 392{ 393 // set trayicon-icon 394 if(!theApp->IsConnected()) { 395 m_wndTaskbarNotifier->SetTrayIcon(TRAY_ICON_DISCONNECTED, percent); 396 } else { 397 if(theApp->IsConnectedED2K() && theApp->serverconnect->IsLowID()) { 398 m_wndTaskbarNotifier->SetTrayIcon(TRAY_ICON_LOWID, percent); 399 } else { 400 m_wndTaskbarNotifier->SetTrayIcon(TRAY_ICON_HIGHID, percent); 401 } 402 } 403} 404 405 406void CamuleDlg::CreateSystray() 407{ 408 wxCHECK_RET(m_wndTaskbarNotifier == NULL, 409 wxT("Systray already created")); 410 411 m_wndTaskbarNotifier = new CMuleTrayIcon(); 412 // This will effectively show the Tray Icon. 413 UpdateTrayIcon(0); 414} 415 416 417void CamuleDlg::RemoveSystray() 418{ 419 delete m_wndTaskbarNotifier; 420 m_wndTaskbarNotifier = NULL; 421} 422 423 424void CamuleDlg::OnToolBarButton(wxCommandEvent& ev) 425{ 426 static int lastbutton = ID_BUTTONDOWNLOADS; 427 428 // Kry - just if the GUI is ready for it 429 if ( m_is_safe_state ) { 430 431 // Rehide the handler if needed 432 if ( lastbutton == ID_BUTTONSEARCH && !thePrefs::GetFED2KLH() ) { 433 if (ev.GetId() != ID_BUTTONSEARCH) { 434 ShowED2KLinksHandler( false ); 435 } else { 436 // Toogle ED2K handler. 437 ToogleED2KLinksHandler(); 438 } 439 } 440 441 if ( lastbutton != ev.GetId() ) { 442 switch ( ev.GetId() ) { 443 case ID_BUTTONNETWORKS: 444 SetActiveDialog(DT_NETWORKS_WND, m_serverwnd); 445 // Set serverlist splitter position 446 CastChild( wxT("SrvSplitterWnd"), wxSplitterWindow )->SetSashPosition(m_srv_split_pos, true); 447 break; 448 449 case ID_BUTTONSEARCH: 450 // The search dialog should always display the handler 451 if ( !thePrefs::GetFED2KLH() ) 452 ShowED2KLinksHandler( true ); 453 454 SetActiveDialog(DT_SEARCH_WND, m_searchwnd); 455 break; 456 457 case ID_BUTTONDOWNLOADS: 458 SetActiveDialog(DT_TRANSFER_WND, m_transferwnd); 459 // Prepare the dialog, sets the splitter-position 460 m_transferwnd->Prepare(); 461 break; 462 463 case ID_BUTTONSHARED: 464 SetActiveDialog(DT_SHARED_WND, m_sharedfileswnd); 465 break; 466 467 case ID_BUTTONMESSAGES: 468 m_BlinkMessages = false; 469 SetActiveDialog(DT_CHAT_WND, m_chatwnd); 470 break; 471 472 case ID_BUTTONSTATISTICS: 473 SetActiveDialog(DT_STATS_WND, m_statisticswnd); 474 break; 475 476 // This shouldn't happen, but just in case 477 default: 478 AddLogLineC(wxT("Unknown button triggered CamuleApp::OnToolBarButton().") ); 479 break; 480 } 481 } 482 483 m_wndToolbar->ToggleTool(lastbutton, lastbutton == ev.GetId() ); 484 lastbutton = ev.GetId(); 485 } 486} 487 488 489void CamuleDlg::OnAboutButton(wxCommandEvent& WXUNUSED(ev)) 490{ 491 wxString msg = wxT(" "); 492#ifdef CLIENT_GUI 493 msg << _("aMule remote control ") << wxT(VERSION); 494#else 495 msg << wxT("aMule ") << wxT(VERSION); 496#endif 497 msg << wxT(" "); 498#ifdef SVNDATE 499 msg << _("Snapshot:") << wxT("\n ") << wxT(SVNDATE); 500#endif 501 msg << wxT("\n\n") << _("'All-Platform' p2p client based on eMule \n\n") << 502 _("Website: http://www.amule.org \n") << 503 _("Forum: http://forum.amule.org \n") << 504 _("FAQ: http://wiki.amule.org \n\n") << 505 _("Contact: admin@amule.org (administrative issues) \n") << 506 _("Copyright (c) 2003-2011 aMule Team \n\n") << 507 _("Part of aMule is based on \n") << 508 _("Kademlia: Peer-to-peer routing based on the XOR metric.\n") << 509 _(" Copyright (c) 2002-2011 Petar Maymounkov ( petar@post.harvard.edu )\n") << 510 _("http://kademlia.scs.cs.nyu.edu\n"); 511 512 if (m_is_safe_state) { 513 wxMessageBox(msg, _("Message"), wxOK | wxICON_INFORMATION, this); 514 } 515} 516 517 518void CamuleDlg::OnPrefButton(wxCommandEvent& WXUNUSED(ev)) 519{ 520 if (m_is_safe_state) { 521 if (m_prefsDialog == NULL) { 522 m_prefsDialog = new PrefsUnifiedDlg(this); 523 } 524 525 m_prefsDialog->TransferToWindow(); 526 m_prefsDialog->Show(true); 527 m_prefsDialog->Raise(); 528 } 529} 530 531 532void CamuleDlg::OnImportButton(wxCommandEvent& WXUNUSED(ev)) 533{ 534#ifndef CLIENT_GUI 535 if (m_is_safe_state) { 536 CPartFileConvertDlg::ShowGUI(NULL); 537 } 538#endif 539} 540 541 542CamuleDlg::~CamuleDlg() 543{ 544 theApp->amuledlg = NULL; 545 546#ifdef ENABLE_IP2COUNTRY 547 delete m_IP2Country; 548#endif 549 550 AddLogLineN(_("aMule dialog destroyed")); 551} 552 553 554void CamuleDlg::OnBnConnect(wxCommandEvent& WXUNUSED(evt)) 555{ 556 557 bool disconnect = (theApp->IsConnectedED2K() || theApp->serverconnect->IsConnecting()) 558 #ifdef CLIENT_GUI 559 || theApp->IsConnectedKad() // there's no Kad running state atm 560 #else 561 || (Kademlia::CKademlia::IsRunning()) 562 #endif 563 ; 564 if (thePrefs::GetNetworkED2K()) { 565 if (disconnect) { 566 //disconnect if currently connected 567 if (theApp->serverconnect->IsConnecting()) { 568 theApp->serverconnect->StopConnectionTry(); 569 } else { 570 theApp->serverconnect->Disconnect(); 571 } 572 } else { 573 //connect if not currently connected 574 AddLogLineC(_("Connecting")); 575 theApp->serverconnect->ConnectToAnyServer(); 576 } 577 } else { 578 wxASSERT(!theApp->IsConnectedED2K()); 579 } 580 581 // Connect Kad also 582 if (thePrefs::GetNetworkKademlia()) { 583 if( disconnect ) { 584 theApp->StopKad(); 585 } else { 586 theApp->StartKad(); 587 } 588 } else { 589 #ifndef CLIENT_GUI 590 wxASSERT(!Kademlia::CKademlia::IsRunning()); 591 #endif 592 } 593 594 ShowConnectionState(); 595} 596 597 598void CamuleDlg::ResetLog(int id) 599{ 600 wxTextCtrl* ct = CastByID(id, m_serverwnd, wxTextCtrl); 601 wxCHECK_RET(ct, wxT("Resetting unknown log")); 602 603 ct->Clear(); 604 605 if (id == ID_LOGVIEW) { 606 // Also clear the log line 607 wxStaticText* text = CastChild(wxT("infoLabel"), wxStaticText); 608 text->SetLabel(wxEmptyString); 609 text->GetParent()->Layout(); 610 } 611} 612 613 614void CamuleDlg::AddLogLine(const wxString& line) 615{ 616 bool addtostatusbar = line[0] == '!'; 617 wxString bufferline = line.Mid(1); 618 619 // Add the message to the log-view 620 wxTextCtrl* ct = CastByID( ID_LOGVIEW, m_serverwnd, wxTextCtrl ); 621 if ( ct ) { 622 // Bold critical log-lines 623 // Works in Windows too thanks to wxTE_RICH2 style in muuli 624 wxTextAttr style = ct->GetDefaultStyle(); 625 wxFont font = style.GetFont(); 626 font.SetWeight(addtostatusbar ? wxFONTWEIGHT_BOLD : wxFONTWEIGHT_NORMAL); 627 style.SetFont(font); 628#if wxCHECK_VERSION(2, 9, 0) 629 style.SetFontSize(8); 630#endif 631 ct->SetDefaultStyle(style); 632 ct->AppendText(bufferline); 633 ct->ShowPosition( ct->GetLastPosition() - 1 ); 634 } 635 636 637 // Set the status-bar if the event warrents it 638 if ( addtostatusbar ) { 639 // Escape "&"s, which would otherwise not show up 640 bufferline.Replace( wxT("&"), wxT("&&") ); 641 wxStaticText* text = CastChild( wxT("infoLabel"), wxStaticText ); 642 // Only show the first line if multiple lines 643 text->SetLabel( bufferline.BeforeFirst( wxT('\n') ) ); 644 text->SetToolTip( bufferline ); 645 text->GetParent()->Layout(); 646 } 647 648} 649 650 651void CamuleDlg::AddServerMessageLine(wxString& message) 652{ 653 wxTextCtrl* cv= CastByID( ID_SERVERINFO, m_serverwnd, wxTextCtrl ); 654 if(cv) { 655 if (message.Length() > 500) { 656 cv->AppendText(message.Left(500) + wxT("\n")); 657 } else { 658 cv->AppendText(message + wxT("\n")); 659 } 660 cv->ShowPosition(cv->GetLastPosition()-1); 661 } 662} 663 664 665void CamuleDlg::ShowConnectionState(bool skinChanged) 666{ 667 static wxImageList status_arrows(16,16,true,0); 668 if (!status_arrows.GetImageCount()) { 669 // Generate the image list (This is only done once) 670 for (int t = 0; t < 7; ++t) { 671 status_arrows.Add(connImages(t)); 672 } 673 } 674 675 m_serverwnd->UpdateED2KInfo(); 676 m_serverwnd->UpdateKadInfo(); 677 678 679 //////////////////////////////////////////////////////////// 680 // Determine the status of the networks 681 // 682 enum ED2KState { ED2KOff = 0, ED2KLowID = 1, ED2KConnecting = 2, ED2KHighID = 3, ED2KUndef = -1 }; 683 enum EKadState { EKadOff = 4, EKadFW = 5, EKadConnecting = 5, EKadOK = 6, EKadUndef = -1 }; 684 685 ED2KState ed2kState = ED2KOff; 686 EKadState kadState = EKadOff; 687 688 //////////////////////////////////////////////////////////// 689 // Update the label on the status-bar and determine 690 // the states of the two networks. 691 // 692 wxString msgED2K; 693 if (theApp->IsConnectedED2K()) { 694 CServer* server = theApp->serverconnect->GetCurrentServer(); 695 if (server) { 696 msgED2K = CFormat(wxT("eD2k: %s")) % server->GetListName(); 697 } 698 699 if (theApp->serverconnect->IsLowID()) { 700 ed2kState = ED2KLowID; 701 } else { 702 ed2kState = ED2KHighID; 703 } 704 } else if (theApp->serverconnect->IsConnecting()) { 705 msgED2K = _("eD2k: Connecting"); 706 707 ed2kState = ED2KConnecting; 708 } else if (thePrefs::GetNetworkED2K()) { 709 msgED2K = _("eD2k: Disconnected"); 710 } 711 712 wxString msgKad; 713 if (theApp->IsConnectedKad()) { 714 if (theApp->IsFirewalledKad()) { 715 msgKad = _("Kad: Firewalled"); 716 717 kadState = EKadFW; 718 } else { 719 msgKad = _("Kad: Connected"); 720 721 kadState = EKadOK; 722 } 723 } else if (theApp->IsKadRunning()) { 724 msgKad = _("Kad: Connecting"); 725 726 kadState = EKadConnecting; 727 } else if (thePrefs::GetNetworkKademlia()) { 728 msgKad = _("Kad: Off"); 729 } 730 731 wxStaticText* connLabel = CastChild( wxT("connLabel"), wxStaticText ); 732 { wxCHECK_RET(connLabel, wxT("'connLabel' widget not found")); } 733 734 wxString labelMsg; 735 if (msgED2K.Length() && msgKad.Length()) { 736 labelMsg = msgED2K + wxT(" | ") + msgKad; 737 } else { 738 labelMsg = msgED2K + msgKad; 739 } 740 741 connLabel->SetLabel(labelMsg); 742 connLabel->GetParent()->Layout(); 743 744 745 //////////////////////////////////////////////////////////// 746 // Update the connect/disconnect/cancel button. 747 // 748 enum EConnState { 749 ECS_Unknown, 750 ECS_Connected, 751 ECS_Connecting, 752 ECS_Disconnected 753 }; 754 755 static EConnState s_oldState = ECS_Unknown; 756 EConnState currentState = ECS_Disconnected; 757 758 if (theApp->serverconnect->IsConnecting() || 759 (theApp->IsKadRunning() && !theApp->IsConnectedKad())) { 760 currentState = ECS_Connecting; 761 } else if (theApp->IsConnected()) { 762 currentState = ECS_Connected; 763 } else { 764 currentState = ECS_Disconnected; 765 } 766 767 if ( (true == skinChanged) || (currentState != s_oldState) ) { 768 wxWindowUpdateLocker freezer(m_wndToolbar); 769 770 wxToolBarToolBase* toolbarTool = m_wndToolbar->RemoveTool(ID_BUTTONCONNECT); 771 772 switch (currentState) { 773 case ECS_Connecting: 774 toolbarTool->SetLabel(_("Cancel")); 775 toolbarTool->SetShortHelp(_("Stop the current connection attempts")); 776 toolbarTool->SetNormalBitmap(m_tblist.GetBitmap(2)); 777 break; 778 779 case ECS_Connected: 780 toolbarTool->SetLabel(_("Disconnect")); 781 toolbarTool->SetShortHelp(_("Disconnect from the currently connected networks")); 782 toolbarTool->SetNormalBitmap(m_tblist.GetBitmap(1)); 783 break; 784 785 default: 786 toolbarTool->SetLabel(_("Connect")); 787 toolbarTool->SetShortHelp(_("Connect to the currently enabled networks")); 788 toolbarTool->SetNormalBitmap(m_tblist.GetBitmap(0)); 789 } 790 791 m_wndToolbar->InsertTool(0, toolbarTool); 792 m_wndToolbar->Realize(); 793 m_wndToolbar->EnableTool(ID_BUTTONCONNECT, (thePrefs::GetNetworkED2K() || thePrefs::GetNetworkKademlia()) && theApp->ipfilter->IsReady()); 794 795 s_oldState = currentState; 796 } 797 798 799 //////////////////////////////////////////////////////////// 800 // Update the globe-icon in the lower-right corner. 801 // (only if connection state has changed) 802 // 803 static ED2KState s_ED2KOldState = ED2KUndef; 804 static EKadState s_EKadOldState = EKadUndef; 805 if (ed2kState != s_ED2KOldState || kadState != s_EKadOldState) { 806 s_ED2KOldState = ed2kState; 807 s_EKadOldState = kadState; 808 wxStaticBitmap* connBitmap = CastChild( wxT("connImage"), wxStaticBitmap ); 809 wxCHECK_RET(connBitmap, wxT("'connImage' widget not found")); 810 811 wxBitmap statusIcon = connBitmap->GetBitmap(); 812 // Sanity check - otherwise there's a crash here if aMule runs out of resources 813 if (statusIcon.GetRefData() == NULL) { 814 return; 815 } 816 817 wxMemoryDC bitmapDC(statusIcon); 818 819 status_arrows.Draw(kadState, bitmapDC, 0, 0, wxIMAGELIST_DRAW_TRANSPARENT); 820 status_arrows.Draw(ed2kState, bitmapDC, 0, 0, wxIMAGELIST_DRAW_TRANSPARENT); 821 822 connBitmap->SetBitmap(statusIcon); 823 } 824} 825 826 827void CamuleDlg::ShowUserCount(const wxString& info) 828{ 829 wxStaticText* label = CastChild( wxT("userLabel"), wxStaticText ); 830 831 // Update Kad tab 832 m_serverwnd->UpdateKadInfo(); 833 834 label->SetLabel(info); 835 label->GetParent()->Layout(); 836} 837 838 839void CamuleDlg::ShowTransferRate() 840{ 841 float kBpsUp = theStats::GetUploadRate() / 1024.0; 842 float kBpsDown = theStats::GetDownloadRate() / 1024.0; 843 wxString buffer; 844 if( thePrefs::ShowOverhead() ) 845 { 846 buffer = CFormat(_("Up: %.1f(%.1f) | Down: %.1f(%.1f)")) % kBpsUp % (theStats::GetUpOverheadRate() / 1024.0) % kBpsDown % (theStats::GetDownOverheadRate() / 1024.0); 847 } else { 848 buffer = CFormat(_("Up: %.1f | Down: %.1f")) % kBpsUp % kBpsDown; 849 } 850 buffer.Truncate(50); // Max size 50 851 852 wxStaticText* label = CastChild( wxT("speedLabel"), wxStaticText ); 853 label->SetLabel(buffer); 854 label->GetParent()->Layout(); 855 856 // Show upload/download speed in title 857 if (thePrefs::GetShowRatesOnTitle()) { 858 wxString UpDownSpeed = CFormat(wxT("Up: %.1f | Down: %.1f")) % kBpsUp % kBpsDown; 859 if (thePrefs::GetShowRatesOnTitle() == 1) { 860 SetTitle(theApp->m_FrameTitle + wxT(" -- ") + UpDownSpeed); 861 } else { 862 SetTitle(UpDownSpeed + wxT(" -- ") + theApp->m_FrameTitle); 863 } 864 } 865 866 wxASSERT((m_wndTaskbarNotifier != NULL) == thePrefs::UseTrayIcon()); 867 if (m_wndTaskbarNotifier) { 868 // set trayicon-icon 869 int percentDown = (int)ceil((kBpsDown*100) / thePrefs::GetMaxGraphDownloadRate()); 870 UpdateTrayIcon( ( percentDown > 100 ) ? 100 : percentDown); 871 872 wxString buffer2; 873 if ( theApp->IsConnected() ) { 874 buffer2 = CFormat(_("aMule (%s | Connected)")) % buffer; 875 } else { 876 buffer2 = CFormat(_("aMule (%s | Disconnected)")) % buffer; 877 } 878 m_wndTaskbarNotifier->SetTrayToolTip(buffer2); 879 } 880 881 wxStaticBitmap* bmp = CastChild( wxT("transferImg"), wxStaticBitmap ); 882 bmp->SetBitmap(dlStatusImages((kBpsUp>0.01 ? 2 : 0) + (kBpsDown>0.01 ? 1 : 0))); 883} 884 885void CamuleDlg::DlgShutDown() 886{ 887 // Are we already shutting down or still on init? 888 if ( m_is_safe_state == false ) { 889 return; 890 } 891 892 // we are going DOWN 893 m_is_safe_state = false; 894 895 // Stop the GUI Timer 896 delete gui_timer; 897 m_transferwnd->downloadlistctrl->DeleteAllItems(); 898 899 // We want to delete the systray too! 900 RemoveSystray(); 901} 902 903void CamuleDlg::OnClose(wxCloseEvent& evt) 904{ 905 if (thePrefs::HideOnClose() && evt.CanVeto()) { 906 Show(false); 907 evt.Veto(); 908 return; 909 } 910 911 // This will be here till the core close is != app close 912 if (evt.CanVeto() && thePrefs::IsConfirmExitEnabled() ) { 913 if (wxNO == wxMessageBox(wxString(CFormat(_("Do you really want to exit %s?")) % theApp->GetMuleAppName()), 914 wxString(_("Exit confirmation")), wxYES_NO, this)) { 915 evt.Veto(); 916 return; 917 } 918 } 919 920 SaveGUIPrefs(); 921 922 Enable(false); 923 Show(false); 924 925 theApp->ShutDown(evt); 926} 927 928 929void CamuleDlg::OnBnClickedFast(wxCommandEvent& WXUNUSED(evt)) 930{ 931 wxTextCtrl* ctl = CastChild( wxT("FastEd2kLinks"), wxTextCtrl ); 932 933 for ( int i = 0; i < ctl->GetNumberOfLines(); i++ ) { 934 wxString strlink = ctl->GetLineText(i); 935 strlink.Trim(true); 936 strlink.Trim(false); 937 if ( !strlink.IsEmpty() ) { 938 theApp->downloadqueue->AddLink( strlink, m_transferwnd->downloadlistctrl->GetCategory() ); 939 } 940 } 941 942 ctl->SetValue(wxEmptyString); 943} 944 945 946// Formerly known as LoadRazorPrefs() 947bool CamuleDlg::LoadGUIPrefs(bool override_pos, bool override_size) 948{ 949 // Create a config base for loading razor preferences 950 wxConfigBase *config = wxConfigBase::Get(); 951 // If config haven't been created exit without loading 952 if (config == NULL) { 953 return false; 954 } 955 956 // The section where to save in in file 957 wxString section = wxT("/Razor_Preferences/"); 958 959 // Get window size and position 960 int x1 = config->Read(section + wxT("MAIN_X_POS"), -1); 961 int y1 = config->Read(section + wxT("MAIN_Y_POS"), -1); 962 int x2 = config->Read(section + wxT("MAIN_X_SIZE"), -1); 963 int y2 = config->Read(section + wxT("MAIN_Y_SIZE"), -1); 964 965 int maximized = config->Read(section + wxT("Maximized"), 01); 966 967 // Kry - Random usable pos for m_srv_split_pos 968 m_srv_split_pos = config->Read(section + wxT("SRV_SPLITTER_POS"), 463l); 969 if (!override_size) { 970 if (x2 > 0 && y2 > 0) { 971 SetSize(x2, y2); 972 } else { 973#ifndef __WXGTK__ 974 // Probably first run. 975 Maximize(); 976#endif 977 } 978 } 979 980 if (!override_pos) { 981 // If x1 and y1 != -1 Redefine location 982 if(x1 != -1 && y1 != -1) { 983 wxRect display = wxGetClientDisplayRect(); 984 if (x1 <= display.GetRightTop().x && y1 <= display.GetRightBottom().y) { 985 Move(x1, y1); 986 } else { 987 // It's offscreen... so let's not. 988 } 989 } 990 } 991 992 if (!override_size && !override_pos && maximized) { 993 Maximize(); 994 } 995 996 return true; 997} 998 999 1000bool CamuleDlg::SaveGUIPrefs() 1001{ 1002 /* Razor 1a - Modif by MikaelB 1003 Save client size and position */ 1004 1005 // Create a config base for saving razor preferences 1006 wxConfigBase *config = wxConfigBase::Get(); 1007 // If config haven't been created exit without saving 1008 if (config == NULL) { 1009 return false; 1010 } 1011 // The section where to save in in file 1012 wxString section = wxT("/Razor_Preferences/"); 1013 1014 if (!IsIconized()) { 1015 // Main window location and size 1016 int x1, y1, x2, y2; 1017 GetPosition(&x1, &y1); 1018 GetSize(&x2, &y2); 1019 1020 // Saving window size and position 1021 config->Write(section+wxT("MAIN_X_POS"), (long) x1); 1022 config->Write(section+wxT("MAIN_Y_POS"), (long) y1); 1023 1024 config->Write(section+wxT("MAIN_X_SIZE"), (long) x2); 1025 config->Write(section+wxT("MAIN_Y_SIZE"), (long) y2); 1026 1027 config->Write(section+wxT("Maximized"), (long) (IsMaximized() ? 1 : 0)); 1028 } 1029 1030 // Saving sash position of splitter in server window 1031 config->Write(section+wxT("SRV_SPLITTER_POS"), (long) m_srv_split_pos); 1032 1033 config->Flush(true); 1034 1035 /* End modif */ 1036 1037 return true; 1038} 1039 1040 1041void CamuleDlg::DoIconize(bool iconize) 1042{ 1043 if (m_wndTaskbarNotifier && thePrefs::DoMinToTray()) { 1044 if (iconize) { 1045 // Skip() will do it. 1046 //Iconize(true); 1047 if (SafeState()) { 1048 Show(false); 1049 } 1050 } else { 1051 Show(true); 1052 Raise(); 1053 } 1054 } else { 1055 // Will be done by Skip(); 1056 //Iconize(iconize); 1057 } 1058} 1059 1060void CamuleDlg::OnMinimize(wxIconizeEvent& evt) 1061{ 1062// Evil Hack: check if the mouse is inside the window 1063#ifndef __WXMSW__ 1064 if (GetScreenRect().Contains(wxGetMousePosition())) 1065#endif 1066 { 1067 if (m_prefsDialog && m_prefsDialog->IsShown()) { 1068 // Veto. 1069 } else { 1070 if (m_wndTaskbarNotifier) { 1071#if wxCHECK_VERSION(2, 9, 0) 1072 DoIconize(evt.IsIconized()); 1073#else 1074 DoIconize(evt.Iconized()); 1075#endif 1076 } 1077 evt.Skip(); 1078 } 1079 } 1080} 1081 1082void CamuleDlg::OnGUITimer(wxTimerEvent& WXUNUSED(evt)) 1083{ 1084 // Former TimerProc section 1085 1086 static uint32 msPrev1, msPrev5; 1087 1088 uint32 msCur = theStats::GetUptimeMillis(); 1089 1090 // can this actually happen under wxwin ? 1091 if (!SafeState()) { 1092 return; 1093 } 1094 1095#ifndef CLIENT_GUI 1096 static uint32 msPrevGraph, msPrevStats; 1097 int msGraphUpdate = thePrefs::GetTrafficOMeterInterval() * 1000; 1098 if ((msGraphUpdate > 0) && ((msCur / msGraphUpdate) > (msPrevGraph / msGraphUpdate))) { 1099 // trying to get the graph shifts evenly spaced after a change in the update period 1100 msPrevGraph = msCur; 1101 1102 GraphUpdateInfo update = theApp->m_statistics->GetPointsForUpdate(); 1103 1104 m_statisticswnd->UpdateStatGraphs(theStats::GetPeakConnections(), update); 1105 m_kademliawnd->UpdateGraph(update); 1106 } 1107 1108 int sStatsUpdate = thePrefs::GetStatsInterval(); 1109 if ((sStatsUpdate > 0) && ((int)(msCur - msPrevStats) > sStatsUpdate*1000)) { 1110 if (m_statisticswnd->IsShownOnScreen()) { 1111 msPrevStats = msCur; 1112 m_statisticswnd->ShowStatistics(); 1113 } 1114 } 1115#endif 1116 1117 if (msCur-msPrev5 > 5000) { // every 5 seconds 1118 msPrev5 = msCur; 1119 ShowTransferRate(); 1120 if (thePrefs::ShowCatTabInfos() && theApp->amuledlg->m_activewnd == theApp->amuledlg->m_transferwnd) { 1121 m_transferwnd->UpdateCatTabTitles(); 1122 } 1123 if (thePrefs::AutoSortDownload()) { 1124 m_transferwnd->downloadlistctrl->SortList(); 1125 m_transferwnd->clientlistctrl->SortList(); 1126 m_sharedfileswnd->peerslistctrl->SortList(); 1127 } 1128 } 1129 1130 if (msCur-msPrev1 > 1000) { // every second 1131 msPrev1 = msCur; 1132 if (m_CurrentBlinkBitmap == 12) { 1133 m_CurrentBlinkBitmap = 7; 1134 SetMessagesTool(); 1135 } else { 1136 if (m_BlinkMessages) { 1137 m_CurrentBlinkBitmap = 12; 1138 SetMessagesTool(); 1139 } 1140 } 1141 1142 } 1143} 1144 1145 1146void CamuleDlg::SetMessagesTool() 1147{ 1148 wxWindowUpdateLocker freezer(m_wndToolbar); 1149#ifdef __WXCOCOA__ 1150 m_wndToolbar->FindById(ID_BUTTONMESSAGES)->SetNormalBitmap(m_tblist.GetBitmap(m_CurrentBlinkBitmap)); 1151#else 1152 m_wndToolbar->SetToolNormalBitmap(ID_BUTTONMESSAGES, m_tblist.GetBitmap(m_CurrentBlinkBitmap)); 1153#endif 1154} 1155 1156void CamuleDlg::LaunchUrl( const wxString& url ) 1157{ 1158 wxString cmd; 1159 1160 cmd = thePrefs::GetBrowser(); 1161 wxString tmp = url; 1162 // Pipes cause problems, so escape them 1163 tmp.Replace( wxT("|"), wxT("%7C") ); 1164 1165 if ( !cmd.IsEmpty() ) { 1166 if (!cmd.Replace(wxT("%s"), tmp)) { 1167 // No %s found, just append the url 1168 cmd += wxT(" ") + tmp; 1169 } 1170 1171 CTerminationProcess *p = new CTerminationProcess(cmd); 1172 if (wxExecute(cmd, wxEXEC_ASYNC, p)) { 1173 AddLogLineN(_("Launch Command: ") + cmd); 1174 return; 1175 } else { 1176 delete p; 1177 } 1178 } else { 1179 wxLaunchDefaultBrowser(tmp); 1180 return; 1181 } 1182 // Unable to execute browser. But this error message doesn't make sense, 1183 // cosidering that you _can't_ set the browser executable path... =/ 1184 wxLogError(wxT("Unable to launch browser. Please set correct browser executable path in Preferences.")); 1185} 1186 1187 1188wxString CamuleDlg::GenWebSearchUrl(const wxString &filename, WebSearch wsProvider ) 1189{ 1190 wxString URL; 1191 switch (wsProvider) { 1192 case WS_FILEHASH: 1193 URL = wxT("http://www.filehash.com/search.html?pattern=FILENAME&submit=Find"); 1194 break; 1195 default: 1196 wxFAIL; 1197 } 1198 URL.Replace(wxT("FILENAME"), filename); 1199 1200 return URL; 1201} 1202 1203 1204bool CamuleDlg::Check_and_Init_Skin() 1205{ 1206 bool ret = true; 1207 wxString skinFileName(thePrefs::GetSkin()); 1208 1209 if (skinFileName.IsEmpty() || skinFileName.IsSameAs(_("- default -"))) { 1210 return false; 1211 } 1212 1213 wxString userDir(JoinPaths(GetConfigDir(), wxT("skins")) + wxFileName::GetPathSeparator()); 1214 1215 wxStandardPathsBase &spb(wxStandardPaths::Get()); 1216#ifdef __WXMSW__ 1217 wxString dataDir(spb.GetPluginsDir()); 1218#elif defined(__WXMAC__) 1219 wxString dataDir(spb.GetDataDir()); 1220#else 1221 wxString dataDir(spb.GetDataDir().BeforeLast(wxT('/')) + wxT("/amule")); 1222#endif 1223 wxString systemDir(JoinPaths(dataDir,wxT("skins")) + wxFileName::GetPathSeparator()); 1224 1225 1226 skinFileName.Replace(wxT("User:"), userDir ); 1227 skinFileName.Replace(wxT("System:"), systemDir ); 1228 1229 m_skinFileName.Assign(skinFileName); 1230 if (!m_skinFileName.FileExists()) { 1231 AddLogLineC(CFormat( 1232 _("Skin directory '%s' does not exist")) % 1233 skinFileName ); 1234 ret = false; 1235 } else if (!m_skinFileName.IsFileReadable()) { 1236 AddLogLineC(CFormat( 1237 _("WARNING: Unable to open skin file '%s' for read")) % 1238 skinFileName); 1239 ret = false; 1240 } 1241 1242 wxFFileInputStream in(m_skinFileName.GetFullPath()); 1243 wxZipInputStream zip(in); 1244 1245 while ((entry = zip.GetNextEntry()) != NULL) { 1246 wxZipEntry*& current = cat[entry->GetInternalName()]; 1247 delete current; 1248 current = entry; 1249 } 1250 1251 return ret; 1252} 1253 1254 1255void CamuleDlg::Add_Skin_Icon( 1256 const wxString &iconName, 1257 const wxBitmap &stdIcon, 1258 bool useSkins) 1259{ 1260 wxImage new_image; 1261 if (useSkins) { 1262 wxFFileInputStream in(m_skinFileName.GetFullPath()); 1263 wxZipInputStream zip(in); 1264 1265 it = cat.find(wxZipEntry::GetInternalName(iconName + wxT(".png"))); 1266 if ( it != cat.end() ) { 1267 zip.OpenEntry(*it->second); 1268 if ( !new_image.LoadFile(zip,wxBITMAP_TYPE_PNG) ) { 1269 AddLogLineN(wxT("Warning: Error loading icon for ") + 1270 iconName); 1271 useSkins = false; 1272 } 1273 }else { 1274 AddLogLineN(wxT("Warning: Can't load icon for ") + 1275 iconName); 1276 useSkins = false; 1277 } 1278 1279 } 1280 1281 wxBitmap bmp(useSkins ? new_image : stdIcon); 1282 if (iconName.StartsWith(wxT("Client_"))) { 1283 m_imagelist.Add(bmp); 1284 } else if (iconName.StartsWith(wxT("Toolbar_"))) { 1285 m_tblist.Add(bmp); 1286 } 1287} 1288 1289 1290void CamuleDlg::Apply_Clients_Skin() 1291{ 1292 bool useSkins = Check_and_Init_Skin(); 1293 1294 // Clear the client image list 1295 m_imagelist.RemoveAll(); 1296 1297 // Add the images to the image list 1298 for (int i = 0; i < CLIENT_SKIN_SIZE; ++i) { 1299 Add_Skin_Icon(wxT("Client_") + m_clientSkinNames[i], 1300 clientImages(i), useSkins); 1301 } 1302} 1303 1304 1305void CamuleDlg::Apply_Toolbar_Skin(wxToolBar *wndToolbar) 1306{ 1307 bool useSkins = Check_and_Init_Skin(); 1308 1309 1310 // Clear the toolbar image list 1311 m_tblist.RemoveAll(); 1312 1313 // Add the images to the image list 1314 Add_Skin_Icon(wxT("Toolbar_Connect"), connButImg(0), useSkins); 1315 Add_Skin_Icon(wxT("Toolbar_Disconnect"), connButImg(1), useSkins); 1316 Add_Skin_Icon(wxT("Toolbar_Connecting"), connButImg(2), useSkins); 1317 Add_Skin_Icon(wxT("Toolbar_Network"), amuleDlgImages(20), useSkins); 1318 Add_Skin_Icon(wxT("Toolbar_Transfers"), amuleDlgImages(21), useSkins); 1319 Add_Skin_Icon(wxT("Toolbar_Search"), amuleDlgImages(22), useSkins); 1320 Add_Skin_Icon(wxT("Toolbar_Shared"), amuleDlgImages(23), useSkins); 1321 Add_Skin_Icon(wxT("Toolbar_Messages"), amuleDlgImages(24), useSkins); 1322 Add_Skin_Icon(wxT("Toolbar_Stats"), amuleDlgImages(25), useSkins); 1323 Add_Skin_Icon(wxT("Toolbar_Prefs"), amuleDlgImages(26), useSkins); 1324 Add_Skin_Icon(wxT("Toolbar_Import"), amuleDlgImages(32), useSkins); 1325 Add_Skin_Icon(wxT("Toolbar_About"), amuleDlgImages(29), useSkins); 1326 Add_Skin_Icon(wxT("Toolbar_Blink"), amuleDlgImages(33), useSkins); 1327 1328 // Build aMule toolbar 1329 wndToolbar->SetMargins(0, 0); 1330 1331 // Placeholder. Gets updated by ShowConnectionState 1332 wndToolbar->AddTool(ID_BUTTONCONNECT, wxT("..."), m_tblist.GetBitmap(0)); 1333 1334 wndToolbar->AddSeparator(); 1335 wndToolbar->AddTool(ID_BUTTONNETWORKS, _("Networks"), m_tblist.GetBitmap(3), wxNullBitmap, wxITEM_CHECK, _("Networks Window")); 1336 wndToolbar->AddTool(ID_BUTTONSEARCH, _("Searches"), m_tblist.GetBitmap(5), wxNullBitmap, wxITEM_CHECK, _("Searches Window")); 1337 wndToolbar->AddTool(ID_BUTTONDOWNLOADS, _("Downloads"), m_tblist.GetBitmap(4), wxNullBitmap, wxITEM_CHECK, _("Downloads Window")); 1338 wndToolbar->AddTool(ID_BUTTONSHARED, _("Shared files"), m_tblist.GetBitmap(6), wxNullBitmap, wxITEM_CHECK, _("Shared Files Window")); 1339 wndToolbar->AddTool(ID_BUTTONMESSAGES, _("Messages"), m_tblist.GetBitmap(7), wxNullBitmap, wxITEM_CHECK, _("Messages Window")); 1340 wndToolbar->AddTool(ID_BUTTONSTATISTICS, _("Statistics"), m_tblist.GetBitmap(8), wxNullBitmap, wxITEM_CHECK, _("Statistics Graph Window")); 1341 wndToolbar->AddSeparator(); 1342 wndToolbar->AddTool(ID_BUTTONNEWPREFERENCES, _("Preferences"), m_tblist.GetBitmap(9), wxNullBitmap, wxITEM_NORMAL, _("Preferences Settings Window")); 1343#ifndef CLIENT_GUI 1344 wndToolbar->AddTool(ID_BUTTONIMPORT, _("Import"), m_tblist.GetBitmap(10), wxNullBitmap, wxITEM_NORMAL, _("The partfile importer tool")); 1345#endif 1346 wndToolbar->AddTool(ID_ABOUT, _("About"), m_tblist.GetBitmap(11), wxNullBitmap, wxITEM_NORMAL, _("About/Help")); 1347 1348 wndToolbar->ToggleTool(ID_BUTTONDOWNLOADS, true); 1349 1350 // Needed for non-GTK platforms, where the 1351 // items don't get added immediatly. 1352 wndToolbar->Realize(); 1353 1354 // Updates the "Connect" button, and so on. 1355 ShowConnectionState(true); 1356} 1357 1358 1359void CamuleDlg::Create_Toolbar(bool orientation) 1360{ 1361 Freeze(); 1362 // Create ToolBar from the one designed by wxDesigner (BigBob) 1363 wxToolBar *current = GetToolBar(); 1364 1365 wxASSERT(current == m_wndToolbar); 1366 1367 if (current) { 1368 bool oldorientation = ((current->GetWindowStyle() & wxTB_VERTICAL) == wxTB_VERTICAL); 1369 if (oldorientation != orientation) { 1370 current->Destroy(); 1371 SetToolBar(NULL); // Remove old one if present 1372 m_wndToolbar = NULL; 1373 } else { 1374 current->ClearTools(); 1375 } 1376 } 1377 1378 if (!m_wndToolbar) { 1379 m_wndToolbar = CreateToolBar( 1380 (orientation ? wxTB_VERTICAL : wxTB_HORIZONTAL) | 1381 wxNO_BORDER | wxTB_TEXT | wxTB_3DBUTTONS | 1382 wxTB_FLAT | wxCLIP_CHILDREN | wxTB_NODIVIDER); 1383 1384 1385 m_wndToolbar->SetToolBitmapSize(wxSize(32, 32)); 1386 } 1387 1388 Apply_Toolbar_Skin(m_wndToolbar); 1389 1390 Thaw(); 1391} 1392 1393 1394void CamuleDlg::OnMainGUISizeChange(wxSizeEvent& evt) 1395{ 1396 wxFrame::OnSize(evt); 1397 if (m_transferwnd && m_transferwnd->clientlistctrl) { 1398 // Transfer window's splitter set again if it's hidden. 1399 if (!m_transferwnd->clientlistctrl->GetShowing()) { 1400 int height = m_transferwnd->clientlistctrl->GetSize().GetHeight(); 1401 wxSplitterWindow* splitter = 1402 CastChild(wxT("splitterWnd"), wxSplitterWindow); 1403 height += splitter->GetWindow1()->GetSize().GetHeight(); 1404 splitter->SetSashPosition( height ); 1405 } 1406 } 1407} 1408 1409 1410void CamuleDlg::OnKeyPressed(wxKeyEvent& event) 1411{ 1412 if (event.GetKeyCode() == WXK_F1) { 1413 // Ctrl/Alt/Shift must not be pressed, to avoid 1414 // conflicts with other (global) shortcuts. 1415 if (!event.HasModifiers() && !event.ShiftDown()) { 1416 LaunchUrl(wxT("http://wiki.amule.org")); 1417 return; 1418 } 1419 } 1420 1421 event.Skip(); 1422} 1423 1424 1425void CamuleDlg::OnExit(wxCommandEvent& WXUNUSED(evt)) 1426{ 1427 Close(true); 1428} 1429 1430void CamuleDlg::DoNetworkRearrange() 1431{ 1432 wxWindowUpdateLocker freezer(this); 1433 1434 wxToolBarToolBase* toolbarTool = m_wndToolbar->RemoveTool(ID_BUTTONNETWORKS); 1435 1436 wxNotebook* logs_notebook = CastChild( ID_SRVLOG_NOTEBOOK, wxNotebook); 1437 wxNotebook* networks_notebook = CastChild( ID_NETNOTEBOOK, wxNotebook); 1438 1439 while (logs_notebook->GetPageCount() > 1) { 1440 logs_notebook->RemovePage(logs_notebook->GetPageCount() - 1); 1441 } 1442 1443 while (networks_notebook->GetPageCount() > 0) { 1444 networks_notebook->RemovePage(networks_notebook->GetPageCount() - 1); 1445 } 1446 1447 if (thePrefs::GetNetworkED2K()) { 1448#ifndef CLIENT_GUI 1449 logs_notebook->AddPage(m_logpages[1].page, m_logpages[1].name); 1450#endif 1451 logs_notebook->AddPage(m_logpages[2].page, m_logpages[2].name); 1452 } 1453 1454 m_networkpages[0].page->Show(thePrefs::GetNetworkED2K()); 1455 1456 if (thePrefs::GetNetworkKademlia()) { 1457 logs_notebook->AddPage(m_logpages[3].page, m_logpages[3].name); 1458 } 1459 1460 m_networkpages[1].page->Show(thePrefs::GetNetworkKademlia()); 1461 1462 networks_notebook->Show(thePrefs::GetNetworkED2K() && thePrefs::GetNetworkKademlia()); 1463 1464 wxWindow* replacement = NULL; 1465 1466 m_networknotebooksizer->Clear(); 1467 1468 if (thePrefs::GetNetworkED2K() && thePrefs::GetNetworkKademlia()) { 1469 toolbarTool->SetLabel(_("Networks")); 1470 1471 m_networkpages[0].page->Reparent(networks_notebook); 1472 m_networkpages[1].page->Reparent(networks_notebook); 1473 1474 networks_notebook->AddPage(m_networkpages[0].page, m_networkpages[0].name); 1475 networks_notebook->AddPage(m_networkpages[1].page, m_networkpages[1].name); 1476 1477 replacement = networks_notebook; 1478 1479 } else if (thePrefs::GetNetworkED2K()) { 1480 toolbarTool->SetLabel(_("eD2k network")); 1481 replacement = m_networkpages[0].page; 1482 m_networkpages[1].page->Reparent(m_networknotebooksizer->GetContainingWindow()); 1483 } else if (thePrefs::GetNetworkKademlia()) { 1484 toolbarTool->SetLabel(_("Kad network")); 1485 m_networkpages[0].page->Reparent(m_networknotebooksizer->GetContainingWindow()); 1486 replacement = m_networkpages[1].page; 1487 } else { 1488 // No networks. 1489 toolbarTool->SetLabel(_("No network")); 1490 } 1491 1492 if (replacement) { 1493 replacement->Reparent(m_networknotebooksizer->GetContainingWindow()); 1494 m_networknotebooksizer->Add( replacement, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxTOP, 5 ); 1495 m_networknotebooksizer->Layout(); 1496 } 1497 1498 m_wndToolbar->InsertTool(2, toolbarTool); 1499 1500 m_wndToolbar->EnableTool(ID_BUTTONNETWORKS, (thePrefs::GetNetworkED2K() || thePrefs::GetNetworkKademlia())); 1501 m_wndToolbar->EnableTool(ID_BUTTONCONNECT, (thePrefs::GetNetworkED2K() || thePrefs::GetNetworkKademlia()) && theApp->ipfilter->IsReady()); 1502 1503 m_wndToolbar->Realize(); 1504 1505 m_searchwnd->FixSearchTypes(); 1506} 1507 1508// File_checked_for_headers 1509