No reason to check for Cryptopp < 5.5
[amule.git] / src / amuleDlg.cpp
blob832696787714c62efd9112421fa4db945c533923
1 //
2 // This file is part of the aMule Project.
3 //
4 // Copyright (c) 2003-2011 aMule Team ( admin@amule.org / http://www.amule.org )
5 // Copyright (c) 2002-2011 Merkur ( devs@emule-project.net / http://www.emule-project.net )
6 //
7 // Any parts of this program derived from the xMule, lMule or eMule project,
8 // or contributed by third-party developers are copyrighted by their
9 // respective authors.
11 // This program is free software; you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation; either version 2 of the License, or
14 // (at your option) any later version.
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU General Public License for more details.
21 // You should have received a copy of the GNU General Public License
22 // along with this program; if not, write to the Free Software
23 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26 #include <wx/app.h>
28 #include <wx/archive.h>
29 #include <wx/config.h> // Do_not_auto_remove (MacOS 10.3, wx 2.7)
30 #include <wx/confbase.h> // Do_not_auto_remove (MacOS 10.3, wx 2.7)
31 #include <wx/html/htmlwin.h>
32 #include <wx/mimetype.h> // Do_not_auto_remove (win32)
33 #include <wx/stattext.h>
34 #include <wx/stdpaths.h>
35 #include <wx/textfile.h> // Do_not_auto_remove (win32)
36 #include <wx/tokenzr.h>
37 #include <wx/wfstream.h>
38 #include <wx/zipstrm.h>
39 #include <wx/sysopt.h>
40 #include <wx/wupdlock.h> // Needed for wxWindowUpdateLocker
41 #include <wx/utils.h> // Needed for wxFindWindowAtPoint
43 #include <common/EventIDs.h>
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
51 #include "amuleDlg.h" // Interface declarations.
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"
80 #ifndef __WINDOWS__
81 #include "aMule.xpm"
82 #endif
84 #include "kademlia/kademlia/Kademlia.h"
85 #include "MuleVersion.h" // Needed for GetMuleVersion()
87 #ifdef ENABLE_IP2COUNTRY
88 #include "IP2Country.h" // Needed for IP2Country
89 #endif
91 #ifdef ENABLE_IP2COUNTRY // That's no bug. MSVC has ENABLE_IP2COUNTRY always on,
92 // but dummy GeoIP.h turns ENABLE_IP2COUNTRY off again.
93 void CamuleDlg::IP2CountryDownloadFinished(uint32 result)
95 m_IP2Country->DownloadFinished(result);
98 void CamuleDlg::EnableIP2Country()
100 if (thePrefs::IsGeoIPEnabled()) {
101 m_IP2Country->Enable();
105 #else
107 void CamuleDlg::IP2CountryDownloadFinished(uint32){}
108 void CamuleDlg::EnableIP2Country(){}
110 #endif
112 BEGIN_EVENT_TABLE(CamuleDlg, wxFrame)
114 EVT_TOOL(ID_BUTTONNETWORKS, CamuleDlg::OnToolBarButton)
115 EVT_TOOL(ID_BUTTONSEARCH, CamuleDlg::OnToolBarButton)
116 EVT_TOOL(ID_BUTTONDOWNLOADS, CamuleDlg::OnToolBarButton)
117 EVT_TOOL(ID_BUTTONSHARED, CamuleDlg::OnToolBarButton)
118 EVT_TOOL(ID_BUTTONMESSAGES, CamuleDlg::OnToolBarButton)
119 EVT_TOOL(ID_BUTTONSTATISTICS, CamuleDlg::OnToolBarButton)
120 EVT_TOOL(ID_ABOUT, CamuleDlg::OnAboutButton)
122 EVT_TOOL(ID_BUTTONNEWPREFERENCES, CamuleDlg::OnPrefButton)
123 EVT_TOOL(ID_BUTTONIMPORT, CamuleDlg::OnImportButton)
125 EVT_TOOL(ID_BUTTONCONNECT, CamuleDlg::OnBnConnect)
127 EVT_CLOSE(CamuleDlg::OnClose)
128 EVT_ICONIZE(CamuleDlg::OnMinimize)
130 EVT_BUTTON(ID_BUTTON_FAST, CamuleDlg::OnBnClickedFast)
132 EVT_TIMER(ID_GUI_TIMER_EVENT, CamuleDlg::OnGUITimer)
134 EVT_SIZE(CamuleDlg::OnMainGUISizeChange)
136 EVT_KEY_UP(CamuleDlg::OnKeyPressed)
138 EVT_MENU(wxID_EXIT, CamuleDlg::OnExit)
140 END_EVENT_TABLE()
142 #ifndef wxCLOSE_BOX
143 #define wxCLOSE_BOX 0
144 #endif
146 CamuleDlg::CamuleDlg(
147 wxWindow* pParent,
148 const wxString &title,
149 wxPoint where,
150 wxSize dlg_size)
152 wxFrame(
153 pParent, -1, title, where, dlg_size,
154 wxCAPTION|wxRESIZE_BORDER|wxSYSTEM_MENU|wxDIALOG_NO_PARENT|
155 wxRESIZE_BORDER|wxMINIMIZE_BOX|wxMAXIMIZE_BOX|wxCLOSE_BOX,
156 wxT("aMule")),
157 m_activewnd(NULL),
158 m_transferwnd(NULL),
159 m_serverwnd(NULL),
160 m_sharedfileswnd(NULL),
161 m_searchwnd(NULL),
162 m_chatwnd(NULL),
163 m_statisticswnd(NULL),
164 m_kademliawnd(NULL),
165 m_prefsDialog(NULL),
166 m_srv_split_pos(0),
167 m_imagelist(16,16),
168 m_tblist(32,32),
169 m_prefsVisible(false),
170 m_wndToolbar(NULL),
171 m_wndTaskbarNotifier(NULL),
172 m_nActiveDialog(DT_NETWORKS_WND),
173 m_is_safe_state(false),
174 m_BlinkMessages(false),
175 m_CurrentBlinkBitmap(24),
176 m_last_iconizing(0),
177 m_skinFileName(),
178 m_clientSkinNames(CLIENT_SKIN_SIZE)
180 // Initialize skin names
181 m_clientSkinNames[Client_Green_Smiley] = wxT("Transfer");
182 m_clientSkinNames[Client_Red_Smiley] = wxT("Connecting");
183 m_clientSkinNames[Client_Yellow_Smiley] = wxT("OnQueue");
184 m_clientSkinNames[Client_Grey_Smiley] = wxT("A4AFNoNeededPartsQueueFull");
185 m_clientSkinNames[Client_White_Smiley] = wxT("StatusUnknown");
186 m_clientSkinNames[Client_ExtendedProtocol_Smiley] = wxT("ExtendedProtocol");
187 m_clientSkinNames[Client_SecIdent_Smiley] = wxT("SecIdent");
188 m_clientSkinNames[Client_BadGuy_Smiley] = wxT("BadGuy");
189 m_clientSkinNames[Client_CreditsGrey_Smiley] = wxT("CreditsGrey");
190 m_clientSkinNames[Client_CreditsYellow_Smiley] = wxT("CreditsYellow");
191 m_clientSkinNames[Client_Upload_Smiley] = wxT("Upload");
192 m_clientSkinNames[Client_Friend_Smiley] = wxT("Friend");
193 m_clientSkinNames[Client_eMule_Smiley] = wxT("eMule");
194 m_clientSkinNames[Client_mlDonkey_Smiley] = wxT("mlDonkey");
195 m_clientSkinNames[Client_eDonkeyHybrid_Smiley] = wxT("eDonkeyHybrid");
196 m_clientSkinNames[Client_aMule_Smiley] = wxT("aMule");
197 m_clientSkinNames[Client_lphant_Smiley] = wxT("lphant");
198 m_clientSkinNames[Client_Shareaza_Smiley] = wxT("Shareaza");
199 m_clientSkinNames[Client_xMule_Smiley] = wxT("xMule");
200 m_clientSkinNames[Client_Unknown] = wxT("Unknown");
201 m_clientSkinNames[Client_InvalidRating_Smiley] = wxT("InvalidRatingOnFile");
202 m_clientSkinNames[Client_PoorRating_Smiley] = wxT("PoorRatingOnFile");
203 m_clientSkinNames[Client_GoodRating_Smiley] = wxT("GoodRatingOnFile");
204 m_clientSkinNames[Client_FairRating_Smiley] = wxT("FairRatingOnFile");
205 m_clientSkinNames[Client_ExcellentRating_Smiley] = wxT("ExcellentRatingOnFile");
206 m_clientSkinNames[Client_CommentOnly_Smiley] = wxT("CommentOnly");
207 m_clientSkinNames[Client_Encryption_Smiley] = wxT("Encrypted");
209 // wxWidgets send idle events to ALL WINDOWS by default... *SIGH*
210 wxIdleEvent::SetMode(wxIDLE_PROCESS_SPECIFIED);
211 wxUpdateUIEvent::SetMode(wxUPDATE_UI_PROCESS_SPECIFIED);
212 wxInitAllImageHandlers();
213 Apply_Clients_Skin();
215 #ifdef __WINDOWS__
216 wxSystemOptions::SetOption(wxT("msw.remap"), 0);
217 #endif
219 #if !(wxCHECK_VERSION(2, 9, 0) && defined(__WXMAC__))
220 // this crashes on Mac with wx 2.9
221 SetIcon(wxICON(aMule));
222 #endif
224 srand(time(NULL));
226 // Create new sizer and stuff a wxPanel in there.
227 wxFlexGridSizer *s_main = new wxFlexGridSizer(1);
228 s_main->AddGrowableCol(0);
229 s_main->AddGrowableRow(0);
231 wxPanel* p_cnt = new wxPanel(this, -1, wxDefaultPosition, wxDefaultSize);
232 s_main->Add(p_cnt, 0, wxGROW|wxEXPAND, 0);
233 muleDlg(p_cnt, false, true);
234 SetSizer(s_main, true);
236 m_serverwnd = new CServerWnd(p_cnt, m_srv_split_pos);
237 AddLogLineN(wxEmptyString);
238 AddLogLineN(wxT(" - ") +
239 CFormat(_("This is aMule %s based on eMule.")) % GetMuleVersion());
240 AddLogLineN(wxT(" ") +
241 CFormat(_("Running on %s")) % wxGetOsDescription());
242 AddLogLineN(wxT(" - ") +
243 wxString(_("Visit http://www.amule.org to check if a new version is available.")));
244 AddLogLineN(wxEmptyString);
246 #ifdef ENABLE_IP2COUNTRY
247 m_GeoIPavailable = true;
248 m_IP2Country = new CIP2Country(thePrefs::GetConfigDir());
249 #else
250 m_GeoIPavailable = false;
251 #endif
252 m_searchwnd = new CSearchDlg(p_cnt);
253 m_transferwnd = new CTransferWnd(p_cnt);
254 m_sharedfileswnd = new CSharedFilesWnd(p_cnt);
255 m_statisticswnd = new CStatisticsDlg(p_cnt, theApp->m_statistics);
256 m_chatwnd = new CChatWnd(p_cnt);
257 m_kademliawnd = CastChild(wxT("kadWnd"), CKadDlg);
259 m_serverwnd->Show(false);
260 m_searchwnd->Show(false);
261 m_transferwnd->Show(false);
262 m_sharedfileswnd->Show(false);
263 m_statisticswnd->Show(false);
264 m_chatwnd->Show(false);
266 // Create the GUI timer
267 gui_timer=new wxTimer(this,ID_GUI_TIMER_EVENT);
268 if (!gui_timer) {
269 AddLogLineN(_("FATAL ERROR: Failed to create Timer"));
270 exit(1);
273 // Set transfers as active window
274 Create_Toolbar(thePrefs::VerticalToolbar());
275 SetActiveDialog(DT_TRANSFER_WND, m_transferwnd);
276 m_wndToolbar->ToggleTool(ID_BUTTONDOWNLOADS, true );
278 bool override_where = (where != wxDefaultPosition);
279 bool override_size = (
280 (dlg_size.x != DEFAULT_SIZE_X) ||
281 (dlg_size.y != DEFAULT_SIZE_Y) );
282 if (!LoadGUIPrefs(override_where, override_size)) {
283 // Prefs not loaded for some reason, exit
284 AddLogLineC(wxT("Error! Unable to load Preferences") );
285 return;
288 // Prepare the dialog, sets the splitter-position (AFTER window size is set)
289 m_transferwnd->Prepare();
291 m_is_safe_state = true;
293 // Init statistics stuff, better do it asap
294 m_statisticswnd->Init();
295 m_kademliawnd->Init();
296 m_searchwnd->UpdateCatChoice();
298 if (thePrefs::UseTrayIcon()) {
299 CreateSystray();
302 Show(true);
303 // Must we start minimized?
304 if (thePrefs::GetStartMinimized()) {
305 Iconize(true);
308 // Set shortcut keys
309 wxAcceleratorEntry entries[] = {
310 wxAcceleratorEntry(wxACCEL_CTRL, wxT('Q'), wxID_EXIT)
313 SetAcceleratorTable(wxAcceleratorTable(itemsof(entries), entries));
314 ShowED2KLinksHandler( thePrefs::GetFED2KLH() );
316 wxNotebook* logs_notebook = CastChild( ID_SRVLOG_NOTEBOOK, wxNotebook);
317 wxNotebook* networks_notebook = CastChild( ID_NETNOTEBOOK, wxNotebook);
319 wxASSERT(logs_notebook->GetPageCount() == 4);
320 wxASSERT(networks_notebook->GetPageCount() == 2);
322 for (uint32 i = 0; i < logs_notebook->GetPageCount(); ++i) {
323 m_logpages[i].page = logs_notebook->GetPage(i);
324 m_logpages[i].name = logs_notebook->GetPageText(i);
327 for (uint32 i = 0; i < networks_notebook->GetPageCount(); ++i) {
328 m_networkpages[i].page = networks_notebook->GetPage(i);
329 m_networkpages[i].name = networks_notebook->GetPageText(i);
332 DoNetworkRearrange();
336 // Madcat - Sets Fast ED2K Links Handler on/off.
337 void CamuleDlg::ShowED2KLinksHandler( bool show )
339 // Errorchecking in case the pointer becomes invalid ...
340 if (s_fed2klh == NULL) {
341 wxLogWarning(wxT("Unable to find Fast ED2K Links handler sizer! Hiding FED2KLH aborted."));
342 return;
345 s_dlgcnt->Show( s_fed2klh, show );
346 s_dlgcnt->Layout();
349 // Toogles ed2k link handler.
350 void CamuleDlg::ToogleED2KLinksHandler()
352 // Errorchecking in case the pointer becomes invalid ...
353 if (s_fed2klh == NULL) {
354 wxLogWarning(wxT("Unable to find Fast ED2K Links handler sizer! Toogling FED2KLH aborted."));
355 return;
357 ShowED2KLinksHandler(!s_dlgcnt->IsShown(s_fed2klh));
360 void CamuleDlg::SetActiveDialog(DialogType type, wxWindow* dlg)
362 m_nActiveDialog = type;
364 if ( type == DT_TRANSFER_WND ) {
365 if (thePrefs::ShowCatTabInfos()) {
366 m_transferwnd->UpdateCatTabTitles();
370 if ( m_activewnd ) {
371 m_activewnd->Show(false);
372 contentSizer->Detach(m_activewnd);
375 contentSizer->Add(dlg, 1, wxALIGN_LEFT|wxEXPAND);
376 dlg->Show(true);
377 m_activewnd=dlg;
378 s_dlgcnt->Layout();
380 // Since we might be suspending redrawing while hiding the dialog
381 // we have to refresh it once it is visible again
382 dlg->Refresh( true );
383 dlg->SetFocus();
385 if ( type == DT_SHARED_WND ) {
386 // set up splitter now that window sizes are defined
387 m_sharedfileswnd->Prepare();
392 void CamuleDlg::UpdateTrayIcon(int percent)
394 // set trayicon-icon
395 if(!theApp->IsConnected()) {
396 m_wndTaskbarNotifier->SetTrayIcon(TRAY_ICON_DISCONNECTED, percent);
397 } else {
398 if(theApp->IsConnectedED2K() && theApp->serverconnect->IsLowID()) {
399 m_wndTaskbarNotifier->SetTrayIcon(TRAY_ICON_LOWID, percent);
400 } else {
401 m_wndTaskbarNotifier->SetTrayIcon(TRAY_ICON_HIGHID, percent);
407 void CamuleDlg::CreateSystray()
409 wxCHECK_RET(m_wndTaskbarNotifier == NULL,
410 wxT("Systray already created"));
412 m_wndTaskbarNotifier = new CMuleTrayIcon();
413 // This will effectively show the Tray Icon.
414 UpdateTrayIcon(0);
418 void CamuleDlg::RemoveSystray()
420 delete m_wndTaskbarNotifier;
421 m_wndTaskbarNotifier = NULL;
425 void CamuleDlg::OnToolBarButton(wxCommandEvent& ev)
427 static int lastbutton = ID_BUTTONDOWNLOADS;
429 // Kry - just if the GUI is ready for it
430 if ( m_is_safe_state ) {
432 // Rehide the handler if needed
433 if ( lastbutton == ID_BUTTONSEARCH && !thePrefs::GetFED2KLH() ) {
434 if (ev.GetId() != ID_BUTTONSEARCH) {
435 ShowED2KLinksHandler( false );
436 } else {
437 // Toogle ED2K handler.
438 ToogleED2KLinksHandler();
442 if ( lastbutton != ev.GetId() ) {
443 switch ( ev.GetId() ) {
444 case ID_BUTTONNETWORKS:
445 SetActiveDialog(DT_NETWORKS_WND, m_serverwnd);
446 // Set serverlist splitter position
447 CastChild( wxT("SrvSplitterWnd"), wxSplitterWindow )->SetSashPosition(m_srv_split_pos, true);
448 break;
450 case ID_BUTTONSEARCH:
451 // The search dialog should always display the handler
452 if ( !thePrefs::GetFED2KLH() )
453 ShowED2KLinksHandler( true );
455 SetActiveDialog(DT_SEARCH_WND, m_searchwnd);
456 break;
458 case ID_BUTTONDOWNLOADS:
459 SetActiveDialog(DT_TRANSFER_WND, m_transferwnd);
460 // Prepare the dialog, sets the splitter-position
461 m_transferwnd->Prepare();
462 break;
464 case ID_BUTTONSHARED:
465 SetActiveDialog(DT_SHARED_WND, m_sharedfileswnd);
466 break;
468 case ID_BUTTONMESSAGES:
469 m_BlinkMessages = false;
470 SetActiveDialog(DT_CHAT_WND, m_chatwnd);
471 break;
473 case ID_BUTTONSTATISTICS:
474 SetActiveDialog(DT_STATS_WND, m_statisticswnd);
475 break;
477 // This shouldn't happen, but just in case
478 default:
479 AddLogLineC(wxT("Unknown button triggered CamuleApp::OnToolBarButton().") );
480 break;
484 m_wndToolbar->ToggleTool(lastbutton, lastbutton == ev.GetId() );
485 lastbutton = ev.GetId();
490 void CamuleDlg::OnAboutButton(wxCommandEvent& WXUNUSED(ev))
492 wxString msg = wxT(" ");
493 #ifdef CLIENT_GUI
494 msg << _("aMule remote control ") << wxT(VERSION);
495 #else
496 msg << wxT("aMule ") << wxT(VERSION);
497 #endif
498 msg << wxT(" ");
499 #ifdef SVNDATE
500 msg << _("Snapshot:") << wxT("\n ") << wxT(SVNDATE);
501 #endif
502 msg << wxT("\n\n") << _("'All-Platform' p2p client based on eMule \n\n") <<
503 _("Website: http://www.amule.org \n") <<
504 _("Forum: http://forum.amule.org \n") <<
505 _("FAQ: http://wiki.amule.org \n\n") <<
506 _("Contact: admin@amule.org (administrative issues) \n") <<
507 _("Copyright (c) 2003-2019 aMule Team \n\n") <<
508 _("Part of aMule is based on \n") <<
509 _("Kademlia: Peer-to-peer routing based on the XOR metric.\n") <<
510 _(" Copyright (c) 2002-2011 Petar Maymounkov ( petar@post.harvard.edu )\n") <<
511 _("http://kademlia.scs.cs.nyu.edu\n");
513 if (m_is_safe_state) {
514 wxMessageBox(msg, _("Message"), wxOK | wxICON_INFORMATION, this);
519 void CamuleDlg::OnPrefButton(wxCommandEvent& WXUNUSED(ev))
521 if (m_is_safe_state) {
522 if (m_prefsDialog == NULL) {
523 m_prefsDialog = new PrefsUnifiedDlg(this);
526 m_prefsDialog->TransferToWindow();
527 m_prefsDialog->Show(true);
528 m_prefsDialog->Raise();
533 void CamuleDlg::OnImportButton(wxCommandEvent& WXUNUSED(ev))
535 #ifndef CLIENT_GUI
536 if (m_is_safe_state) {
537 CPartFileConvertDlg::ShowGUI(NULL);
539 #endif
543 CamuleDlg::~CamuleDlg()
545 theApp->amuledlg = NULL;
547 #ifdef ENABLE_IP2COUNTRY
548 delete m_IP2Country;
549 #endif
551 AddLogLineN(_("aMule dialog destroyed"));
555 void CamuleDlg::OnBnConnect(wxCommandEvent& WXUNUSED(evt))
558 bool disconnect = (theApp->IsConnectedED2K() || theApp->serverconnect->IsConnecting())
559 #ifdef CLIENT_GUI
560 || theApp->IsConnectedKad() // there's no Kad running state atm
561 #else
562 || (Kademlia::CKademlia::IsRunning())
563 #endif
565 if (thePrefs::GetNetworkED2K()) {
566 if (disconnect) {
567 //disconnect if currently connected
568 if (theApp->serverconnect->IsConnecting()) {
569 theApp->serverconnect->StopConnectionTry();
570 } else {
571 theApp->serverconnect->Disconnect();
573 } else {
574 //connect if not currently connected
575 AddLogLineC(_("Connecting"));
576 theApp->serverconnect->ConnectToAnyServer();
578 } else {
579 wxASSERT(!theApp->IsConnectedED2K());
582 // Connect Kad also
583 if (thePrefs::GetNetworkKademlia()) {
584 if( disconnect ) {
585 theApp->StopKad();
586 } else {
587 theApp->StartKad();
589 } else {
590 #ifndef CLIENT_GUI
591 wxASSERT(!Kademlia::CKademlia::IsRunning());
592 #endif
595 ShowConnectionState();
599 void CamuleDlg::ResetLog(int id)
601 wxTextCtrl* ct = CastByID(id, m_serverwnd, wxTextCtrl);
602 wxCHECK_RET(ct, wxT("Resetting unknown log"));
604 ct->Clear();
606 if (id == ID_LOGVIEW) {
607 // Also clear the log line
608 wxStaticText* text = CastChild(wxT("infoLabel"), wxStaticText);
609 text->SetLabel(wxEmptyString);
610 text->GetParent()->Layout();
615 void CamuleDlg::AddLogLine(const wxString& line)
617 bool addtostatusbar = line[0] == '!';
618 wxString bufferline = line.Mid(1);
620 // Add the message to the log-view
621 wxTextCtrl* ct = CastByID( ID_LOGVIEW, m_serverwnd, wxTextCtrl );
622 if ( ct ) {
623 // Bold critical log-lines
624 // Works in Windows too thanks to wxTE_RICH2 style in muuli
625 wxTextAttr style = ct->GetDefaultStyle();
626 wxFont font = style.GetFont();
627 font.SetWeight(addtostatusbar ? wxFONTWEIGHT_BOLD : wxFONTWEIGHT_NORMAL);
628 style.SetFont(font);
629 #if wxCHECK_VERSION(2, 9, 0)
630 style.SetFontSize(8);
631 #endif
632 ct->SetDefaultStyle(style);
633 ct->AppendText(bufferline);
634 ct->ShowPosition( ct->GetLastPosition() - 1 );
638 // Set the status-bar if the event warrents it
639 if ( addtostatusbar ) {
640 // Escape "&"s, which would otherwise not show up
641 bufferline.Replace( wxT("&"), wxT("&&") );
642 wxStaticText* text = CastChild( wxT("infoLabel"), wxStaticText );
643 // Only show the first line if multiple lines
644 text->SetLabel( bufferline.BeforeFirst( wxT('\n') ) );
645 text->SetToolTip( bufferline );
646 text->GetParent()->Layout();
652 void CamuleDlg::AddServerMessageLine(wxString& message)
654 wxTextCtrl* cv= CastByID( ID_SERVERINFO, m_serverwnd, wxTextCtrl );
655 if(cv) {
656 if (message.Length() > 500) {
657 cv->AppendText(message.Left(500) + wxT("\n"));
658 } else {
659 cv->AppendText(message + wxT("\n"));
661 cv->ShowPosition(cv->GetLastPosition()-1);
666 void CamuleDlg::ShowConnectionState(bool skinChanged)
668 static wxImageList status_arrows(16,16,true,0);
669 if (!status_arrows.GetImageCount()) {
670 // Generate the image list (This is only done once)
671 for (int t = 0; t < 7; ++t) {
672 status_arrows.Add(connImages(t));
676 m_serverwnd->UpdateED2KInfo();
677 m_serverwnd->UpdateKadInfo();
680 ////////////////////////////////////////////////////////////
681 // Determine the status of the networks
683 enum ED2KState { ED2KOff = 0, ED2KLowID = 1, ED2KConnecting = 2, ED2KHighID = 3, ED2KUndef = -1 };
684 enum EKadState { EKadOff = 4, EKadFW = 5, EKadConnecting = 5, EKadOK = 6, EKadUndef = -1 };
686 ED2KState ed2kState = ED2KOff;
687 EKadState kadState = EKadOff;
689 ////////////////////////////////////////////////////////////
690 // Update the label on the status-bar and determine
691 // the states of the two networks.
693 wxString msgED2K;
694 if (theApp->IsConnectedED2K()) {
695 CServer* server = theApp->serverconnect->GetCurrentServer();
696 if (server) {
697 msgED2K = CFormat(wxT("eD2k: %s")) % server->GetListName();
700 if (theApp->serverconnect->IsLowID()) {
701 ed2kState = ED2KLowID;
702 } else {
703 ed2kState = ED2KHighID;
705 } else if (theApp->serverconnect->IsConnecting()) {
706 msgED2K = _("eD2k: Connecting");
708 ed2kState = ED2KConnecting;
709 } else if (thePrefs::GetNetworkED2K()) {
710 msgED2K = _("eD2k: Disconnected");
713 wxString msgKad;
714 if (theApp->IsConnectedKad()) {
715 if (theApp->IsFirewalledKad()) {
716 msgKad = _("Kad: Firewalled");
718 kadState = EKadFW;
719 } else {
720 msgKad = _("Kad: Connected");
722 kadState = EKadOK;
724 } else if (theApp->IsKadRunning()) {
725 msgKad = _("Kad: Connecting");
727 kadState = EKadConnecting;
728 } else if (thePrefs::GetNetworkKademlia()) {
729 msgKad = _("Kad: Off");
732 wxStaticText* connLabel = CastChild( wxT("connLabel"), wxStaticText );
733 { wxCHECK_RET(connLabel, wxT("'connLabel' widget not found")); }
735 wxString labelMsg;
736 if (msgED2K.Length() && msgKad.Length()) {
737 labelMsg = msgED2K + wxT(" | ") + msgKad;
738 } else {
739 labelMsg = msgED2K + msgKad;
742 connLabel->SetLabel(labelMsg);
743 connLabel->GetParent()->Layout();
746 ////////////////////////////////////////////////////////////
747 // Update the connect/disconnect/cancel button.
749 enum EConnState {
750 ECS_Unknown,
751 ECS_Connected,
752 ECS_Connecting,
753 ECS_Disconnected
756 static EConnState s_oldState = ECS_Unknown;
757 EConnState currentState = ECS_Disconnected;
759 if (theApp->serverconnect->IsConnecting() ||
760 (theApp->IsKadRunning() && !theApp->IsConnectedKad())) {
761 currentState = ECS_Connecting;
762 } else if (theApp->IsConnected()) {
763 currentState = ECS_Connected;
764 } else {
765 currentState = ECS_Disconnected;
768 if ( (true == skinChanged) || (currentState != s_oldState) ) {
769 wxWindowUpdateLocker freezer(m_wndToolbar);
771 wxToolBarToolBase* toolbarTool = m_wndToolbar->RemoveTool(ID_BUTTONCONNECT);
773 switch (currentState) {
774 case ECS_Connecting:
775 toolbarTool->SetLabel(_("Cancel"));
776 toolbarTool->SetShortHelp(_("Stop the current connection attempts"));
777 toolbarTool->SetNormalBitmap(m_tblist.GetBitmap(2));
778 break;
780 case ECS_Connected:
781 toolbarTool->SetLabel(_("Disconnect"));
782 toolbarTool->SetShortHelp(_("Disconnect from the currently connected networks"));
783 toolbarTool->SetNormalBitmap(m_tblist.GetBitmap(1));
784 break;
786 default:
787 toolbarTool->SetLabel(_("Connect"));
788 toolbarTool->SetShortHelp(_("Connect to the currently enabled networks"));
789 toolbarTool->SetNormalBitmap(m_tblist.GetBitmap(0));
792 m_wndToolbar->InsertTool(0, toolbarTool);
793 m_wndToolbar->Realize();
794 m_wndToolbar->EnableTool(ID_BUTTONCONNECT, (thePrefs::GetNetworkED2K() || thePrefs::GetNetworkKademlia()) && theApp->ipfilter->IsReady());
796 s_oldState = currentState;
800 ////////////////////////////////////////////////////////////
801 // Update the globe-icon in the lower-right corner.
802 // (only if connection state has changed)
804 static ED2KState s_ED2KOldState = ED2KUndef;
805 static EKadState s_EKadOldState = EKadUndef;
806 if (ed2kState != s_ED2KOldState || kadState != s_EKadOldState) {
807 s_ED2KOldState = ed2kState;
808 s_EKadOldState = kadState;
809 wxStaticBitmap* connBitmap = CastChild( wxT("connImage"), wxStaticBitmap );
810 wxCHECK_RET(connBitmap, wxT("'connImage' widget not found"));
812 wxBitmap statusIcon = connBitmap->GetBitmap();
813 // Sanity check - otherwise there's a crash here if aMule runs out of resources
814 if (statusIcon.GetRefData() == NULL) {
815 return;
818 wxMemoryDC bitmapDC(statusIcon);
820 status_arrows.Draw(kadState, bitmapDC, 0, 0, wxIMAGELIST_DRAW_TRANSPARENT);
821 status_arrows.Draw(ed2kState, bitmapDC, 0, 0, wxIMAGELIST_DRAW_TRANSPARENT);
823 connBitmap->SetBitmap(statusIcon);
828 void CamuleDlg::ShowUserCount(const wxString& info)
830 wxStaticText* label = CastChild( wxT("userLabel"), wxStaticText );
832 // Update Kad tab
833 m_serverwnd->UpdateKadInfo();
835 label->SetLabel(info);
836 label->GetParent()->Layout();
840 void CamuleDlg::ShowTransferRate()
842 float kBpsUp = theStats::GetUploadRate() / 1024.0;
843 float kBpsDown = theStats::GetDownloadRate() / 1024.0;
844 float MBpsUp = kBpsUp / 1024.0;
845 float MBpsDown = kBpsDown / 1024.0;
846 bool showMBpsUp = (MBpsUp >= 1);
847 bool showMBpsDown = (MBpsDown >= 1);
848 wxString buffer;
849 if( thePrefs::ShowOverhead() )
851 buffer = CFormat(_("Up: %.1f%s (%.1f) | Down: %.1f%s (%.1f)"))
852 % (showMBpsUp ? MBpsUp : kBpsUp) % (showMBpsUp ? _(" MB/s") : ((kBpsUp > 0) ? _(" kB/s") : "")) % (theStats::GetUpOverheadRate() / 1024.0)
853 % (showMBpsDown ? MBpsDown : kBpsDown) % (showMBpsDown ? _(" MB/s") : ((kBpsDown > 0) ? _(" kB/s") : "")) % (theStats::GetDownOverheadRate() / 1024.0);
854 } else {
855 buffer = CFormat(_("Up: %.1f%s | Down: %.1f%s"))
856 % (showMBpsUp ? MBpsUp : kBpsUp) % (showMBpsUp ? _(" MB/s") : ((kBpsUp > 0) ? _(" kB/s") : ""))
857 % (showMBpsDown ? MBpsDown : kBpsDown) % (showMBpsDown ? _(" MB/s") : ((kBpsDown > 0) ? _(" kB/s") : ""));
859 buffer.Truncate(50); // Max size 50
861 wxStaticText* label = CastChild( wxT("speedLabel"), wxStaticText );
862 label->SetLabel(buffer);
863 label->GetParent()->Layout();
865 // Show upload/download speed in title
866 if (thePrefs::GetShowRatesOnTitle()) {
867 wxString UpDownSpeed = CFormat(wxT("Up: %.1f%s | Down: %.1f%s"))
868 % (showMBpsUp ? MBpsUp : kBpsUp) % (showMBpsUp ? _(" MB/s") : ((kBpsUp > 0) ? _(" kB/s") : ""))
869 % (showMBpsDown ? MBpsDown : kBpsDown) % (showMBpsDown ? _(" MB/s") : ((kBpsDown > 0) ? _(" kB/s") : ""));
870 if (thePrefs::GetShowRatesOnTitle() == 1) {
871 SetTitle(theApp->m_FrameTitle + wxT(" -- ") + UpDownSpeed);
872 } else {
873 SetTitle(UpDownSpeed + wxT(" -- ") + theApp->m_FrameTitle);
877 wxASSERT((m_wndTaskbarNotifier != NULL) == thePrefs::UseTrayIcon());
878 if (m_wndTaskbarNotifier) {
879 // set trayicon-icon
880 int percentDown = (int)ceil((kBpsDown*100) / thePrefs::GetMaxGraphDownloadRate());
881 UpdateTrayIcon( ( percentDown > 100 ) ? 100 : percentDown);
883 wxString buffer2;
884 if ( theApp->IsConnected() ) {
885 buffer2 = CFormat(_("aMule (%s | Connected)")) % buffer;
886 } else {
887 buffer2 = CFormat(_("aMule (%s | Disconnected)")) % buffer;
889 m_wndTaskbarNotifier->SetTrayToolTip(buffer2);
892 wxStaticBitmap* bmp = CastChild( wxT("transferImg"), wxStaticBitmap );
893 bmp->SetBitmap(dlStatusImages((kBpsUp>0.01 ? 2 : 0) + (kBpsDown>0.01 ? 1 : 0)));
896 void CamuleDlg::DlgShutDown()
898 // Are we already shutting down or still on init?
899 if ( m_is_safe_state == false ) {
900 return;
903 // we are going DOWN
904 m_is_safe_state = false;
906 // Stop the GUI Timer
907 delete gui_timer;
908 m_transferwnd->downloadlistctrl->DeleteAllItems();
910 // We want to delete the systray too!
911 RemoveSystray();
914 void CamuleDlg::OnClose(wxCloseEvent& evt)
916 if (thePrefs::HideOnClose() && evt.CanVeto()) {
917 Show(false);
918 evt.Veto();
919 return;
922 // This will be here till the core close is != app close
923 if (evt.CanVeto() && thePrefs::IsConfirmExitEnabled() ) {
924 if (wxNO == wxMessageBox(wxString(CFormat(_("Do you really want to exit %s?")) % theApp->GetMuleAppName()),
925 wxString(_("Exit confirmation")), wxYES_NO, this)) {
926 evt.Veto();
927 return;
931 SaveGUIPrefs();
933 Enable(false);
934 Show(false);
936 theApp->ShutDown(evt);
940 void CamuleDlg::OnBnClickedFast(wxCommandEvent& WXUNUSED(evt))
942 wxTextCtrl* ctl = CastChild( wxT("FastEd2kLinks"), wxTextCtrl );
944 for ( int i = 0; i < ctl->GetNumberOfLines(); i++ ) {
945 wxString strlink = ctl->GetLineText(i);
946 strlink.Trim(true);
947 strlink.Trim(false);
948 if ( !strlink.IsEmpty() ) {
949 theApp->downloadqueue->AddLink( strlink, m_transferwnd->downloadlistctrl->GetCategory() );
953 ctl->SetValue(wxEmptyString);
957 // Formerly known as LoadRazorPrefs()
958 bool CamuleDlg::LoadGUIPrefs(bool override_pos, bool override_size)
960 // Create a config base for loading razor preferences
961 wxConfigBase *config = wxConfigBase::Get();
962 // If config haven't been created exit without loading
963 if (config == NULL) {
964 return false;
967 // The section where to save in in file
968 wxString section = wxT("/Razor_Preferences/");
970 // Get window size and position
971 int x1 = config->Read(section + wxT("MAIN_X_POS"), -1);
972 int y1 = config->Read(section + wxT("MAIN_Y_POS"), -1);
973 int x2 = config->Read(section + wxT("MAIN_X_SIZE"), -1);
974 int y2 = config->Read(section + wxT("MAIN_Y_SIZE"), -1);
976 int maximized = config->Read(section + wxT("Maximized"), 01);
978 // Kry - Random usable pos for m_srv_split_pos
979 m_srv_split_pos = config->Read(section + wxT("SRV_SPLITTER_POS"), 463l);
980 if (!override_size) {
981 if (x2 > 0 && y2 > 0) {
982 SetSize(x2, y2);
983 } else {
984 #ifndef __WXGTK__
985 // Probably first run.
986 Maximize();
987 #endif
991 if (!override_pos) {
992 // If x1 and y1 != -1 Redefine location
993 if(x1 != -1 && y1 != -1) {
994 wxRect display = wxGetClientDisplayRect();
995 if (x1 <= display.GetRightTop().x && y1 <= display.GetRightBottom().y) {
996 Move(x1, y1);
997 } else {
998 // It's offscreen... so let's not.
1003 if (!override_size && !override_pos && maximized) {
1004 Maximize();
1007 return true;
1011 bool CamuleDlg::SaveGUIPrefs()
1013 /* Razor 1a - Modif by MikaelB
1014 Save client size and position */
1016 // Create a config base for saving razor preferences
1017 wxConfigBase *config = wxConfigBase::Get();
1018 // If config haven't been created exit without saving
1019 if (config == NULL) {
1020 return false;
1022 // The section where to save in in file
1023 wxString section = wxT("/Razor_Preferences/");
1025 if (!IsIconized()) {
1026 // Main window location and size
1027 int x1, y1, x2, y2;
1028 GetPosition(&x1, &y1);
1029 GetSize(&x2, &y2);
1031 // Saving window size and position
1032 config->Write(section+wxT("MAIN_X_POS"), (long) x1);
1033 config->Write(section+wxT("MAIN_Y_POS"), (long) y1);
1035 config->Write(section+wxT("MAIN_X_SIZE"), (long) x2);
1036 config->Write(section+wxT("MAIN_Y_SIZE"), (long) y2);
1038 config->Write(section+wxT("Maximized"), (long) (IsMaximized() ? 1 : 0));
1041 // Saving sash position of splitter in server window
1042 config->Write(section+wxT("SRV_SPLITTER_POS"), (long) m_srv_split_pos);
1044 config->Flush(true);
1046 /* End modif */
1048 return true;
1052 void CamuleDlg::OnMinimize(wxIconizeEvent& evt)
1054 // Evil Hack: check if the mouse is inside the window
1055 #ifndef __WINDOWS__
1056 if (wxFindWindowAtPoint(wxGetMousePosition()))
1057 #endif
1059 if (m_prefsDialog && m_prefsDialog->IsShown()) {
1060 // Veto.
1061 } else {
1062 if (m_wndTaskbarNotifier && thePrefs::DoMinToTray()) {
1063 #if wxCHECK_VERSION(2, 9, 0)
1064 Show(!evt.IsIconized());
1065 #else
1066 Show(!evt.Iconized());
1067 #endif
1069 else {
1070 evt.Skip();
1076 void CamuleDlg::OnGUITimer(wxTimerEvent& WXUNUSED(evt))
1078 // Former TimerProc section
1080 static uint32 msPrev1, msPrev5;
1082 uint32 msCur = theStats::GetUptimeMillis();
1084 // can this actually happen under wxwin ?
1085 if (!SafeState()) {
1086 return;
1089 #ifndef CLIENT_GUI
1090 static uint32 msPrevGraph, msPrevStats;
1091 int msGraphUpdate = thePrefs::GetTrafficOMeterInterval() * 1000;
1092 if ((msGraphUpdate > 0) && ((msCur / msGraphUpdate) > (msPrevGraph / msGraphUpdate))) {
1093 // trying to get the graph shifts evenly spaced after a change in the update period
1094 msPrevGraph = msCur;
1096 GraphUpdateInfo update = theApp->m_statistics->GetPointsForUpdate();
1098 m_statisticswnd->UpdateStatGraphs(theStats::GetPeakConnections(), update);
1099 m_kademliawnd->UpdateGraph(update);
1102 int sStatsUpdate = thePrefs::GetStatsInterval();
1103 if ((sStatsUpdate > 0) && ((int)(msCur - msPrevStats) > sStatsUpdate*1000)) {
1104 if (m_statisticswnd->IsShownOnScreen()) {
1105 msPrevStats = msCur;
1106 m_statisticswnd->ShowStatistics();
1109 #endif
1111 if (msCur-msPrev5 > 5000) { // every 5 seconds
1112 msPrev5 = msCur;
1113 ShowTransferRate();
1114 if (thePrefs::ShowCatTabInfos() && theApp->amuledlg->m_activewnd == theApp->amuledlg->m_transferwnd) {
1115 m_transferwnd->UpdateCatTabTitles();
1117 if (thePrefs::AutoSortDownload()) {
1118 m_transferwnd->downloadlistctrl->SortList();
1119 m_transferwnd->clientlistctrl->SortList();
1120 m_sharedfileswnd->peerslistctrl->SortList();
1122 m_kademliawnd->UpdateNodeCount(CStatistics::GetKadNodes());
1125 if (msCur-msPrev1 > 1000) { // every second
1126 msPrev1 = msCur;
1127 if (m_CurrentBlinkBitmap == 12) {
1128 m_CurrentBlinkBitmap = 7;
1129 SetMessagesTool();
1130 } else {
1131 if (m_BlinkMessages) {
1132 m_CurrentBlinkBitmap = 12;
1133 SetMessagesTool();
1141 void CamuleDlg::SetMessagesTool()
1143 wxWindowUpdateLocker freezer(m_wndToolbar);
1144 #ifdef __WXCOCOA__
1145 m_wndToolbar->FindById(ID_BUTTONMESSAGES)->SetNormalBitmap(m_tblist.GetBitmap(m_CurrentBlinkBitmap));
1146 #else
1147 m_wndToolbar->SetToolNormalBitmap(ID_BUTTONMESSAGES, m_tblist.GetBitmap(m_CurrentBlinkBitmap));
1148 #endif
1151 void CamuleDlg::LaunchUrl( const wxString& url )
1153 wxString cmd;
1155 cmd = thePrefs::GetBrowser();
1156 wxString tmp = url;
1157 // Pipes cause problems, so escape them
1158 tmp.Replace( wxT("|"), wxT("%7C") );
1160 if ( !cmd.IsEmpty() ) {
1161 if (!cmd.Replace(wxT("%s"), tmp)) {
1162 // No %s found, just append the url
1163 cmd += wxT(" ") + tmp;
1166 CTerminationProcess *p = new CTerminationProcess(cmd);
1167 if (wxExecute(cmd, wxEXEC_ASYNC, p)) {
1168 AddLogLineN(_("Launch Command: ") + cmd);
1169 return;
1170 } else {
1171 delete p;
1173 } else {
1174 wxLaunchDefaultBrowser(tmp);
1175 return;
1177 // Unable to execute browser. But this error message doesn't make sense,
1178 // cosidering that you _can't_ set the browser executable path... =/
1179 wxLogError(wxT("Unable to launch browser. Please set correct browser executable path in Preferences."));
1183 bool CamuleDlg::Check_and_Init_Skin()
1185 bool ret = true;
1186 wxString skinFileName(thePrefs::GetSkin());
1188 if (skinFileName.IsEmpty() || skinFileName.IsSameAs(_("- default -"))) {
1189 return false;
1192 wxString userDir(JoinPaths(thePrefs::GetConfigDir(), wxT("skins")) + wxFileName::GetPathSeparator());
1194 wxStandardPathsBase &spb(wxStandardPaths::Get());
1195 #ifdef __WINDOWS__
1196 wxString dataDir(spb.GetPluginsDir());
1197 #elif defined(__WXMAC__)
1198 wxString dataDir(spb.GetDataDir());
1199 #else
1200 wxString dataDir(spb.GetDataDir().BeforeLast(wxT('/')) + wxT("/amule"));
1201 #endif
1202 wxString systemDir(JoinPaths(dataDir,wxT("skins")) + wxFileName::GetPathSeparator());
1205 skinFileName.Replace(wxT("User:"), userDir );
1206 skinFileName.Replace(wxT("System:"), systemDir );
1208 m_skinFileName.Assign(skinFileName);
1209 if (!m_skinFileName.FileExists()) {
1210 AddLogLineC(CFormat(
1211 _("Skin directory '%s' does not exist")) %
1212 skinFileName );
1213 ret = false;
1214 } else if (!m_skinFileName.IsFileReadable()) {
1215 AddLogLineC(CFormat(
1216 _("WARNING: Unable to open skin file '%s' for read")) %
1217 skinFileName);
1218 ret = false;
1221 wxFFileInputStream in(m_skinFileName.GetFullPath());
1222 wxZipInputStream zip(in);
1223 wxZipEntry *entry;
1225 while ((entry = zip.GetNextEntry()) != NULL) {
1226 wxZipEntry*& current = cat[entry->GetInternalName()];
1227 delete current;
1228 current = entry;
1231 return ret;
1235 void CamuleDlg::Add_Skin_Icon(
1236 const wxString &iconName,
1237 const wxBitmap &stdIcon,
1238 bool useSkins)
1240 wxImage new_image;
1241 if (useSkins) {
1242 wxFFileInputStream in(m_skinFileName.GetFullPath());
1243 wxZipInputStream zip(in);
1245 ZipCatalog::iterator it = cat.find(wxZipEntry::GetInternalName(iconName + wxT(".png")));
1246 if ( it != cat.end() ) {
1247 zip.OpenEntry(*it->second);
1248 if ( !new_image.LoadFile(zip,wxBITMAP_TYPE_PNG) ) {
1249 AddLogLineN(wxT("Warning: Error loading icon for ") +
1250 iconName);
1251 useSkins = false;
1253 }else {
1254 AddLogLineN(wxT("Warning: Can't load icon for ") +
1255 iconName);
1256 useSkins = false;
1261 wxBitmap bmp(useSkins ? new_image : stdIcon);
1262 if (iconName.StartsWith(wxT("Client_"))) {
1263 m_imagelist.Add(bmp);
1264 } else if (iconName.StartsWith(wxT("Toolbar_"))) {
1265 m_tblist.Add(bmp);
1270 void CamuleDlg::Apply_Clients_Skin()
1272 bool useSkins = Check_and_Init_Skin();
1274 // Clear the client image list
1275 m_imagelist.RemoveAll();
1277 // Add the images to the image list
1278 for (int i = 0; i < CLIENT_SKIN_SIZE; ++i) {
1279 Add_Skin_Icon(wxT("Client_") + m_clientSkinNames[i],
1280 clientImages(i), useSkins);
1285 void CamuleDlg::Apply_Toolbar_Skin(wxToolBar *wndToolbar)
1287 bool useSkins = Check_and_Init_Skin();
1290 // Clear the toolbar image list
1291 m_tblist.RemoveAll();
1293 // Add the images to the image list
1294 Add_Skin_Icon(wxT("Toolbar_Connect"), connButImg(0), useSkins);
1295 Add_Skin_Icon(wxT("Toolbar_Disconnect"), connButImg(1), useSkins);
1296 Add_Skin_Icon(wxT("Toolbar_Connecting"), connButImg(2), useSkins);
1297 Add_Skin_Icon(wxT("Toolbar_Network"), amuleDlgImages(20), useSkins);
1298 Add_Skin_Icon(wxT("Toolbar_Transfers"), amuleDlgImages(21), useSkins);
1299 Add_Skin_Icon(wxT("Toolbar_Search"), amuleDlgImages(22), useSkins);
1300 Add_Skin_Icon(wxT("Toolbar_Shared"), amuleDlgImages(23), useSkins);
1301 Add_Skin_Icon(wxT("Toolbar_Messages"), amuleDlgImages(24), useSkins);
1302 Add_Skin_Icon(wxT("Toolbar_Stats"), amuleDlgImages(25), useSkins);
1303 Add_Skin_Icon(wxT("Toolbar_Prefs"), amuleDlgImages(26), useSkins);
1304 Add_Skin_Icon(wxT("Toolbar_Import"), amuleDlgImages(32), useSkins);
1305 Add_Skin_Icon(wxT("Toolbar_About"), amuleDlgImages(29), useSkins);
1306 Add_Skin_Icon(wxT("Toolbar_Blink"), amuleDlgImages(33), useSkins);
1308 // Build aMule toolbar
1309 wndToolbar->SetMargins(0, 0);
1311 // Placeholder. Gets updated by ShowConnectionState
1312 wndToolbar->AddTool(ID_BUTTONCONNECT, wxT("..."), m_tblist.GetBitmap(0));
1314 wndToolbar->AddSeparator();
1315 wndToolbar->AddTool(ID_BUTTONNETWORKS, _("Networks"), m_tblist.GetBitmap(3), wxNullBitmap, wxITEM_CHECK, _("Networks Window"));
1316 wndToolbar->AddTool(ID_BUTTONSEARCH, _("Searches"), m_tblist.GetBitmap(5), wxNullBitmap, wxITEM_CHECK, _("Searches Window"));
1317 wndToolbar->AddTool(ID_BUTTONDOWNLOADS, _("Downloads"), m_tblist.GetBitmap(4), wxNullBitmap, wxITEM_CHECK, _("Downloads Window"));
1318 wndToolbar->AddTool(ID_BUTTONSHARED, _("Shared files"), m_tblist.GetBitmap(6), wxNullBitmap, wxITEM_CHECK, _("Shared Files Window"));
1319 wndToolbar->AddTool(ID_BUTTONMESSAGES, _("Messages"), m_tblist.GetBitmap(7), wxNullBitmap, wxITEM_CHECK, _("Messages Window"));
1320 wndToolbar->AddTool(ID_BUTTONSTATISTICS, _("Statistics"), m_tblist.GetBitmap(8), wxNullBitmap, wxITEM_CHECK, _("Statistics Graph Window"));
1321 wndToolbar->AddSeparator();
1322 wndToolbar->AddTool(ID_BUTTONNEWPREFERENCES, _("Preferences"), m_tblist.GetBitmap(9), wxNullBitmap, wxITEM_NORMAL, _("Preferences Settings Window"));
1323 #ifndef CLIENT_GUI
1324 wndToolbar->AddTool(ID_BUTTONIMPORT, _("Import"), m_tblist.GetBitmap(10), wxNullBitmap, wxITEM_NORMAL, _("The partfile importer tool"));
1325 #endif
1326 wndToolbar->AddTool(ID_ABOUT, _("About"), m_tblist.GetBitmap(11), wxNullBitmap, wxITEM_NORMAL, _("About/Help"));
1328 wndToolbar->ToggleTool(ID_BUTTONDOWNLOADS, true);
1330 // Needed for non-GTK platforms, where the
1331 // items don't get added immediatly.
1332 wndToolbar->Realize();
1334 // Updates the "Connect" button, and so on.
1335 ShowConnectionState(true);
1339 void CamuleDlg::Create_Toolbar(bool orientation)
1341 Freeze();
1342 // Create ToolBar from the one designed by wxDesigner (BigBob)
1343 wxToolBar *current = GetToolBar();
1345 wxASSERT(current == m_wndToolbar);
1347 if (current) {
1348 bool oldorientation = ((current->GetWindowStyle() & wxTB_VERTICAL) == wxTB_VERTICAL);
1349 if (oldorientation != orientation) {
1350 current->Destroy();
1351 SetToolBar(NULL); // Remove old one if present
1352 m_wndToolbar = NULL;
1353 } else {
1354 current->ClearTools();
1358 if (!m_wndToolbar) {
1359 #if wxCHECK_VERSION(3, 1, 2)
1360 m_wndToolbar = CreateToolBar(
1361 (orientation ? wxTB_VERTICAL : wxTB_HORIZONTAL) |
1362 wxNO_BORDER | wxTB_TEXT | wxTB_FLAT |
1363 wxCLIP_CHILDREN | wxTB_NODIVIDER);
1364 #else
1365 m_wndToolbar = CreateToolBar(
1366 (orientation ? wxTB_VERTICAL : wxTB_HORIZONTAL) |
1367 wxNO_BORDER | wxTB_TEXT | wxTB_3DBUTTONS |
1368 wxTB_FLAT | wxCLIP_CHILDREN | wxTB_NODIVIDER);
1369 #endif
1371 m_wndToolbar->SetToolBitmapSize(wxSize(32, 32));
1374 Apply_Toolbar_Skin(m_wndToolbar);
1376 Thaw();
1380 void CamuleDlg::OnMainGUISizeChange(wxSizeEvent& evt)
1382 wxFrame::OnSize(evt);
1383 if (m_transferwnd && m_transferwnd->clientlistctrl) {
1384 // Transfer window's splitter set again if it's hidden.
1385 if (!m_transferwnd->clientlistctrl->GetShowing()) {
1386 int height = m_transferwnd->clientlistctrl->GetSize().GetHeight();
1387 wxSplitterWindow* splitter =
1388 CastChild(wxT("splitterWnd"), wxSplitterWindow);
1389 height += splitter->GetWindow1()->GetSize().GetHeight();
1390 splitter->SetSashPosition( height );
1396 void CamuleDlg::OnKeyPressed(wxKeyEvent& event)
1398 if (event.GetKeyCode() == WXK_F1) {
1399 // Ctrl/Alt/Shift must not be pressed, to avoid
1400 // conflicts with other (global) shortcuts.
1401 if (!event.HasModifiers() && !event.ShiftDown()) {
1402 LaunchUrl(wxT("http://wiki.amule.org"));
1403 return;
1407 event.Skip();
1411 void CamuleDlg::OnExit(wxCommandEvent& WXUNUSED(evt))
1413 Close(true);
1416 void CamuleDlg::DoNetworkRearrange()
1418 #if !defined(__WXOSX_COCOA__)
1419 // in Mac OS with wxWidgets >= 3.0 and COCOA the following seems to cause problems
1420 // (window is not refreshed after changes in network settings)
1421 wxWindowUpdateLocker freezer(this);
1422 #endif
1424 wxToolBarToolBase* toolbarTool = m_wndToolbar->RemoveTool(ID_BUTTONNETWORKS);
1426 // set the log windows
1427 wxNotebook* logs_notebook = CastChild( ID_SRVLOG_NOTEBOOK, wxNotebook);
1429 while (logs_notebook->GetPageCount() > 1) {
1430 logs_notebook->RemovePage(logs_notebook->GetPageCount() - 1);
1433 if (thePrefs::GetNetworkED2K()) {
1434 #ifndef CLIENT_GUI
1435 logs_notebook->AddPage(m_logpages[1].page, m_logpages[1].name);
1436 #endif
1437 logs_notebook->AddPage(m_logpages[2].page, m_logpages[2].name);
1440 if (thePrefs::GetNetworkKademlia()) {
1441 logs_notebook->AddPage(m_logpages[3].page, m_logpages[3].name);
1444 // Set the main window.
1445 // If we have both networks active, activate a notebook to select between them.
1446 // If only one is active, show the window directly without a surrounding one tab notebook.
1448 // States:
1449 // 1: ED2K only
1450 // 2: Kad only
1451 // 3: both (in Notebook)
1453 static uint8 currentState = 3; // on startup we have both enabled
1454 uint8 newState;
1455 if (thePrefs::GetNetworkED2K() && thePrefs::GetNetworkKademlia()) {
1456 newState = 3;
1457 toolbarTool->SetLabel(_("Networks"));
1459 else if (thePrefs::GetNetworkED2K()) {
1460 newState = 1;
1461 toolbarTool->SetLabel(_("eD2k network"));
1463 else { // Kad only or no network
1464 newState = 2; // no network makes no sense anyway, so just show Kad there
1465 toolbarTool->SetLabel(thePrefs::GetNetworkKademlia() ? _("Kad network") : _("No network"));
1468 if (newState != currentState) {
1469 wxNotebook* networks_notebook = CastChild(ID_NETNOTEBOOK, wxNotebook);
1470 // First hide all windows
1471 networks_notebook->Show(false);
1472 m_networkpages[0].page->Show(false);
1473 m_networkpages[1].page->Show(false);
1474 m_networknotebooksizer->Clear();
1476 wxWindow* replacement = NULL;
1478 // Move both pages into the notebook if they aren't already there.
1479 if (currentState == 1) { // ED2K
1480 m_networkpages[0].page->Reparent(networks_notebook);
1481 networks_notebook->InsertPage(0, m_networkpages[0].page, m_networkpages[0].name);
1482 } else if (currentState == 2) { // Kad
1483 m_networkpages[1].page->Reparent(networks_notebook);
1484 networks_notebook->AddPage(m_networkpages[1].page, m_networkpages[1].name);
1487 // Now both pages are in the notebook. If we want to show one of them outside, move it back out again.
1488 // Windows that are part of a notebook can't be reparented.
1489 if (newState == 3) {
1490 // Since we messed with the notebook, we now have to show both pages, one after the other.
1491 // Otherwise GTK gets confused and shows the first tab only.
1492 // (So much for "platform independent".)
1493 networks_notebook->SetSelection(1);
1494 m_networkpages[1].page->Show();
1495 networks_notebook->SetSelection(0);
1496 m_networkpages[0].page->Show();
1497 replacement = networks_notebook;
1498 } else if (newState == 1) {
1499 replacement = m_networkpages[0].page;
1500 networks_notebook->RemovePage(0);
1501 } else {
1502 replacement = m_networkpages[1].page;
1503 networks_notebook->RemovePage(1);
1506 replacement->Reparent(m_networknotebooksizer->GetContainingWindow());
1507 replacement->Show();
1508 m_networknotebooksizer->Add(replacement, 1, wxGROW | wxALIGN_CENTER_VERTICAL | wxTOP, 5);
1509 m_networknotebooksizer->Layout();
1510 currentState = newState;
1513 // Tool bar
1515 m_wndToolbar->InsertTool(2, toolbarTool);
1516 m_wndToolbar->EnableTool(ID_BUTTONNETWORKS, (thePrefs::GetNetworkED2K() || thePrefs::GetNetworkKademlia()));
1517 m_wndToolbar->EnableTool(ID_BUTTONCONNECT, (thePrefs::GetNetworkED2K() || thePrefs::GetNetworkKademlia()) && theApp->ipfilter->IsReady());
1519 m_wndToolbar->Realize();
1521 ShowConnectionState(); // status in the bottom right
1522 m_searchwnd->FixSearchTypes();
1525 // File_checked_for_headers