Upstream tarball 9667
[amule.git] / src / amuleDlg.cpp
blobb11f6607adeb0ecd4b2d5839763daa84bda1c7ee
2 //
3 // This file is part of the aMule Project.
4 //
5 // Copyright (c) 2003-2008 aMule Team ( admin@amule.org / http://www.amule.org )
6 // Copyright (c) 2002-2008 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.
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.
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
27 #include <wx/app.h>
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 #include <wx/utils.h> // Needed for wxBusyCursor
44 #include <common/EventIDs.h>
46 #ifdef HAVE_CONFIG_H
47 #include "config.h" // Needed for SVNDATE, PACKAGE, VERSION
48 #else
49 #include <common/ClientVersion.h>
50 #endif // HAVE_CONFIG_H
52 #include "amuleDlg.h" // Interface declarations.
54 #include <common/Format.h> // Needed for CFormat
55 #include "amule.h" // Needed for theApp
56 #include "ChatWnd.h" // Needed for CChatWnd
57 #include "ClientListCtrl.h" // Needed for CClientListCtrl
58 #include "DownloadListCtrl.h" // Needed for CDownloadListCtrl
59 #include "DownloadQueue.h" // Needed for CDownloadQueue
60 #include "KadDlg.h" // Needed for CKadDlg
61 #include "Logger.h"
62 #include "MuleTrayIcon.h"
63 #include "muuli_wdr.h" // Needed for ID_BUTTON*
64 #include "Preferences.h" // Needed for CPreferences
65 #include "PrefsUnifiedDlg.h"
66 #include "SearchDlg.h" // Needed for CSearchDlg
67 #include "Server.h" // Needed for CServer
68 #include "ServerConnect.h" // Needed for CServerConnect
69 #include "ServerWnd.h" // Needed for CServerWnd
70 #include "SharedFilesWnd.h" // Needed for CSharedFilesWnd
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 "PartFileConvert.h"
77 #endif
79 #ifndef __WXMSW__
80 #include "aMule.xpm"
81 #endif
83 #include "kademlia/kademlia/Kademlia.h"
85 #ifdef ENABLE_IP2COUNTRY
86 #include "IP2Country.h" // Needed for IP2Country
87 #endif
89 #ifdef ENABLE_IP2COUNTRY // That's no bug. MSVC has ENABLE_IP2COUNTRY always on,
90 // but dummy GeoIP.h turns ENABLE_IP2COUNTRY off again.
91 void CamuleDlg::IP2CountryDownloadFinished(uint32 result)
93 m_IP2Country->DownloadFinished(result);
96 void CamuleDlg::EnableIP2Country()
98 if (thePrefs::IsGeoIPEnabled()) {
99 m_IP2Country->Enable();
103 #else
105 void CamuleDlg::IP2CountryDownloadFinished(uint32){}
106 void CamuleDlg::EnableIP2Country(){}
108 #endif
110 BEGIN_EVENT_TABLE(CamuleDlg, wxFrame)
112 EVT_TOOL(ID_BUTTONNETWORKS, CamuleDlg::OnToolBarButton)
113 EVT_TOOL(ID_BUTTONSEARCH, CamuleDlg::OnToolBarButton)
114 EVT_TOOL(ID_BUTTONTRANSFER, CamuleDlg::OnToolBarButton)
115 EVT_TOOL(ID_BUTTONSHARED, CamuleDlg::OnToolBarButton)
116 EVT_TOOL(ID_BUTTONMESSAGES, CamuleDlg::OnToolBarButton)
117 EVT_TOOL(ID_BUTTONSTATISTICS, CamuleDlg::OnToolBarButton)
118 EVT_TOOL(ID_ABOUT, CamuleDlg::OnAboutButton)
120 EVT_TOOL(ID_BUTTONNEWPREFERENCES, CamuleDlg::OnPrefButton)
121 #ifndef CLIENT_GUI
122 EVT_TOOL(ID_BUTTONIMPORT, CamuleDlg::OnImportButton)
123 #endif
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 __WXMSW__
216 wxSystemOptions::SetOption(wxT("msw.remap"), 0);
217 #endif
219 SetIcon(wxICON(aMule));
221 srand(time(NULL));
223 // Create new sizer and stuff a wxPanel in there.
224 wxFlexGridSizer *s_main = new wxFlexGridSizer(1);
225 s_main->AddGrowableCol(0);
226 s_main->AddGrowableRow(0);
228 wxPanel* p_cnt = new wxPanel(this, -1, wxDefaultPosition, wxDefaultSize);
229 s_main->Add(p_cnt, 0, wxGROW|wxEXPAND, 0);
230 muleDlg(p_cnt, false, true);
231 SetSizer(s_main, true);
233 m_serverwnd = new CServerWnd(p_cnt, m_srv_split_pos);
234 AddLogLineM(false, wxEmptyString);
235 AddLogLineM(false, wxT(" - ") +
236 CFormat(_("This is aMule %s based on eMule.")) % GetMuleVersion());
237 AddLogLineM(false, wxT(" ") +
238 CFormat(_("Running on %s")) % wxGetOsDescription());
239 AddLogLineM(false, wxT(" - ") +
240 wxString(_("Visit http://www.amule.org to check if a new version is available.")));
241 AddLogLineM(false, wxEmptyString);
243 #ifdef ENABLE_IP2COUNTRY
244 m_GeoIPavailable = true;
245 m_IP2Country = new CIP2Country();
246 #else
247 m_GeoIPavailable = false;
248 #endif
249 m_searchwnd = new CSearchDlg(p_cnt);
250 m_transferwnd = new CTransferWnd(p_cnt);
251 m_sharedfileswnd = new CSharedFilesWnd(p_cnt);
252 m_statisticswnd = new CStatisticsDlg(p_cnt, theApp->m_statistics);
253 m_chatwnd = new CChatWnd(p_cnt);
254 m_kademliawnd = CastChild(wxT("kadWnd"), CKadDlg);
256 m_serverwnd->Show(false);
257 m_searchwnd->Show(false);
258 m_transferwnd->Show(false);
259 m_sharedfileswnd->Show(false);
260 m_statisticswnd->Show(false);
261 m_chatwnd->Show(false);
263 // Create the GUI timer
264 gui_timer=new wxTimer(this,ID_GUI_TIMER_EVENT);
265 if (!gui_timer) {
266 AddLogLineM(false, _("FATAL ERROR: Failed to create Timer"));
267 exit(1);
270 // Set transfers as active window
271 Create_Toolbar(thePrefs::VerticalToolbar());
272 SetActiveDialog(DT_TRANSFER_WND, m_transferwnd);
273 m_wndToolbar->ToggleTool(ID_BUTTONTRANSFER, true );
275 bool override_where = (where != wxDefaultPosition);
276 bool override_size = (
277 (dlg_size.x != DEFAULT_SIZE_X) ||
278 (dlg_size.y != DEFAULT_SIZE_Y) );
279 if (!LoadGUIPrefs(override_where, override_size)) {
280 // Prefs not loaded for some reason, exit
281 AddLogLineM( true, wxT("Error! Unable to load Preferences") );
282 return;
285 // Prepare the dialog, sets the splitter-position (AFTER window size is set)
286 m_transferwnd->Prepare();
288 m_is_safe_state = true;
290 // Init statistics stuff, better do it asap
291 m_statisticswnd->Init();
292 m_kademliawnd->Init();
293 m_searchwnd->UpdateCatChoice();
294 if (thePrefs::UseTrayIcon()) {
295 CreateSystray();
298 Show(true);
299 // Must we start minimized?
300 if (thePrefs::GetStartMinimized()) {
301 DoIconize(true);
304 // Set shortcut keys
305 wxAcceleratorEntry entries[] = {
306 wxAcceleratorEntry(wxACCEL_CTRL, wxT('Q'), wxID_EXIT)
309 SetAcceleratorTable(wxAcceleratorTable(itemsof(entries), entries));
310 ShowED2KLinksHandler( thePrefs::GetFED2KLH() );
312 wxNotebook* logs_notebook = CastChild( ID_SRVLOG_NOTEBOOK, wxNotebook);
313 wxNotebook* networks_notebook = CastChild( ID_NETNOTEBOOK, wxNotebook);
315 wxASSERT(logs_notebook->GetPageCount() == 4);
316 wxASSERT(networks_notebook->GetPageCount() == 2);
318 for (uint32 i = 0; i < logs_notebook->GetPageCount(); ++i) {
319 m_logpages[i].page = logs_notebook->GetPage(i);
320 m_logpages[i].name = logs_notebook->GetPageText(i);
323 for (uint32 i = 0; i < networks_notebook->GetPageCount(); ++i) {
324 m_networkpages[i].page = networks_notebook->GetPage(i);
325 m_networkpages[i].name = networks_notebook->GetPageText(i);
328 DoNetworkRearrange();
332 // Madcat - Sets Fast ED2K Links Handler on/off.
333 void CamuleDlg::ShowED2KLinksHandler( bool show )
335 // Errorchecking in case the pointer becomes invalid ...
336 if (s_fed2klh == NULL) {
337 wxLogWarning(wxT("Unable to find Fast ED2K Links handler sizer! Hiding FED2KLH aborted."));
338 return;
341 s_dlgcnt->Show( s_fed2klh, show );
342 s_dlgcnt->Layout();
345 // Toogles ed2k link handler.
346 void CamuleDlg::ToogleED2KLinksHandler()
348 // Errorchecking in case the pointer becomes invalid ...
349 if (s_fed2klh == NULL) {
350 wxLogWarning(wxT("Unable to find Fast ED2K Links handler sizer! Toogling FED2KLH aborted."));
351 return;
353 ShowED2KLinksHandler(!s_dlgcnt->IsShown(s_fed2klh));
356 void CamuleDlg::SetActiveDialog(DialogType type, wxWindow* dlg)
358 m_nActiveDialog = type;
360 if ( type == DT_TRANSFER_WND ) {
361 if (thePrefs::ShowCatTabInfos()) {
362 m_transferwnd->UpdateCatTabTitles();
366 if ( m_activewnd ) {
367 m_activewnd->Show(false);
368 contentSizer->Detach(m_activewnd);
371 contentSizer->Add(dlg, 1, wxALIGN_LEFT|wxEXPAND);
372 dlg->Show(true);
373 m_activewnd=dlg;
374 s_dlgcnt->Layout();
376 // Since we might be suspending redrawing while hiding the dialog
377 // we have to refresh it once it is visible again
378 dlg->Refresh( true );
379 dlg->SetFocus();
383 void CamuleDlg::UpdateTrayIcon(int percent)
385 // set trayicon-icon
386 if(!theApp->IsConnected()) {
387 m_wndTaskbarNotifier->SetTrayIcon(TRAY_ICON_DISCONNECTED, percent);
388 } else {
389 if(theApp->IsConnectedED2K() && theApp->serverconnect->IsLowID()) {
390 m_wndTaskbarNotifier->SetTrayIcon(TRAY_ICON_LOWID, percent);
391 } else {
392 m_wndTaskbarNotifier->SetTrayIcon(TRAY_ICON_HIGHID, percent);
398 void CamuleDlg::CreateSystray()
400 wxCHECK_RET(m_wndTaskbarNotifier == NULL,
401 wxT("Systray already created"));
403 m_wndTaskbarNotifier = new CMuleTrayIcon();
404 // This will effectively show the Tray Icon.
405 UpdateTrayIcon(0);
409 void CamuleDlg::RemoveSystray()
411 delete m_wndTaskbarNotifier;
412 m_wndTaskbarNotifier = NULL;
416 void CamuleDlg::OnToolBarButton(wxCommandEvent& ev)
418 static int lastbutton = ID_BUTTONTRANSFER;
420 // Kry - just if the GUI is ready for it
421 if ( m_is_safe_state ) {
423 // Rehide the handler if needed
424 if ( lastbutton == ID_BUTTONSEARCH && !thePrefs::GetFED2KLH() ) {
425 if (ev.GetId() != ID_BUTTONSEARCH) {
426 ShowED2KLinksHandler( false );
427 } else {
428 // Toogle ED2K handler.
429 ToogleED2KLinksHandler();
433 if ( lastbutton != ev.GetId() ) {
434 switch ( ev.GetId() ) {
435 case ID_BUTTONNETWORKS:
436 SetActiveDialog(DT_NETWORKS_WND, m_serverwnd);
437 // Set serverlist splitter position
438 CastChild( wxT("SrvSplitterWnd"), wxSplitterWindow )->SetSashPosition(m_srv_split_pos, true);
439 break;
441 case ID_BUTTONSEARCH:
442 // The search dialog should always display the handler
443 if ( !thePrefs::GetFED2KLH() )
444 ShowED2KLinksHandler( true );
446 SetActiveDialog(DT_SEARCH_WND, m_searchwnd);
447 break;
449 case ID_BUTTONTRANSFER:
450 SetActiveDialog(DT_TRANSFER_WND, m_transferwnd);
451 // Prepare the dialog, sets the splitter-position
452 m_transferwnd->Prepare();
453 break;
455 case ID_BUTTONSHARED:
456 SetActiveDialog(DT_SHARED_WND, m_sharedfileswnd);
457 break;
459 case ID_BUTTONMESSAGES:
460 m_BlinkMessages = false;
461 SetActiveDialog(DT_CHAT_WND, m_chatwnd);
462 break;
464 case ID_BUTTONSTATISTICS:
465 SetActiveDialog(DT_STATS_WND, m_statisticswnd);
466 break;
468 // This shouldn't happen, but just in case
469 default:
470 AddLogLineM( true, wxT("Unknown button triggered CamuleApp::OnToolBarButton().") );
471 break;
475 m_wndToolbar->ToggleTool(lastbutton, lastbutton == ev.GetId() );
476 lastbutton = ev.GetId();
481 void CamuleDlg::OnAboutButton(wxCommandEvent& WXUNUSED(ev))
483 wxString msg = wxT(" ");
484 #ifdef CLIENT_GUI
485 msg << _("aMule remote control ") << wxT(VERSION);
486 #else
487 msg << wxT("aMule ") << wxT(VERSION);
488 #endif
489 msg << wxT(" ");
490 #ifdef SVNDATE
491 msg << _("Snapshot:") << wxT("\n ") << wxT(SVNDATE);
492 #endif
493 msg << wxT("\n\n") << _("'All-Platform' p2p client based on eMule \n\n") <<
494 _("Website: http://www.amule.org \n") <<
495 _("Forum: http://forum.amule.org \n") <<
496 _("FAQ: http://wiki.amule.org \n\n") <<
497 _("Contact: admin@amule.org (administrative issues) \n") <<
498 _("Copyright (c) 2003-2008 aMule Team \n\n") <<
499 _("Part of aMule is based on \n") <<
500 _("Kademlia: Peer-to-peer routing based on the XOR metric.\n") <<
501 _(" Copyright (c) 2002-2008 Petar Maymounkov ( petar@post.harvard.edu )\n") <<
502 _("http://kademlia.scs.cs.nyu.edu\n");
504 if (m_is_safe_state) {
505 wxMessageBox(msg, _("Message"), wxOK | wxICON_INFORMATION, this);
510 void CamuleDlg::OnPrefButton(wxCommandEvent& WXUNUSED(ev))
512 if (m_is_safe_state) {
513 wxBusyCursor busyCursor;
514 if (m_prefsDialog == NULL) {
515 m_prefsDialog = new PrefsUnifiedDlg(this);
518 m_prefsDialog->TransferToWindow();
519 m_prefsDialog->Show(true);
520 m_prefsDialog->Raise();
525 #ifndef CLIENT_GUI
526 void CamuleDlg::OnImportButton(wxCommandEvent& WXUNUSED(ev))
528 if ( m_is_safe_state ) {
529 CPartFileConvert::ShowGUI(NULL);
532 #endif
534 CamuleDlg::~CamuleDlg()
536 AddLogLineN(_("Shutting down aMule..."));
538 SaveGUIPrefs();
540 theApp->amuledlg = NULL;
542 #ifdef ENABLE_IP2COUNTRY
543 delete m_IP2Country;
544 #endif
546 AddLogLineN(_("aMule dialog destroyed"));
550 void CamuleDlg::OnBnConnect(wxCommandEvent& WXUNUSED(evt))
553 bool disconnect = (theApp->IsConnectedED2K() || theApp->serverconnect->IsConnecting())
554 #ifndef CLIENT_GUI
555 || (Kademlia::CKademlia::IsRunning())
556 #endif
558 if (thePrefs::GetNetworkED2K()) {
559 if (disconnect) {
560 //disconnect if currently connected
561 if (theApp->serverconnect->IsConnecting()) {
562 theApp->serverconnect->StopConnectionTry();
563 } else {
564 theApp->serverconnect->Disconnect();
566 } else {
567 //connect if not currently connected
568 AddLogLineM(true, _("Connecting"));
569 theApp->serverconnect->ConnectToAnyServer();
571 } else {
572 wxASSERT(!theApp->IsConnectedED2K());
575 // Connect Kad also
576 if (thePrefs::GetNetworkKademlia()) {
577 if( disconnect ) {
578 theApp->StopKad();
579 } else {
580 theApp->StartKad();
582 } else {
583 #ifndef CLIENT_GUI
584 wxASSERT(!Kademlia::CKademlia::IsRunning());
585 #endif
588 ShowConnectionState();
592 void CamuleDlg::ResetLog(int id)
594 wxTextCtrl* ct = CastByID(id, m_serverwnd, wxTextCtrl);
595 wxCHECK_RET(ct, wxT("Resetting unknown log"));
597 ct->Clear();
599 if (id == ID_LOGVIEW) {
600 // Also clear the log line
601 wxStaticText* text = CastChild(wxT("infoLabel"), wxStaticText);
602 text->SetLabel(wxEmptyString);
603 text->GetParent()->Layout();
608 void CamuleDlg::AddLogLine(const wxString& line)
610 bool addtostatusbar = line[0] == '!';
611 wxString bufferline = line.Mid(1);
613 // Add the message to the log-view
614 wxTextCtrl* ct = CastByID( ID_LOGVIEW, m_serverwnd, wxTextCtrl );
615 if ( ct ) {
616 // Bold critical log-lines
617 // to enable this on Windows control has to be changed to wxTE_RICH2 in muuli
618 #ifdef __WXMSW__
619 ct->AppendText(line); // keep the leading "!" if it can't be bolded
620 #else
621 wxTextAttr style = ct->GetDefaultStyle();
622 wxFont font = style.GetFont();
623 font.SetWeight(addtostatusbar ? wxFONTWEIGHT_BOLD : wxFONTWEIGHT_NORMAL);
624 style.SetFont(font);
625 ct->SetDefaultStyle(style);
626 ct->AppendText(bufferline);
627 #endif
628 ct->ShowPosition( ct->GetLastPosition() - 1 );
632 // Set the status-bar if the event warrents it
633 if ( addtostatusbar ) {
634 // Escape "&"s, which would otherwise not show up
635 bufferline.Replace( wxT("&"), wxT("&&") );
636 wxStaticText* text = CastChild( wxT("infoLabel"), wxStaticText );
637 // Only show the first line if multiple lines
638 text->SetLabel( bufferline.BeforeFirst( wxT('\n') ) );
639 text->SetToolTip( bufferline );
640 text->GetParent()->Layout();
646 void CamuleDlg::AddServerMessageLine(wxString& message)
648 wxTextCtrl* cv= CastByID( ID_SERVERINFO, m_serverwnd, wxTextCtrl );
649 if(cv) {
650 if (message.Length() > 500) {
651 cv->AppendText(message.Left(500) + wxT("\n"));
652 } else {
653 cv->AppendText(message + wxT("\n"));
655 cv->ShowPosition(cv->GetLastPosition()-1);
660 void CamuleDlg::ShowConnectionState(bool skinChanged)
662 static wxImageList status_arrows(16,16,true,0);
663 if (!status_arrows.GetImageCount()) {
664 // Generate the image list (This is only done once)
665 for (int t = 0; t < 7; ++t) {
666 status_arrows.Add(connImages(t));
670 m_serverwnd->UpdateED2KInfo();
671 m_serverwnd->UpdateKadInfo();
674 ////////////////////////////////////////////////////////////
675 // Determine the status of the networks
677 enum ED2KState { ED2KOff = 0, ED2KLowID = 1, ED2KConnecting = 2, ED2KHighID = 3, ED2KUndef = -1 };
678 enum EKadState { EKadOff = 4, EKadFW = 5, EKadConnecting = 5, EKadOK = 6, EKadUndef = -1 };
680 ED2KState ed2kState = ED2KOff;
681 EKadState kadState = EKadOff;
683 ////////////////////////////////////////////////////////////
684 // Update the label on the status-bar and determine
685 // the states of the two networks.
687 wxString msgED2K;
688 if (theApp->IsConnectedED2K()) {
689 CServer* server = theApp->serverconnect->GetCurrentServer();
690 if (server) {
691 msgED2K = CFormat(wxT("eD2k: %s")) % server->GetListName();
694 if (theApp->serverconnect->IsLowID()) {
695 ed2kState = ED2KLowID;
696 } else {
697 ed2kState = ED2KHighID;
699 } else if (theApp->serverconnect->IsConnecting()) {
700 msgED2K = _("eD2k: Connecting");
702 ed2kState = ED2KConnecting;
703 } else if (thePrefs::GetNetworkED2K()) {
704 msgED2K = _("eD2k: Disconnected");
707 wxString msgKad;
708 if (theApp->IsConnectedKad()) {
709 if (theApp->IsFirewalledKad()) {
710 msgKad = _("Kad: Firewalled");
712 kadState = EKadFW;
713 } else {
714 msgKad = _("Kad: Connected");
716 kadState = EKadOK;
718 } else if (theApp->IsKadRunning()) {
719 msgKad = _("Kad: Connecting");
721 kadState = EKadConnecting;
722 } else if (thePrefs::GetNetworkKademlia()) {
723 msgKad = _("Kad: Off");
726 wxStaticText* connLabel = CastChild( wxT("connLabel"), wxStaticText );
727 wxCHECK_RET(connLabel, wxT("'connLabel' widget not found"));
729 wxString labelMsg;
730 if (msgED2K.Length() && msgKad.Length()) {
731 labelMsg = msgED2K + wxT(" | ") + msgKad;
732 } else {
733 labelMsg = msgED2K + msgKad;
736 connLabel->SetLabel(labelMsg);
737 connLabel->GetParent()->Layout();
740 ////////////////////////////////////////////////////////////
741 // Update the connect/disconnect/cancel button.
743 enum EConnState {
744 ECS_Unknown,
745 ECS_Connected,
746 ECS_Connecting,
747 ECS_Disconnected
750 static EConnState s_oldState = ECS_Unknown;
751 EConnState currentState = ECS_Disconnected;
753 if (theApp->serverconnect->IsConnecting() ||
754 (theApp->IsKadRunning() && !theApp->IsConnectedKad())) {
755 currentState = ECS_Connecting;
756 } else if (theApp->IsConnected()) {
757 currentState = ECS_Connected;
758 } else {
759 currentState = ECS_Disconnected;
762 if ( (true == skinChanged) || (currentState != s_oldState) ) {
763 wxWindowUpdateLocker freezer(m_wndToolbar);
765 wxToolBarToolBase* toolbarTool = m_wndToolbar->RemoveTool(ID_BUTTONCONNECT);
767 switch (currentState) {
768 case ECS_Connecting:
769 toolbarTool->SetLabel(_("Cancel"));
770 toolbarTool->SetShortHelp(_("Stop the current connection attempts"));
771 toolbarTool->SetNormalBitmap(m_tblist.GetBitmap(2));
772 break;
774 case ECS_Connected:
775 toolbarTool->SetLabel(_("Disconnect"));
776 toolbarTool->SetShortHelp(_("Disconnect from the currently connected networks"));
777 toolbarTool->SetNormalBitmap(m_tblist.GetBitmap(1));
778 break;
780 default:
781 toolbarTool->SetLabel(_("Connect"));
782 toolbarTool->SetShortHelp(_("Connect to the currently enabled networks"));
783 toolbarTool->SetNormalBitmap(m_tblist.GetBitmap(0));
786 m_wndToolbar->InsertTool(0, toolbarTool);
787 m_wndToolbar->Realize();
789 s_oldState = currentState;
793 ////////////////////////////////////////////////////////////
794 // Update the globe-icon in the lower-right corner.
795 // (only if connection state has changed)
797 static ED2KState s_ED2KOldState = ED2KUndef;
798 static EKadState s_EKadOldState = EKadUndef;
799 if (ed2kState != s_ED2KOldState || kadState != s_EKadOldState) {
800 s_ED2KOldState = ed2kState;
801 s_EKadOldState = kadState;
802 wxStaticBitmap* connBitmap = CastChild( wxT("connImage"), wxStaticBitmap );
803 wxCHECK_RET(connBitmap, wxT("'connImage' widget not found"));
805 wxBitmap statusIcon = connBitmap->GetBitmap();
806 // Sanity check - otherwise there's a crash here if aMule runs out of resources
807 if (statusIcon.GetRefData() == NULL) {
808 return;
811 wxMemoryDC bitmapDC(statusIcon);
813 status_arrows.Draw(kadState, bitmapDC, 0, 0, wxIMAGELIST_DRAW_TRANSPARENT);
814 status_arrows.Draw(ed2kState, bitmapDC, 0, 0, wxIMAGELIST_DRAW_TRANSPARENT);
816 connBitmap->SetBitmap(statusIcon);
821 void CamuleDlg::ShowUserCount(const wxString& info)
823 wxStaticText* label = CastChild( wxT("userLabel"), wxStaticText );
825 // Update Kad tab
826 m_serverwnd->UpdateKadInfo();
828 label->SetLabel(info);
829 label->GetParent()->Layout();
833 void CamuleDlg::ShowTransferRate()
835 float kBpsUp = theStats::GetUploadRate() / 1024.0;
836 float kBpsDown = theStats::GetDownloadRate() / 1024.0;
837 wxString buffer;
838 if( thePrefs::ShowOverhead() )
840 buffer = wxString::Format(_("Up: %.1f(%.1f) | Down: %.1f(%.1f)"), kBpsUp, theStats::GetUpOverheadRate() / 1024.0, kBpsDown, theStats::GetDownOverheadRate() / 1024.0);
841 } else {
842 buffer = wxString::Format(_("Up: %.1f | Down: %.1f"), kBpsUp, kBpsDown);
844 buffer.Truncate(50); // Max size 50
846 wxStaticText* label = CastChild( wxT("speedLabel"), wxStaticText );
847 label->SetLabel(buffer);
848 label->GetParent()->Layout();
850 // Show upload/download speed in title
851 if (thePrefs::GetShowRatesOnTitle()) {
852 wxString UpDownSpeed = wxString::Format(wxT("Up: %.1f | Down: %.1f"), kBpsUp, kBpsDown);
853 if (thePrefs::GetShowRatesOnTitle() == 1) {
854 SetTitle(theApp->m_FrameTitle + wxT(" -- ") + UpDownSpeed);
855 } else {
856 SetTitle(UpDownSpeed + wxT(" -- ") + theApp->m_FrameTitle);
860 wxASSERT((m_wndTaskbarNotifier != NULL) == thePrefs::UseTrayIcon());
861 if (m_wndTaskbarNotifier) {
862 // set trayicon-icon
863 int percentDown = (int)ceil((kBpsDown*100) / thePrefs::GetMaxGraphDownloadRate());
864 UpdateTrayIcon( ( percentDown > 100 ) ? 100 : percentDown);
866 wxString buffer2;
867 if ( theApp->IsConnected() ) {
868 buffer2 = CFormat(_("aMule (%s | Connected)")) % buffer;
869 } else {
870 buffer2 = CFormat(_("aMule (%s | Disconnected)")) % buffer;
872 m_wndTaskbarNotifier->SetTrayToolTip(buffer2);
875 wxStaticBitmap* bmp = CastChild( wxT("transferImg"), wxStaticBitmap );
876 bmp->SetBitmap(dlStatusImages((kBpsUp>0.01 ? 2 : 0) + (kBpsDown>0.01 ? 1 : 0)));
879 void CamuleDlg::DlgShutDown()
881 // Are we already shutting down or still on init?
882 if ( m_is_safe_state == false ) {
883 return;
886 // we are going DOWN
887 m_is_safe_state = false;
889 // Stop the GUI Timer
890 delete gui_timer;
891 m_transferwnd->downloadlistctrl->DeleteAllItems();
893 // We want to delete the systray too!
894 RemoveSystray();
897 void CamuleDlg::OnClose(wxCloseEvent& evt)
899 // This will be here till the core close is != app close
900 if (evt.CanVeto() && thePrefs::IsConfirmExitEnabled() ) {
901 if (wxNO == wxMessageBox(wxString(_("Do you really want to exit aMule?")),
902 wxString(_("Exit confirmation")), wxYES_NO, this)) {
903 evt.Veto();
904 return;
908 Enable(false);
909 Show(false);
911 theApp->ShutDown(evt);
915 void CamuleDlg::OnBnClickedFast(wxCommandEvent& WXUNUSED(evt))
917 wxTextCtrl* ctl = CastChild( wxT("FastEd2kLinks"), wxTextCtrl );
919 for ( int i = 0; i < ctl->GetNumberOfLines(); i++ ) {
920 wxString strlink = ctl->GetLineText(i);
921 strlink.Trim(true);
922 strlink.Trim(false);
923 if ( !strlink.IsEmpty() ) {
924 theApp->downloadqueue->AddLink( strlink, m_transferwnd->downloadlistctrl->GetCategory() );
928 ctl->SetValue(wxEmptyString);
932 // Formerly known as LoadRazorPrefs()
933 bool CamuleDlg::LoadGUIPrefs(bool override_pos, bool override_size)
935 // Create a config base for loading razor preferences
936 wxConfigBase *config = wxConfigBase::Get();
937 // If config haven't been created exit without loading
938 if (config == NULL) {
939 return false;
942 // The section where to save in in file
943 wxString section = wxT("/Razor_Preferences/");
945 // Get window size and position
946 int x1 = config->Read(section + wxT("MAIN_X_POS"), -1);
947 int y1 = config->Read(section + wxT("MAIN_Y_POS"), -1);
948 int x2 = config->Read(section + wxT("MAIN_X_SIZE"), -1);
949 int y2 = config->Read(section + wxT("MAIN_Y_SIZE"), -1);
951 int maximized = config->Read(section + wxT("Maximized"), 01);
953 // Kry - Random usable pos for m_srv_split_pos
954 m_srv_split_pos = config->Read(section + wxT("SRV_SPLITTER_POS"), 463l);
955 if (!override_size) {
956 if (x2 > 0 && y2 > 0) {
957 SetSize(x2, y2);
958 } else {
959 #ifndef __WXGTK__
960 // Probably first run.
961 Maximize();
962 #endif
966 if (!override_pos) {
967 // If x1 and y1 != -1 Redefine location
968 if(x1 != -1 && y1 != -1) {
969 wxRect display = wxGetClientDisplayRect();
970 if (x1 <= display.GetRightTop().x && y1 <= display.GetRightBottom().y) {
971 Move(x1, y1);
972 } else {
973 // It's offscreen... so let's not.
978 if (!override_size && !override_pos && maximized) {
979 Maximize();
982 return true;
986 bool CamuleDlg::SaveGUIPrefs()
988 /* Razor 1a - Modif by MikaelB
989 Save client size and position */
991 // Create a config base for saving razor preferences
992 wxConfigBase *config = wxConfigBase::Get();
993 // If config haven't been created exit without saving
994 if (config == NULL) {
995 return false;
997 // The section where to save in in file
998 wxString section = wxT("/Razor_Preferences/");
1000 if (!IsIconized()) {
1001 // Main window location and size
1002 int x1, y1, x2, y2;
1003 GetPosition(&x1, &y1);
1004 GetSize(&x2, &y2);
1006 // Saving window size and position
1007 config->Write(section+wxT("MAIN_X_POS"), (long) x1);
1008 config->Write(section+wxT("MAIN_Y_POS"), (long) y1);
1010 config->Write(section+wxT("MAIN_X_SIZE"), (long) x2);
1011 config->Write(section+wxT("MAIN_Y_SIZE"), (long) y2);
1013 config->Write(section+wxT("Maximized"), (long) (IsMaximized() ? 1 : 0));
1016 // Saving sash position of splitter in server window
1017 config->Write(section+wxT("SRV_SPLITTER_POS"), (long) m_srv_split_pos);
1019 config->Flush(true);
1021 /* End modif */
1023 return true;
1027 void CamuleDlg::DoIconize(bool iconize)
1029 if (m_wndTaskbarNotifier && thePrefs::DoMinToTray()) {
1030 if (iconize) {
1031 // Skip() will do it.
1032 //Iconize(true);
1033 if (SafeState()) {
1034 Show(false);
1036 } else {
1037 Show(true);
1038 Raise();
1040 } else {
1041 // Will be done by Skip();
1042 //Iconize(iconize);
1046 void CamuleDlg::OnMinimize(wxIconizeEvent& evt)
1048 // Evil Hack: check if the mouse is inside the window
1049 #ifndef __WXMSW__
1050 if (GetScreenRect().Contains(wxGetMousePosition()))
1051 #endif
1053 if (m_prefsDialog && m_prefsDialog->IsShown()) {
1054 // Veto.
1055 } else {
1056 if (m_wndTaskbarNotifier) {
1057 #if wxCHECK_VERSION(2, 9, 0)
1058 DoIconize(evt.IsIconized());
1059 #else
1060 DoIconize(evt.Iconized());
1061 #endif
1063 evt.Skip();
1068 void CamuleDlg::OnGUITimer(wxTimerEvent& WXUNUSED(evt))
1070 // Former TimerProc section
1072 static uint32 msPrev1, msPrev5, msPrevStats;
1074 uint32 msCur = theStats::GetUptimeMillis();
1076 // can this actually happen under wxwin ?
1077 if (!SafeState()) {
1078 return;
1081 #ifndef CLIENT_GUI
1082 static uint32 msPrevGraph;
1083 int msGraphUpdate = thePrefs::GetTrafficOMeterInterval() * 1000;
1084 if ((msGraphUpdate > 0) && ((msCur / msGraphUpdate) > (msPrevGraph / msGraphUpdate))) {
1085 // trying to get the graph shifts evenly spaced after a change in the update period
1086 msPrevGraph = msCur;
1088 GraphUpdateInfo update = theApp->m_statistics->GetPointsForUpdate();
1090 m_statisticswnd->UpdateStatGraphs(theStats::GetPeakConnections(), update);
1091 m_kademliawnd->UpdateGraph(update);
1093 #else
1094 //#warning TODO: CORE/GUI -- EC needed
1095 #endif
1097 int sStatsUpdate = thePrefs::GetStatsInterval();
1098 if ((sStatsUpdate > 0) && ((int)(msCur - msPrevStats) > sStatsUpdate*1000)) {
1099 if (m_statisticswnd->IsShownOnScreen()) {
1100 msPrevStats = msCur;
1101 m_statisticswnd->ShowStatistics();
1105 if (msCur-msPrev5 > 5000) { // every 5 seconds
1106 msPrev5 = msCur;
1107 ShowTransferRate();
1108 if (thePrefs::ShowCatTabInfos() && theApp->amuledlg->m_activewnd == theApp->amuledlg->m_transferwnd) {
1109 m_transferwnd->UpdateCatTabTitles();
1111 if (thePrefs::AutoSortDownload()) {
1112 m_transferwnd->downloadlistctrl->SortList();
1116 if (msCur-msPrev1 > 1000) { // every second
1117 msPrev1 = msCur;
1118 if (m_CurrentBlinkBitmap == 12) {
1119 m_CurrentBlinkBitmap = 7;
1120 SetMessagesTool();
1121 } else {
1122 if (m_BlinkMessages) {
1123 m_CurrentBlinkBitmap = 12;
1124 SetMessagesTool();
1132 void CamuleDlg::SetMessagesTool()
1134 int pos = m_wndToolbar->GetToolPos(ID_BUTTONMESSAGES);
1135 wxASSERT(pos == 6); // so we don't miss a change on wx2.4
1137 wxWindowUpdateLocker freezer(m_wndToolbar);
1138 #ifdef __WXCOCOA__
1139 m_wndToolbar->FindById(ID_BUTTONMESSAGES)->SetNormalBitmap(m_tblist.GetBitmap(m_CurrentBlinkBitmap));
1140 #else
1141 m_wndToolbar->SetToolNormalBitmap(ID_BUTTONMESSAGES, m_tblist.GetBitmap(m_CurrentBlinkBitmap));
1142 #endif
1145 void CamuleDlg::LaunchUrl( const wxString& url )
1147 wxString cmd;
1149 cmd = thePrefs::GetBrowser();
1150 wxString tmp = url;
1151 // Pipes cause problems, so escape them
1152 tmp.Replace( wxT("|"), wxT("%7C") );
1154 if ( !cmd.IsEmpty() ) {
1155 if (!cmd.Replace(wxT("%s"), tmp)) {
1156 // No %s found, just append the url
1157 cmd += wxT(" ") + tmp;
1160 CTerminationProcess *p = new CTerminationProcess(cmd);
1161 if (wxExecute(cmd, wxEXEC_ASYNC, p)) {
1162 AddLogLineN(_("Launch Command: ") + cmd);
1163 return;
1164 } else {
1165 delete p;
1167 } else {
1168 wxLaunchDefaultBrowser(tmp);
1169 return;
1171 // Unable to execute browser. But this error message doesn't make sense,
1172 // cosidering that you _can't_ set the browser executable path... =/
1173 wxLogError(wxT("Unable to launch browser. Please set correct browser executable path in Preferences."));
1177 wxString CamuleDlg::GenWebSearchUrl(const wxString &filename, WebSearch wsProvider )
1179 wxString URL;
1180 switch (wsProvider) {
1181 case WS_FILEHASH:
1182 URL = wxT("http://www.filehash.com/search.html?pattern=FILENAME&submit=Find");
1183 break;
1184 default:
1185 wxFAIL;
1187 URL.Replace(wxT("FILENAME"), filename);
1189 return URL;
1193 bool CamuleDlg::Check_and_Init_Skin()
1195 bool ret = true;
1196 wxString skinFileName(thePrefs::GetSkin());
1198 if (skinFileName.IsEmpty()) {
1199 return false;
1202 wxString userDir(JoinPaths(GetConfigDir(), wxT("skins")) + wxFileName::GetPathSeparator());
1204 wxStandardPathsBase &spb(wxStandardPaths::Get());
1205 #ifdef __WXMSW__
1206 wxString dataDir(spb.GetPluginsDir());
1207 #elif defined(__WXMAC__)
1208 wxString dataDir(spb.GetDataDir());
1209 #else
1210 wxString dataDir(spb.GetDataDir().BeforeLast(wxT('/')) + wxT("/amule"));
1211 #endif
1212 wxString systemDir(JoinPaths(dataDir,wxT("skins")) + wxFileName::GetPathSeparator());
1215 skinFileName.Replace(wxT("User:"), userDir );
1216 skinFileName.Replace(wxT("System:"), systemDir );
1218 m_skinFileName.Assign(skinFileName);
1219 if (!m_skinFileName.FileExists()) {
1220 AddLogLineM(true, CFormat(
1221 _("Skin directory '%s' does not exist")) %
1222 skinFileName );
1223 ret = false;
1224 } else if (!m_skinFileName.IsFileReadable()) {
1225 AddLogLineM(true, CFormat(
1226 _("WARNING: Unable to open skin file '%s' for read")) %
1227 skinFileName);
1228 ret = false;
1231 wxFFileInputStream in(m_skinFileName.GetFullPath());
1232 wxZipInputStream zip(in);
1234 while ((entry = zip.GetNextEntry()) != NULL) {
1235 wxZipEntry*& current = cat[entry->GetInternalName()];
1236 delete current;
1237 current = entry;
1240 return ret;
1244 void CamuleDlg::Add_Skin_Icon(
1245 const wxString &iconName,
1246 const wxBitmap &stdIcon,
1247 bool useSkins)
1249 wxImage new_image;
1250 if (useSkins) {
1251 wxFFileInputStream in(m_skinFileName.GetFullPath());
1252 wxZipInputStream zip(in);
1254 it = cat.find(wxZipEntry::GetInternalName(iconName + wxT(".png")));
1255 if ( it != cat.end() ) {
1256 zip.OpenEntry(*it->second);
1257 if ( !new_image.LoadFile(zip,wxBITMAP_TYPE_PNG) ) {
1258 AddLogLineM(false,
1259 wxT("Warning: Error loading icon for ") +
1260 iconName);
1261 useSkins = false;
1263 }else {
1264 AddLogLineM(false,
1265 wxT("Warning: Can't load icon for ") +
1266 iconName);
1267 useSkins = false;
1272 wxBitmap bmp(useSkins ? new_image : stdIcon);
1273 if (iconName.StartsWith(wxT("Client_"))) {
1274 m_imagelist.Add(bmp);
1275 } else if (iconName.StartsWith(wxT("Toolbar_"))) {
1276 m_tblist.Add(bmp);
1281 void CamuleDlg::Apply_Clients_Skin()
1283 bool useSkins = Check_and_Init_Skin();
1285 // Clear the client image list
1286 m_imagelist.RemoveAll();
1288 // Add the images to the image list
1289 for (int i = 0; i < CLIENT_SKIN_SIZE; ++i) {
1290 Add_Skin_Icon(wxT("Client_") + m_clientSkinNames[i],
1291 clientImages(i), useSkins);
1296 void CamuleDlg::Apply_Toolbar_Skin(wxToolBar *wndToolbar)
1298 bool useSkins = Check_and_Init_Skin();
1301 // Clear the toolbar image list
1302 m_tblist.RemoveAll();
1304 // Add the images to the image list
1305 Add_Skin_Icon(wxT("Toolbar_Connect"), connButImg(0), useSkins);
1306 Add_Skin_Icon(wxT("Toolbar_Disconnect"), connButImg(1), useSkins);
1307 Add_Skin_Icon(wxT("Toolbar_Connecting"), connButImg(2), useSkins);
1308 Add_Skin_Icon(wxT("Toolbar_Network"), amuleDlgImages(20), useSkins);
1309 Add_Skin_Icon(wxT("Toolbar_Transfers"), amuleDlgImages(21), useSkins);
1310 Add_Skin_Icon(wxT("Toolbar_Search"), amuleDlgImages(22), useSkins);
1311 Add_Skin_Icon(wxT("Toolbar_Shared"), amuleDlgImages(23), useSkins);
1312 Add_Skin_Icon(wxT("Toolbar_Messages"), amuleDlgImages(24), useSkins);
1313 Add_Skin_Icon(wxT("Toolbar_Stats"), amuleDlgImages(25), useSkins);
1314 Add_Skin_Icon(wxT("Toolbar_Prefs"), amuleDlgImages(26), useSkins);
1315 Add_Skin_Icon(wxT("Toolbar_Import"), amuleDlgImages(32), useSkins);
1316 Add_Skin_Icon(wxT("Toolbar_About"), amuleDlgImages(29), useSkins);
1317 Add_Skin_Icon(wxT("Toolbar_Blink"), amuleDlgImages(33), useSkins);
1319 // Build aMule toolbar
1320 wndToolbar->SetMargins(0, 0);
1322 // Placeholder. Gets updated by ShowConnectionState
1323 wndToolbar->AddTool(ID_BUTTONCONNECT, wxT("..."), m_tblist.GetBitmap(0));
1325 wndToolbar->AddSeparator();
1326 wndToolbar->AddTool(ID_BUTTONNETWORKS,
1327 _("Networks"), m_tblist.GetBitmap(3),
1328 wxNullBitmap, wxITEM_CHECK,
1329 _("Networks window"));
1330 wndToolbar->AddTool(ID_BUTTONSEARCH,
1331 _("Searches"), m_tblist.GetBitmap(5),
1332 wxNullBitmap, wxITEM_CHECK,
1333 _("Searches window"));
1334 wndToolbar->AddTool(ID_BUTTONTRANSFER,
1335 _("Transfers"), m_tblist.GetBitmap(4),
1336 wxNullBitmap, wxITEM_CHECK,
1337 _("Files transfers window"));
1338 wndToolbar->AddTool(ID_BUTTONSHARED,
1339 _("Shared files"), m_tblist.GetBitmap(6),
1340 wxNullBitmap, wxITEM_CHECK,
1341 _("Shared files window"));
1342 wndToolbar->AddTool(ID_BUTTONMESSAGES,
1343 _("Messages"), m_tblist.GetBitmap(7),
1344 wxNullBitmap, wxITEM_CHECK,
1345 _("Messages window"));
1346 wndToolbar->AddTool(ID_BUTTONSTATISTICS,
1347 _("Statistics"), m_tblist.GetBitmap(8),
1348 wxNullBitmap, wxITEM_CHECK,
1349 _("Statistics graph window"));
1350 wndToolbar->AddSeparator();
1351 wndToolbar->AddTool(ID_BUTTONNEWPREFERENCES,
1352 _("Preferences"), m_tblist.GetBitmap(9),
1353 wxNullBitmap, wxITEM_NORMAL,
1354 _("Preferences settings window"));
1355 wndToolbar->AddTool(ID_BUTTONIMPORT,
1356 _("Import"), m_tblist.GetBitmap(10),
1357 wxNullBitmap, wxITEM_NORMAL,
1358 _("The partfile importer tool"));
1359 wndToolbar->AddTool(ID_ABOUT,
1360 _("About"), m_tblist.GetBitmap(11),
1361 wxNullBitmap, wxITEM_NORMAL,
1362 _("About/Help"));
1364 wndToolbar->ToggleTool(ID_BUTTONTRANSFER, true);
1366 // Needed for non-GTK platforms, where the
1367 // items don't get added immediatly.
1368 wndToolbar->Realize();
1370 // Updates the "Connect" button, and so on.
1371 ShowConnectionState(true);
1375 void CamuleDlg::Create_Toolbar(bool orientation)
1377 Freeze();
1378 // Create ToolBar from the one designed by wxDesigner (BigBob)
1379 wxToolBar *current = GetToolBar();
1381 wxASSERT(current == m_wndToolbar);
1383 if (current) {
1384 bool oldorientation = ((current->GetWindowStyle() & wxTB_VERTICAL) == wxTB_VERTICAL);
1385 if (oldorientation != orientation) {
1386 current->Destroy();
1387 SetToolBar(NULL); // Remove old one if present
1388 m_wndToolbar = NULL;
1389 } else {
1390 current->ClearTools();
1394 if (!m_wndToolbar) {
1395 m_wndToolbar = CreateToolBar(
1396 (orientation ? wxTB_VERTICAL : wxTB_HORIZONTAL) |
1397 wxNO_BORDER | wxTB_TEXT | wxTB_3DBUTTONS |
1398 wxTB_FLAT | wxCLIP_CHILDREN | wxTB_NODIVIDER);
1401 m_wndToolbar->SetToolBitmapSize(wxSize(32, 32));
1404 Apply_Toolbar_Skin(m_wndToolbar);
1405 #ifdef CLIENT_GUI
1406 m_wndToolbar->DeleteTool(ID_BUTTONIMPORT);
1407 #endif
1409 Thaw();
1413 void CamuleDlg::OnMainGUISizeChange(wxSizeEvent& evt)
1415 wxFrame::OnSize(evt);
1416 if (m_transferwnd && m_transferwnd->clientlistctrl) {
1417 // Transfer window's splitter set again if it's hidden.
1418 if (m_transferwnd->clientlistctrl->GetListView() == vtNone) {
1419 int height = m_transferwnd->clientlistctrl->GetSize().GetHeight();
1420 wxSplitterWindow* splitter =
1421 CastChild(wxT("splitterWnd"), wxSplitterWindow);
1422 height += splitter->GetWindow1()->GetSize().GetHeight();
1423 splitter->SetSashPosition( height );
1430 void CamuleDlg::OnKeyPressed(wxKeyEvent& event)
1432 if (event.GetKeyCode() == WXK_F1) {
1433 // Ctrl/Alt/Shift must not be pressed, to avoid
1434 // conflicts with other (global) shortcuts.
1435 if (!event.HasModifiers() && !event.ShiftDown()) {
1436 LaunchUrl(wxT("http://wiki.amule.org"));
1437 return;
1441 event.Skip();
1445 void CamuleDlg::OnExit(wxCommandEvent& WXUNUSED(evt))
1447 Close();
1450 void CamuleDlg::DoNetworkRearrange()
1453 wxWindowUpdateLocker freezer(this);
1455 wxToolBarToolBase* toolbarTool = m_wndToolbar->RemoveTool(ID_BUTTONNETWORKS);
1457 wxNotebook* logs_notebook = CastChild( ID_SRVLOG_NOTEBOOK, wxNotebook);
1458 wxNotebook* networks_notebook = CastChild( ID_NETNOTEBOOK, wxNotebook);
1460 while (logs_notebook->GetPageCount() > 1) {
1461 logs_notebook->RemovePage(logs_notebook->GetPageCount() - 1);
1464 while (networks_notebook->GetPageCount() > 0) {
1465 networks_notebook->RemovePage(networks_notebook->GetPageCount() - 1);
1468 if (thePrefs::GetNetworkED2K()) {
1469 logs_notebook->AddPage(m_logpages[1].page, m_logpages[1].name);
1470 logs_notebook->AddPage(m_logpages[2].page, m_logpages[2].name);
1473 m_networkpages[0].page->Show(thePrefs::GetNetworkED2K());
1475 if (thePrefs::GetNetworkKademlia()) {
1476 logs_notebook->AddPage(m_logpages[3].page, m_logpages[3].name);
1479 m_networkpages[1].page->Show(thePrefs::GetNetworkKademlia());
1481 networks_notebook->Show(thePrefs::GetNetworkED2K() && thePrefs::GetNetworkKademlia());
1483 wxWindow* replacement = NULL;
1485 m_networknotebooksizer->Clear();
1487 if (thePrefs::GetNetworkED2K() && thePrefs::GetNetworkKademlia()) {
1488 toolbarTool->SetLabel(_("Networks"));
1490 m_networkpages[0].page->Reparent(networks_notebook);
1491 m_networkpages[1].page->Reparent(networks_notebook);
1493 networks_notebook->AddPage(m_networkpages[0].page, m_networkpages[0].name);
1494 networks_notebook->AddPage(m_networkpages[1].page, m_networkpages[1].name);
1496 replacement = networks_notebook;
1498 } else if (thePrefs::GetNetworkED2K()) {
1499 toolbarTool->SetLabel(_("eD2k network"));
1500 replacement = m_networkpages[0].page;
1501 m_networkpages[1].page->Reparent(m_networknotebooksizer->GetContainingWindow());
1502 } else if (thePrefs::GetNetworkKademlia()) {
1503 toolbarTool->SetLabel(_("Kad network"));
1504 m_networkpages[0].page->Reparent(m_networknotebooksizer->GetContainingWindow());
1505 replacement = m_networkpages[1].page;
1506 } else {
1507 // No networks.
1508 toolbarTool->SetLabel(_("No network"));
1511 if (replacement) {
1512 replacement->Reparent(m_networknotebooksizer->GetContainingWindow());
1513 m_networknotebooksizer->Add( replacement, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxTOP, 5 );
1514 m_networknotebooksizer->Layout();
1517 m_wndToolbar->InsertTool(2, toolbarTool);
1519 m_wndToolbar->EnableTool(ID_BUTTONNETWORKS, (thePrefs::GetNetworkED2K() || thePrefs::GetNetworkKademlia()));
1520 m_wndToolbar->EnableTool(ID_BUTTONCONNECT, (thePrefs::GetNetworkED2K() || thePrefs::GetNetworkKademlia()));
1522 m_wndToolbar->Realize();
1524 m_searchwnd->FixSearchTypes();
1527 // File_checked_for_headers