2 // This file is part of the aMule Project.
4 // Copyright (c) 2003-2008 aMule Team ( admin@amule.org / http://www.amule.org )
5 // Copyright (c) 2002 Merkur ( devs@emule-project.net / http://www.emule-project.net )
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
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
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/wupdlock.h> // Needed for wxWindowUpdateLocker
41 #include <common/EventIDs.h>
44 #include "config.h" // Needed for SVNDATE, PACKAGE, VERSION
46 #include <common/ClientVersion.h>
47 #endif // HAVE_CONFIG_H
49 #include "amuleDlg.h" // Interface declarations.
51 #include <common/Format.h> // Needed for CFormat
52 #include "amule.h" // Needed for theApp
53 #include "ChatWnd.h" // Needed for CChatWnd
54 #include "ClientListCtrl.h" // Needed for CClientListCtrl
55 #include "DownloadListCtrl.h" // Needed for CDownloadListCtrl
56 #include "DownloadQueue.h" // Needed for CDownloadQueue
57 #include "KadDlg.h" // Needed for CKadDlg
59 #include "MuleTrayIcon.h"
60 #include "muuli_wdr.h" // Needed for ID_BUTTON*
61 #include "Preferences.h" // Needed for CPreferences
62 #include "PrefsUnifiedDlg.h"
63 #include "SearchDlg.h" // Needed for CSearchDlg
64 #include "Server.h" // Needed for CServer
65 #include "ServerConnect.h" // Needed for CServerConnect
66 #include "ServerWnd.h" // Needed for CServerWnd
67 #include "SharedFilesWnd.h" // Needed for CSharedFilesWnd
68 #include "Statistics.h" // Needed for theStats
69 #include "StatisticsDlg.h" // Needed for CStatisticsDlg
70 #include "TerminationProcess.h" // Needed for CTerminationProcess
71 #include "TransferWnd.h" // Needed for CTransferWnd
73 #include "PartFileConvert.h"
80 #include "kademlia/kademlia/Kademlia.h"
82 #ifdef ENABLE_IP2COUNTRY
83 #include "IP2Country.h" // Needed for IP2Country
86 BEGIN_EVENT_TABLE(CamuleDlg
, wxFrame
)
88 EVT_TOOL(ID_BUTTONNETWORKS
, CamuleDlg::OnToolBarButton
)
89 EVT_TOOL(ID_BUTTONSEARCH
, CamuleDlg::OnToolBarButton
)
90 EVT_TOOL(ID_BUTTONTRANSFER
, CamuleDlg::OnToolBarButton
)
91 EVT_TOOL(ID_BUTTONSHARED
, CamuleDlg::OnToolBarButton
)
92 EVT_TOOL(ID_BUTTONMESSAGES
, CamuleDlg::OnToolBarButton
)
93 EVT_TOOL(ID_BUTTONSTATISTICS
, CamuleDlg::OnToolBarButton
)
94 EVT_TOOL(ID_ABOUT
, CamuleDlg::OnAboutButton
)
96 EVT_TOOL(ID_BUTTONNEWPREFERENCES
, CamuleDlg::OnPrefButton
)
98 EVT_TOOL(ID_BUTTONIMPORT
, CamuleDlg::OnImportButton
)
101 EVT_TOOL(ID_BUTTONCONNECT
, CamuleDlg::OnBnConnect
)
103 EVT_CLOSE(CamuleDlg::OnClose
)
104 EVT_ICONIZE(CamuleDlg::OnMinimize
)
106 EVT_BUTTON(ID_BUTTON_FAST
, CamuleDlg::OnBnClickedFast
)
107 EVT_BUTTON(IDC_SHOWSTATUSTEXT
, CamuleDlg::OnBnStatusText
)
109 EVT_TIMER(ID_GUI_TIMER_EVENT
, CamuleDlg::OnGUITimer
)
111 EVT_SIZE(CamuleDlg::OnMainGUISizeChange
)
113 EVT_KEY_UP(CamuleDlg::OnKeyPressed
)
115 EVT_MENU(wxID_EXIT
, CamuleDlg::OnExit
)
120 #define wxCLOSE_BOX 0
123 CamuleDlg::CamuleDlg(
125 const wxString
&title
,
130 pParent
, -1, title
, where
, dlg_size
,
131 wxCAPTION
|wxRESIZE_BORDER
|wxSYSTEM_MENU
|wxDIALOG_NO_PARENT
|
132 wxRESIZE_BORDER
|wxMINIMIZE_BOX
|wxMAXIMIZE_BOX
|wxCLOSE_BOX
,
137 m_sharedfileswnd(NULL
),
140 m_statisticswnd(NULL
),
146 m_prefsVisible(false),
148 m_wndTaskbarNotifier(NULL
),
149 m_nActiveDialog(DT_NETWORKS_WND
),
150 m_is_safe_state(false),
151 m_BlinkMessages(false),
152 m_CurrentBlinkBitmap(24),
155 m_clientSkinNames(CLIENT_SKIN_SIZE
)
157 // Initialize skin names
158 m_clientSkinNames
[Client_Green_Smiley
] = wxT("Transfer");
159 m_clientSkinNames
[Client_Red_Smiley
] = wxT("Connecting");
160 m_clientSkinNames
[Client_Yellow_Smiley
] = wxT("OnQueue");
161 m_clientSkinNames
[Client_Grey_Smiley
] = wxT("A4AFNoNeededPartsQueueFull");
162 m_clientSkinNames
[Client_White_Smiley
] = wxT("StatusUnknown");
163 m_clientSkinNames
[Client_ExtendedProtocol_Smiley
] = wxT("ExtendedProtocol");
164 m_clientSkinNames
[Client_SecIdent_Smiley
] = wxT("SecIdent");
165 m_clientSkinNames
[Client_BadGuy_Smiley
] = wxT("BadGuy");
166 m_clientSkinNames
[Client_CreditsGrey_Smiley
] = wxT("CreditsGrey");
167 m_clientSkinNames
[Client_CreditsYellow_Smiley
] = wxT("CreditsYellow");
168 m_clientSkinNames
[Client_Upload_Smiley
] = wxT("Upload");
169 m_clientSkinNames
[Client_Friend_Smiley
] = wxT("Friend");
170 m_clientSkinNames
[Client_eMule_Smiley
] = wxT("eMule");
171 m_clientSkinNames
[Client_mlDonkey_Smiley
] = wxT("mlDonkey");
172 m_clientSkinNames
[Client_eDonkeyHybrid_Smiley
] = wxT("eDonkeyHybrid");
173 m_clientSkinNames
[Client_aMule_Smiley
] = wxT("aMule");
174 m_clientSkinNames
[Client_lphant_Smiley
] = wxT("lphant");
175 m_clientSkinNames
[Client_Shareaza_Smiley
] = wxT("Shareaza");
176 m_clientSkinNames
[Client_xMule_Smiley
] = wxT("xMule");
177 m_clientSkinNames
[Client_Unknown
] = wxT("Unknown");
178 m_clientSkinNames
[Client_InvalidRating_Smiley
] = wxT("InvalidRatingOnFile");
179 m_clientSkinNames
[Client_PoorRating_Smiley
] = wxT("PoorRatingOnFile");
180 m_clientSkinNames
[Client_GoodRating_Smiley
] = wxT("GoodRatingOnFile");
181 m_clientSkinNames
[Client_FairRating_Smiley
] = wxT("FairRatingOnFile");
182 m_clientSkinNames
[Client_ExcellentRating_Smiley
] = wxT("ExcellentRatingOnFile");
183 m_clientSkinNames
[Client_CommentOnly_Smiley
] = wxT("CommentOnly");
184 m_clientSkinNames
[Client_Encryption_Smiley
] = wxT("Encrypted");
186 // wxWidgets send idle events to ALL WINDOWS by default... *SIGH*
187 wxIdleEvent::SetMode(wxIDLE_PROCESS_SPECIFIED
);
188 wxUpdateUIEvent::SetMode(wxUPDATE_UI_PROCESS_SPECIFIED
);
189 wxInitAllImageHandlers();
190 Apply_Clients_Skin();
192 bool override_where
= where
!= wxDefaultPosition
;
194 dlg_size
.x
!= DEFAULT_SIZE_X
||
195 dlg_size
.y
!= DEFAULT_SIZE_Y
;
196 if (!LoadGUIPrefs(override_where
, override_size
)) {
197 // Prefs not loaded for some reason, exit
198 AddLogLineM( true, wxT("Error! Unable to load Preferences") );
202 SetIcon(wxICON(aMule
));
206 // Create new sizer and stuff a wxPanel in there.
207 wxFlexGridSizer
*s_main
= new wxFlexGridSizer(1);
208 s_main
->AddGrowableCol(0);
209 s_main
->AddGrowableRow(0);
211 wxPanel
* p_cnt
= new wxPanel(this, -1, wxDefaultPosition
, wxDefaultSize
);
212 s_main
->Add(p_cnt
, 0, wxGROW
|wxEXPAND
, 0);
213 muleDlg(p_cnt
, false, true);
214 SetSizer(s_main
, true);
216 m_serverwnd
= new CServerWnd(p_cnt
, m_srv_split_pos
);
217 AddLogLineM(false, wxEmptyString
);
218 AddLogLineM(false, wxT(" - ") +
219 CFormat(_("This is aMule %s based on eMule.")) % GetMuleVersion());
220 AddLogLineM(false, wxT(" ") +
221 CFormat(_("Running on %s")) % wxGetOsDescription());
222 AddLogLineM(false, wxT(" - ") +
223 wxString(_("Visit http://www.amule.org to check if a new version is available.")));
224 AddLogLineM(false, wxEmptyString
);
226 #ifdef ENABLE_IP2COUNTRY
227 m_IP2Country
= new CIP2Country();
229 m_searchwnd
= new CSearchDlg(p_cnt
);
230 m_transferwnd
= new CTransferWnd(p_cnt
);
231 m_sharedfileswnd
= new CSharedFilesWnd(p_cnt
);
232 m_statisticswnd
= new CStatisticsDlg(p_cnt
, theApp
->m_statistics
);
233 m_chatwnd
= new CChatWnd(p_cnt
);
234 m_kademliawnd
= CastChild(wxT("kadWnd"), CKadDlg
);
236 m_serverwnd
->Show(false);
237 m_searchwnd
->Show(false);
238 m_transferwnd
->Show(false);
239 m_sharedfileswnd
->Show(false);
240 m_statisticswnd
->Show(false);
241 m_chatwnd
->Show(false);
243 // Create the GUI timer
244 gui_timer
=new wxTimer(this,ID_GUI_TIMER_EVENT
);
246 AddLogLine(false, _("Fatal Error: Failed to create Timer"));
250 // Set Serverlist as active window
251 Create_Toolbar(thePrefs::VerticalToolbar());
252 SetActiveDialog(DT_NETWORKS_WND
, m_serverwnd
);
253 m_wndToolbar
->ToggleTool(ID_BUTTONNETWORKS
, true );
255 m_is_safe_state
= true;
257 // Init statistics stuff, better do it asap
258 m_statisticswnd
->Init();
259 m_kademliawnd
->Init();
260 m_searchwnd
->UpdateCatChoice();
261 if (thePrefs::UseTrayIcon()) {
266 // Must we start minimized?
267 if (thePrefs::GetStartMinimized()) {
272 wxAcceleratorEntry entries
[] = {
273 wxAcceleratorEntry(wxACCEL_CTRL
, wxT('Q'), wxID_EXIT
)
276 SetAcceleratorTable(wxAcceleratorTable(itemsof(entries
), entries
));
277 ShowED2KLinksHandler( thePrefs::GetFED2KLH() );
281 // Madcat - Sets Fast ED2K Links Handler on/off.
282 void CamuleDlg::ShowED2KLinksHandler( bool show
)
284 // Errorchecking in case the pointer becomes invalid ...
285 if (s_fed2klh
== NULL
) {
286 wxLogWarning(wxT("Unable to find Fast ED2K Links handler sizer! Hiding FED2KLH aborted."));
290 s_dlgcnt
->Show( s_fed2klh
, show
);
294 // Toogles ed2k link handler.
295 void CamuleDlg::ToogleED2KLinksHandler()
297 // Errorchecking in case the pointer becomes invalid ...
298 if (s_fed2klh
== NULL
) {
299 wxLogWarning(wxT("Unable to find Fast ED2K Links handler sizer! Toogling FED2KLH aborted."));
302 ShowED2KLinksHandler(!s_dlgcnt
->IsShown(s_fed2klh
));
305 void CamuleDlg::SetActiveDialog(DialogType type
, wxWindow
* dlg
)
307 m_nActiveDialog
= type
;
309 if ( type
== DT_TRANSFER_WND
) {
310 if (thePrefs::ShowCatTabInfos()) {
311 m_transferwnd
->UpdateCatTabTitles();
316 m_activewnd
->Show(false);
317 contentSizer
->Detach(m_activewnd
);
320 contentSizer
->Add(dlg
, 1, wxALIGN_LEFT
|wxEXPAND
);
325 // Since we might be suspending redrawing while hiding the dialog
326 // we have to refresh it once it is visible again
327 dlg
->Refresh( true );
332 void CamuleDlg::UpdateTrayIcon(int percent
)
335 if(!theApp
->IsConnected()) {
336 m_wndTaskbarNotifier
->SetTrayIcon(TRAY_ICON_DISCONNECTED
, percent
);
338 if(theApp
->IsConnectedED2K() && theApp
->serverconnect
->IsLowID()) {
339 m_wndTaskbarNotifier
->SetTrayIcon(TRAY_ICON_LOWID
, percent
);
341 m_wndTaskbarNotifier
->SetTrayIcon(TRAY_ICON_HIGHID
, percent
);
347 void CamuleDlg::CreateSystray()
349 wxCHECK_RET(m_wndTaskbarNotifier
== NULL
,
350 wxT("Systray already created"));
352 m_wndTaskbarNotifier
= new CMuleTrayIcon();
353 // This will effectively show the Tray Icon.
358 void CamuleDlg::RemoveSystray()
360 delete m_wndTaskbarNotifier
;
361 m_wndTaskbarNotifier
= NULL
;
365 void CamuleDlg::OnToolBarButton(wxCommandEvent
& ev
)
367 static int lastbutton
= ID_BUTTONNETWORKS
;
369 // Kry - just if the GUI is ready for it
370 if ( m_is_safe_state
) {
372 // Rehide the handler if needed
373 if ( lastbutton
== ID_BUTTONSEARCH
&& !thePrefs::GetFED2KLH() ) {
374 if (ev
.GetId() != ID_BUTTONSEARCH
) {
375 ShowED2KLinksHandler( false );
377 // Toogle ED2K handler.
378 ToogleED2KLinksHandler();
382 if ( lastbutton
!= ev
.GetId() ) {
383 switch ( ev
.GetId() ) {
384 case ID_BUTTONNETWORKS
:
385 SetActiveDialog(DT_NETWORKS_WND
, m_serverwnd
);
386 // Set serverlist splitter position
387 CastChild( wxT("SrvSplitterWnd"), wxSplitterWindow
)->SetSashPosition(m_srv_split_pos
, true);
390 case ID_BUTTONSEARCH
:
391 // The search dialog should always display the handler
392 if ( !thePrefs::GetFED2KLH() )
393 ShowED2KLinksHandler( true );
395 SetActiveDialog(DT_SEARCH_WND
, m_searchwnd
);
398 case ID_BUTTONTRANSFER
:
399 SetActiveDialog(DT_TRANSFER_WND
, m_transferwnd
);
400 // Prepare the dialog, sets the splitter-position
401 m_transferwnd
->Prepare();
404 case ID_BUTTONSHARED
:
405 SetActiveDialog(DT_SHARED_WND
, m_sharedfileswnd
);
408 case ID_BUTTONMESSAGES
:
409 m_BlinkMessages
= false;
410 SetActiveDialog(DT_CHAT_WND
, m_chatwnd
);
413 case ID_BUTTONSTATISTICS
:
414 SetActiveDialog(DT_STATS_WND
, m_statisticswnd
);
417 // This shouldn't happen, but just in case
419 AddLogLineM( true, wxT("Unknown button triggered CamuleApp::OnToolBarButton().") );
424 m_wndToolbar
->ToggleTool(lastbutton
, lastbutton
== ev
.GetId() );
425 lastbutton
= ev
.GetId();
430 void CamuleDlg::OnAboutButton(wxCommandEvent
& WXUNUSED(ev
))
432 wxString msg
= wxT(" ");
434 msg
<< _("aMule remote control ") << wxT(VERSION
);
436 msg
<< wxT("aMule ") << wxT(VERSION
);
440 msg
<< _("Snapshot:") << wxT("\n ") << wxT(SVNDATE
);
442 msg
<< wxT("\n\n") << _(" 'All-Platform' p2p client based on eMule \n\n") <<
443 _(" Website: http://www.amule.org \n") <<
444 _(" Forum: http://forum.amule.org \n") <<
445 _(" FAQ: http://wiki.amule.org \n\n") <<
446 _(" Contact: admin@amule.org (administrative issues) \n") <<
447 _(" Copyright (C) 2003-2008 aMule Team \n\n") <<
448 _(" Part of aMule is based on \n") <<
449 _("Kademlia: Peer-to-peer routing based on the XOR metric.\n") <<
450 _(" Copyright (C) 2002 Petar Maymounkov\n") <<
451 _(" http://kademlia.scs.cs.nyu.edu\n");
453 if (m_is_safe_state
) {
454 wxMessageBox(msg
, _("Message"), wxOK
| wxICON_INFORMATION
, this);
459 void CamuleDlg::OnPrefButton(wxCommandEvent
& WXUNUSED(ev
))
461 if (m_is_safe_state
) {
462 if (m_prefsDialog
== NULL
) {
463 m_prefsDialog
= new PrefsUnifiedDlg(this);
466 m_prefsDialog
->TransferToWindow();
467 m_prefsDialog
->Show(true);
468 m_prefsDialog
->Raise();
474 void CamuleDlg::OnImportButton(wxCommandEvent
& WXUNUSED(ev
))
476 if ( m_is_safe_state
) {
477 CPartFileConvert::ShowGUI(NULL
);
482 CamuleDlg::~CamuleDlg()
484 printf("Shutting down aMule...\n");
488 theApp
->amuledlg
= NULL
;
490 printf("aMule dialog destroyed\n");
494 void CamuleDlg::OnBnConnect(wxCommandEvent
& WXUNUSED(evt
))
497 bool disconnect
= (theApp
->IsConnectedED2K() || theApp
->serverconnect
->IsConnecting())
499 || (Kademlia::CKademlia::IsRunning())
502 if (thePrefs::GetNetworkED2K()) {
504 //disconnect if currently connected
505 if (theApp
->serverconnect
->IsConnecting()) {
506 theApp
->serverconnect
->StopConnectionTry();
508 theApp
->serverconnect
->Disconnect();
511 //connect if not currently connected
512 AddLogLine(true, _("Connecting"));
513 theApp
->serverconnect
->ConnectToAnyServer();
516 wxASSERT(!theApp
->IsConnectedED2K());
520 if (thePrefs::GetNetworkKademlia()) {
528 wxASSERT(!Kademlia::CKademlia::IsRunning());
532 ShowConnectionState();
536 void CamuleDlg::OnBnStatusText(wxCommandEvent
& WXUNUSED(evt
))
538 wxString line
= CastChild(wxT("infoLabel"), wxStaticText
)->GetLabel();
540 if (!line
.IsEmpty()) {
541 wxMessageBox(line
, wxString(_("Status text")), wxOK
|wxICON_INFORMATION
, this);
546 void CamuleDlg::ResetLog(int id
)
548 wxTextCtrl
* ct
= CastByID(id
, m_serverwnd
, wxTextCtrl
);
549 wxCHECK_RET(ct
, wxT("Resetting unknown log"));
553 if (id
== ID_LOGVIEW
) {
554 // Also clear the log line
555 wxStaticText
* text
= CastChild(wxT("infoLabel"), wxStaticText
);
556 text
->SetLabel(wxEmptyString
);
557 text
->GetParent()->Layout();
562 void CamuleDlg::AddLogLine(bool addtostatusbar
, const wxString
& line
)
564 // Remove newspace at end, it causes problems with the layout...
565 wxString bufferline
= line
.Strip(wxString::trailing
);
567 // Create the timestamp
568 wxString stamp
= wxDateTime::Now().FormatISODate() + wxT(" ") + wxDateTime::Now().FormatISOTime() + wxT(": ");
570 // Add the message to the log-view
571 wxTextCtrl
* ct
= CastByID( ID_LOGVIEW
, m_serverwnd
, wxTextCtrl
);
573 if ( bufferline
.IsEmpty() ) {
574 // If it's empty we just write a blank line with no timestamp.
575 ct
->AppendText( wxT("\n") );
577 // Bold critical log-lines
578 wxTextAttr style
= ct
->GetDefaultStyle();
579 wxFont font
= style
.GetFont();
580 font
.SetWeight(addtostatusbar
? wxFONTWEIGHT_BOLD
: wxFONTWEIGHT_NORMAL
);
582 ct
->SetDefaultStyle(style
);
584 // Split multi-line messages into individual lines
585 wxStringTokenizer
tokens( bufferline
, wxT("\n") );
586 while ( tokens
.HasMoreTokens() ) {
587 ct
->AppendText( stamp
+ tokens
.GetNextToken() + wxT("\n") );
591 ct
->ShowPosition( ct
->GetLastPosition() - 1 );
595 // Set the status-bar if the event warrents it
596 if ( addtostatusbar
) {
597 // Escape "&"s, which would otherwise not show up
598 bufferline
.Replace( wxT("&"), wxT("&&") );
599 wxStaticText
* text
= CastChild( wxT("infoLabel"), wxStaticText
);
600 // Only show the first line if multiple lines
601 text
->SetLabel( bufferline
.BeforeFirst( wxT('\n') ) );
602 text
->GetParent()->Layout();
608 void CamuleDlg::AddServerMessageLine(wxString
& message
)
610 wxTextCtrl
* cv
= CastByID( ID_SERVERINFO
, m_serverwnd
, wxTextCtrl
);
612 if (message
.Length() > 500) {
613 cv
->AppendText(message
.Left(500) + wxT("\n"));
615 cv
->AppendText(message
+ wxT("\n"));
617 cv
->ShowPosition(cv
->GetLastPosition()-1);
622 void CamuleDlg::ShowConnectionState()
624 static wxImageList
status_arrows(16,16,true,0);
625 if (!status_arrows
.GetImageCount()) {
626 // Generate the image list (This is only done once)
627 for (int t
= 0; t
< 7; ++t
) {
628 status_arrows
.Add(connImages(t
));
632 m_serverwnd
->UpdateED2KInfo();
633 m_serverwnd
->UpdateKadInfo();
636 ////////////////////////////////////////////////////////////
637 // Determine the status of the networks
639 enum ED2KState
{ ED2KOff
= 0, ED2KLowID
= 1, ED2KConnecting
= 2, ED2KHighID
= 3 };
640 enum EKadState
{ EKadOff
= 4, EKadFW
= 5, EKadConnecting
= 5, EKadOK
= 6 };
642 ED2KState ed2kState
= ED2KOff
;
643 EKadState kadState
= EKadOff
;
645 ////////////////////////////////////////////////////////////
646 // Update the label on the status-bar and determine
647 // the states of the two networks.
650 if (theApp
->IsConnectedED2K()) {
651 CServer
* server
= theApp
->serverconnect
->GetCurrentServer();
653 msgED2K
= CFormat(wxT("ED2K: %s")) % server
->GetListName();
656 if (theApp
->serverconnect
->IsLowID()) {
657 ed2kState
= ED2KLowID
;
659 ed2kState
= ED2KHighID
;
661 } else if (theApp
->serverconnect
->IsConnecting()) {
662 msgED2K
= _("ED2K: Connecting");
664 ed2kState
= ED2KConnecting
;
665 } else if (thePrefs::GetNetworkED2K()) {
666 msgED2K
= _("ED2K: Disconnected");
670 if (theApp
->IsConnectedKad()) {
671 if (theApp
->IsFirewalledKad()) {
672 msgKad
= _("Kad: Firewalled");
676 msgKad
= _("Kad: Connected");
680 } else if (theApp
->IsKadRunning()) {
681 msgKad
= _("Kad: Connecting");
683 kadState
= EKadConnecting
;
684 } else if (thePrefs::GetNetworkKademlia()) {
685 msgKad
= _("Kad: Off");
688 wxStaticText
* connLabel
= CastChild( wxT("connLabel"), wxStaticText
);
689 wxCHECK_RET(connLabel
, wxT("'connLabel' widget not found"));
692 if (msgED2K
.Length() && msgKad
.Length()) {
693 labelMsg
= msgED2K
+ wxT(" | ") + msgKad
;
695 labelMsg
= msgED2K
+ msgKad
;
698 connLabel
->SetLabel(labelMsg
);
699 connLabel
->GetParent()->Layout();
702 ////////////////////////////////////////////////////////////
703 // Update the connect/disconnect/cancel button.
712 static EConnState s_oldState
= ECS_Unknown
;
713 EConnState currentState
= ECS_Disconnected
;
715 if (theApp
->serverconnect
->IsConnecting() ||
716 (theApp
->IsKadRunning() && !theApp
->IsConnectedKad())) {
717 currentState
= ECS_Connecting
;
718 } else if (theApp
->IsConnected()) {
719 currentState
= ECS_Connected
;
721 currentState
= ECS_Disconnected
;
724 if (currentState
!= s_oldState
) {
725 m_wndToolbar
->Freeze();
726 wxToolBarToolBase
* toolbarTool
= m_wndToolbar
->RemoveTool(ID_BUTTONCONNECT
);
728 switch (currentState
) {
730 toolbarTool
->SetLabel(_("Cancel"));
731 toolbarTool
->SetShortHelp(_("Stop the current connection attempts"));
732 toolbarTool
->SetNormalBitmap(m_tblist
.GetBitmap(2));
736 toolbarTool
->SetLabel(_("Disconnect"));
737 toolbarTool
->SetShortHelp(_("Disconnect from the currently connected networks"));
738 toolbarTool
->SetNormalBitmap(m_tblist
.GetBitmap(1));
742 toolbarTool
->SetLabel(_("Connect"));
743 toolbarTool
->SetShortHelp(_("Connect to the currently enabled networks"));
744 toolbarTool
->SetNormalBitmap(m_tblist
.GetBitmap(0));
747 m_wndToolbar
->InsertTool(0, toolbarTool
);
748 m_wndToolbar
->Realize();
749 m_wndToolbar
->Thaw();
751 s_oldState
= currentState
;
755 ////////////////////////////////////////////////////////////
756 // Update the globe-icon in the lower-right corner.
758 wxStaticBitmap
* connBitmap
= CastChild( wxT("connImage"), wxStaticBitmap
);
759 wxCHECK_RET(connBitmap
, wxT("'connImage' widget not found"));
761 wxBitmap statusIcon
= connBitmap
->GetBitmap();
762 wxMemoryDC
bitmapDC(statusIcon
);
764 status_arrows
.Draw(kadState
, bitmapDC
, 0, 0, wxIMAGELIST_DRAW_TRANSPARENT
);
765 status_arrows
.Draw(ed2kState
, bitmapDC
, 0, 0, wxIMAGELIST_DRAW_TRANSPARENT
);
767 connBitmap
->SetBitmap(statusIcon
);
771 void CamuleDlg::ShowUserCount(const wxString
& info
)
773 wxStaticText
* label
= CastChild( wxT("userLabel"), wxStaticText
);
776 m_serverwnd
->UpdateKadInfo();
778 label
->SetLabel(info
);
779 label
->GetParent()->Layout();
783 void CamuleDlg::ShowTransferRate()
785 float kBpsUp
= theStats::GetUploadRate() / 1024.0;
786 float kBpsDown
= theStats::GetDownloadRate() / 1024.0;
788 if( thePrefs::ShowOverhead() )
790 buffer
= wxString::Format(_("Up: %.1f(%.1f) | Down: %.1f(%.1f)"), kBpsUp
, theStats::GetUpOverheadRate() / 1024.0, kBpsDown
, theStats::GetDownOverheadRate() / 1024.0);
792 buffer
= wxString::Format(_("Up: %.1f | Down: %.1f"), kBpsUp
, kBpsDown
);
794 buffer
.Truncate(50); // Max size 50
796 wxStaticText
* label
= CastChild( wxT("speedLabel"), wxStaticText
);
797 label
->SetLabel(buffer
);
798 label
->GetParent()->Layout();
800 // Show upload/download speed in title
801 if (thePrefs::GetShowRatesOnTitle()) {
802 wxString UpDownSpeed
= wxString::Format(wxT(" -- Up: %.1f | Down: %.1f"), kBpsUp
, kBpsDown
);
803 SetTitle(theApp
->m_FrameTitle
+ UpDownSpeed
);
806 wxASSERT((m_wndTaskbarNotifier
!= NULL
) == thePrefs::UseTrayIcon());
807 if (m_wndTaskbarNotifier
) {
809 int percentDown
= (int)ceil((kBpsDown
*100) / thePrefs::GetMaxGraphDownloadRate());
810 UpdateTrayIcon( ( percentDown
> 100 ) ? 100 : percentDown
);
813 if ( theApp
->IsConnected() ) {
814 buffer2
= CFormat(_("aMule (%s | Connected)")) % buffer
;
816 buffer2
= CFormat(_("aMule (%s | Disconnected)")) % buffer
;
818 m_wndTaskbarNotifier
->SetTrayToolTip(buffer2
);
821 wxStaticBitmap
* bmp
= CastChild( wxT("transferImg"), wxStaticBitmap
);
822 bmp
->SetBitmap(dlStatusImages((kBpsUp
>0.01 ? 2 : 0) + (kBpsDown
>0.01 ? 1 : 0)));
825 void CamuleDlg::DlgShutDown()
827 // Are we already shutting down or still on init?
828 if ( m_is_safe_state
== false ) {
833 m_is_safe_state
= false;
835 // Stop the GUI Timer
837 m_transferwnd
->downloadlistctrl
->DeleteAllItems();
839 // We want to delete the systray too!
843 void CamuleDlg::OnClose(wxCloseEvent
& evt
)
845 // This will be here till the core close is != app close
846 if (evt
.CanVeto() && thePrefs::IsConfirmExitEnabled() ) {
847 if (wxNO
== wxMessageBox(wxString(_("Do you really want to exit aMule?")),
848 wxString(_("Exit confirmation")), wxYES_NO
, this)) {
857 theApp
->ShutDown(evt
);
861 void CamuleDlg::OnBnClickedFast(wxCommandEvent
& WXUNUSED(evt
))
863 wxTextCtrl
* ctl
= CastChild( wxT("FastEd2kLinks"), wxTextCtrl
);
865 for ( int i
= 0; i
< ctl
->GetNumberOfLines(); i
++ ) {
866 wxString strlink
= ctl
->GetLineText(i
);
869 if ( !strlink
.IsEmpty() ) {
870 theApp
->downloadqueue
->AddLink( strlink
, m_transferwnd
->downloadlistctrl
->GetCategory() );
874 ctl
->SetValue(wxEmptyString
);
878 // Formerly known as LoadRazorPrefs()
879 bool CamuleDlg::LoadGUIPrefs(bool override_pos
, bool override_size
)
881 // Create a config base for loading razor preferences
882 wxConfigBase
*config
= wxConfigBase::Get();
883 // If config haven't been created exit without loading
884 if (config
== NULL
) {
888 // The section where to save in in file
889 wxString section
= wxT("/Razor_Preferences/");
891 // Get window size and position
892 int x1
= config
->Read(section
+ wxT("MAIN_X_POS"), -1);
893 int y1
= config
->Read(section
+ wxT("MAIN_Y_POS"), -1);
894 int x2
= config
->Read(section
+ wxT("MAIN_X_SIZE"), -1);
895 int y2
= config
->Read(section
+ wxT("MAIN_Y_SIZE"), -1);
897 int maximized
= config
->Read(section
+ wxT("Maximized"), 01);
899 // Kry - Random usable pos for m_srv_split_pos
900 m_srv_split_pos
= config
->Read(section
+ wxT("SRV_SPLITTER_POS"), 463l);
901 if (!override_size
) {
902 if (x2
> 0 && y2
> 0) {
906 // Probably first run.
913 // If x1 and y1 != -1 Redefine location
914 if(x1
!= -1 && y1
!= -1) {
915 wxRect display
= wxGetClientDisplayRect();
916 if (x1
<= display
.GetRightTop().x
&& y1
<= display
.GetRightBottom().y
) {
919 // It's offscreen... so let's not.
924 if (!override_size
&& !override_pos
&& maximized
) {
932 bool CamuleDlg::SaveGUIPrefs()
934 /* Razor 1a - Modif by MikaelB
935 Save client size and position */
937 // Create a config base for saving razor preferences
938 wxConfigBase
*config
= wxConfigBase::Get();
939 // If config haven't been created exit without saving
940 if (config
== NULL
) {
943 // The section where to save in in file
944 wxString section
= wxT("/Razor_Preferences/");
946 // Main window location and size
948 GetPosition(&x1
, &y1
);
951 // Saving window size and position
952 config
->Write(section
+wxT("MAIN_X_POS"), (long) x1
);
953 config
->Write(section
+wxT("MAIN_Y_POS"), (long) y1
);
955 config
->Write(section
+wxT("MAIN_X_SIZE"), (long) x2
);
956 config
->Write(section
+wxT("MAIN_Y_SIZE"), (long) y2
);
958 config
->Write(section
+wxT("Maximized"), (long) (IsMaximized() ? 1 : 0));
960 // Saving sash position of splitter in server window
961 config
->Write(section
+wxT("SRV_SPLITTER_POS"), (long) m_srv_split_pos
);
971 void CamuleDlg::DoIconize(bool iconize
)
973 // Evil Hack: check if the mouse is inside the window
975 if (GetScreenRect().Contains(wxGetMousePosition()))
978 if (m_wndTaskbarNotifier
&& thePrefs::DoMinToTray()) {
980 // Skip() will do it.
990 // Will be done by Skip();
996 void CamuleDlg::OnMinimize(wxIconizeEvent
& evt
)
998 if (m_prefsDialog
&& m_prefsDialog
->IsShown()) {
1001 if (m_wndTaskbarNotifier
) {
1002 DoIconize(evt
.Iconized());
1008 void CamuleDlg::OnGUITimer(wxTimerEvent
& WXUNUSED(evt
))
1010 // Former TimerProc section
1012 static uint32 msPrev1
, msPrev5
, msPrevStats
;
1014 uint32 msCur
= theStats::GetUptimeMillis();
1016 // can this actually happen under wxwin ?
1022 static uint32 msPrevGraph
;
1023 int msGraphUpdate
= thePrefs::GetTrafficOMeterInterval() * 1000;
1024 if ((msGraphUpdate
> 0) && ((msCur
/ msGraphUpdate
) > (msPrevGraph
/ msGraphUpdate
))) {
1025 // trying to get the graph shifts evenly spaced after a change in the update period
1026 msPrevGraph
= msCur
;
1028 GraphUpdateInfo update
= theApp
->m_statistics
->GetPointsForUpdate();
1030 m_statisticswnd
->UpdateStatGraphs(theStats::GetPeakConnections(), update
);
1031 m_kademliawnd
->UpdateGraph(update
);
1034 //#warning TODO: CORE/GUI -- EC needed
1037 int sStatsUpdate
= thePrefs::GetStatsInterval();
1038 if ((sStatsUpdate
> 0) && ((int)(msCur
- msPrevStats
) > sStatsUpdate
*1000)) {
1039 if (m_statisticswnd
->IsShownOnScreen()) {
1040 msPrevStats
= msCur
;
1041 m_statisticswnd
->ShowStatistics();
1045 if (msCur
-msPrev5
> 5000) { // every 5 seconds
1048 if (thePrefs::ShowCatTabInfos() && theApp
->amuledlg
->m_activewnd
== theApp
->amuledlg
->m_transferwnd
) {
1049 m_transferwnd
->UpdateCatTabTitles();
1051 if (thePrefs::AutoSortDownload()) {
1052 m_transferwnd
->downloadlistctrl
->SortList();
1056 if (msCur
-msPrev1
> 1000) { // every second
1058 if (m_CurrentBlinkBitmap
== 12) {
1059 m_CurrentBlinkBitmap
= 7;
1062 if (m_BlinkMessages
) {
1063 m_CurrentBlinkBitmap
= 12;
1072 void CamuleDlg::SetMessagesTool()
1074 int pos
= m_wndToolbar
->GetToolPos(ID_BUTTONMESSAGES
);
1075 wxASSERT(pos
== 6); // so we don't miss a change on wx2.4
1077 wxWindowUpdateLocker
freezer(m_wndToolbar
);
1078 wxToolBarToolBase
* item
= m_wndToolbar
->RemoveTool(ID_BUTTONMESSAGES
);
1079 item
->SetNormalBitmap(m_tblist
.GetBitmap(m_CurrentBlinkBitmap
));
1081 m_wndToolbar
->InsertTool(pos
, item
);
1082 m_wndToolbar
->Realize();
1087 Try to launch the specified url:
1088 - Windows: Default or custom browser will be used.
1089 - Mac: Currently not implemented
1090 - Anything else: Try a number of hardcoded browsers. Should be made configurable...
1092 void CamuleDlg::LaunchUrl( const wxString
& url
)
1096 cmd
= thePrefs::GetBrowser();
1097 if ( !cmd
.IsEmpty() ) {
1099 // Pipes cause problems, so escape them
1100 tmp
.Replace( wxT("|"), wxT("%7C") );
1102 if (!cmd
.Replace(wxT("%s"), tmp
)) {
1103 // No %s found, just append the url
1104 cmd
+= wxT(" ") + tmp
;
1107 CTerminationProcess
*p
= new CTerminationProcess(cmd
);
1108 if (wxExecute(cmd
, wxEXEC_ASYNC
, p
)) {
1109 printf( "Launch Command: %s\n", (const char *)unicode2char(cmd
));
1117 wxTheMimeTypesManager
->GetFileTypeFromExtension(wxT("html"));
1119 wxLogError(wxT("Impossible to determine the file type for extension html. Please edit your MIME types."));
1123 bool ok
= ft
->GetOpenCommand(
1124 &cmd
, wxFileType::MessageParameters(url
, wxT("")));
1129 _("Could not determine the command for running the browser."),
1130 wxT("Browsing problem"), wxOK
|wxICON_EXCLAMATION
, this);
1134 wxPuts(wxT("Launch Command: ") + cmd
);
1135 CTerminationProcess
*p
= new CTerminationProcess(cmd
);
1136 if (wxExecute(cmd
, wxEXEC_ASYNC
, p
)) {
1143 // Unable to execute browser. But this error message doesn't make sense,
1144 // cosidering that you _can't_ set the browser executable path... =/
1145 wxLogError(wxT("Unable to launch browser. Please set correct browser executable path in Preferences."));
1149 wxString
CamuleDlg::GenWebSearchUrl(const wxString
&filename
, WebSearch wsProvider
)
1152 switch (wsProvider
) {
1154 URL
= wxT("http://www.filehash.com/search.html?pattern=FILENAME&submit=Find");
1159 URL
.Replace(wxT("FILENAME"), filename
);
1165 bool CamuleDlg::Check_and_Init_Skin()
1168 wxString
skinFileName(thePrefs::GetSkin());
1170 wxString
userDir(JoinPaths(GetConfigDir(), wxT("skins")) + wxFileName::GetPathSeparator());
1172 wxStandardPathsBase
&spb(wxStandardPaths::Get());
1174 wxString
dataDir(spb
.GetPluginsDir());
1175 #elif defined(__WXMAC__)
1176 wxString
dataDir(spb
.GetDataDir());
1178 wxString
dataDir(spb
.GetDataDir().BeforeLast(wxT('/')) + wxT("/amule"));
1180 wxString
systemDir(JoinPaths(dataDir
,wxT("skins")) + wxFileName::GetPathSeparator());
1183 skinFileName
.Replace(wxT("User:"), userDir
);
1184 skinFileName
.Replace(wxT("System:"), systemDir
);
1186 m_skinFileName
.Assign(skinFileName
);
1187 if (!m_skinFileName
.FileExists()) {
1188 AddLogLineM(true, CFormat(
1189 _("Skin directory '%s' does not exist")) %
1192 } else if (!m_skinFileName
.IsFileReadable()) {
1193 AddLogLineM(true, CFormat(
1194 _("Warning: Unable to open skin file '%s' for read")) %
1199 wxFFileInputStream
in(m_skinFileName
.GetFullPath());
1200 wxZipInputStream
zip(in
);
1202 while ((entry
= zip
.GetNextEntry()) != NULL
) {
1203 wxZipEntry
*& current
= cat
[entry
->GetInternalName()];
1212 void CamuleDlg::Add_Skin_Icon(
1213 const wxString
&iconName
,
1214 const wxBitmap
&stdIcon
,
1219 wxFFileInputStream
in(m_skinFileName
.GetFullPath());
1220 wxZipInputStream
zip(in
);
1222 it
= cat
.find(wxZipEntry::GetInternalName(iconName
+ wxT(".png")));
1223 if ( it
!= cat
.end() ) {
1224 zip
.OpenEntry(*it
->second
);
1225 if ( !new_image
.LoadFile(zip
,wxBITMAP_TYPE_PNG
) ) {
1227 wxT("Warning: Error loading icon for ") +
1233 wxT("Warning: Can't load icon for ") +
1240 wxBitmap
bmp(useSkins
? new_image
: stdIcon
);
1241 if (iconName
.StartsWith(wxT("Client_"))) {
1242 m_imagelist
.Add(bmp
);
1243 } else if (iconName
.StartsWith(wxT("Toolbar_"))) {
1249 void CamuleDlg::Apply_Clients_Skin()
1251 bool useSkins
= thePrefs::UseSkins() && Check_and_Init_Skin();
1253 // Clear the client image list
1254 m_imagelist
.RemoveAll();
1256 // Add the images to the image list
1257 for (int i
= 0; i
< CLIENT_SKIN_SIZE
; ++i
) {
1258 Add_Skin_Icon(wxT("Client_") + m_clientSkinNames
[i
],
1259 clientImages(i
), useSkins
);
1264 void CamuleDlg::Apply_Toolbar_Skin(wxToolBar
*wndToolbar
)
1266 bool useSkins
= thePrefs::UseSkins() && Check_and_Init_Skin();
1268 // Clear the toolbar image list
1269 m_tblist
.RemoveAll();
1271 // Add the images to the image list
1272 Add_Skin_Icon(wxT("Toolbar_Connect"), connButImg(0), useSkins
);
1273 Add_Skin_Icon(wxT("Toolbar_Disconnect"), connButImg(1), useSkins
);
1274 Add_Skin_Icon(wxT("Toolbar_Connecting"), connButImg(2), useSkins
);
1275 Add_Skin_Icon(wxT("Toolbar_Network"), amuleDlgImages(20), useSkins
);
1276 Add_Skin_Icon(wxT("Toolbar_Transfers"), amuleDlgImages(21), useSkins
);
1277 Add_Skin_Icon(wxT("Toolbar_Search"), amuleDlgImages(22), useSkins
);
1278 Add_Skin_Icon(wxT("Toolbar_Shared"), amuleDlgImages(23), useSkins
);
1279 Add_Skin_Icon(wxT("Toolbar_Messages"), amuleDlgImages(24), useSkins
);
1280 Add_Skin_Icon(wxT("Toolbar_Stats"), amuleDlgImages(25), useSkins
);
1281 Add_Skin_Icon(wxT("Toolbar_Prefs"), amuleDlgImages(26), useSkins
);
1282 Add_Skin_Icon(wxT("Toolbar_Import"), amuleDlgImages(32), useSkins
);
1283 Add_Skin_Icon(wxT("Toolbar_About"), amuleDlgImages(29), useSkins
);
1284 Add_Skin_Icon(wxT("Toolbar_Blink"), amuleDlgImages(33), useSkins
);
1286 // Build aMule toolbar
1287 wndToolbar
->SetMargins(0, 0);
1289 // Placeholder. Gets updated by ShowConnectionState
1290 wndToolbar
->AddTool(ID_BUTTONCONNECT
, wxT("..."), m_tblist
.GetBitmap(0));
1292 wndToolbar
->AddSeparator();
1293 wndToolbar
->AddTool(ID_BUTTONNETWORKS
,
1294 _("Networks"), m_tblist
.GetBitmap(3),
1295 wxNullBitmap
, wxITEM_CHECK
,
1296 _("Networks Window"));
1297 wndToolbar
->ToggleTool(ID_BUTTONNETWORKS
, true);
1298 wndToolbar
->AddTool(ID_BUTTONSEARCH
,
1299 _("Searches"), m_tblist
.GetBitmap(5),
1300 wxNullBitmap
, wxITEM_CHECK
,
1301 _("Searches Window"));
1302 wndToolbar
->AddTool(ID_BUTTONTRANSFER
,
1303 _("Transfers"), m_tblist
.GetBitmap(4),
1304 wxNullBitmap
, wxITEM_CHECK
,
1305 _("Files Transfers Window"));
1306 wndToolbar
->AddTool(ID_BUTTONSHARED
,
1307 _("Shared Files"), m_tblist
.GetBitmap(6),
1308 wxNullBitmap
, wxITEM_CHECK
,
1309 _("Shared Files Window"));
1310 wndToolbar
->AddTool(ID_BUTTONMESSAGES
,
1311 _("Messages"), m_tblist
.GetBitmap(7),
1312 wxNullBitmap
, wxITEM_CHECK
,
1313 _("Messages Window"));
1314 wndToolbar
->AddTool(ID_BUTTONSTATISTICS
,
1315 _("Statistics"), m_tblist
.GetBitmap(8),
1316 wxNullBitmap
, wxITEM_CHECK
,
1317 _("Statistics Graph Window"));
1318 wndToolbar
->AddSeparator();
1319 wndToolbar
->AddTool(ID_BUTTONNEWPREFERENCES
,
1320 _("Preferences"), m_tblist
.GetBitmap(9),
1321 wxNullBitmap
, wxITEM_NORMAL
,
1322 _("Preferences Settings Window"));
1323 wndToolbar
->AddTool(ID_BUTTONIMPORT
,
1324 _("Import"), m_tblist
.GetBitmap(10),
1325 wxNullBitmap
, wxITEM_NORMAL
,
1326 _("The partfile importer tool"));
1327 wndToolbar
->AddTool(ID_ABOUT
,
1328 _("About"), m_tblist
.GetBitmap(11),
1329 wxNullBitmap
, wxITEM_NORMAL
,
1332 // Needed for non-GTK platforms, where the
1333 // items don't get added immediatly.
1334 wndToolbar
->Realize();
1336 // Updates the "Connect" button, and so on.
1337 ShowConnectionState();
1341 void CamuleDlg::Create_Toolbar(bool orientation
)
1344 // Create ToolBar from the one designed by wxDesigner (BigBob)
1345 wxToolBar
*current
= GetToolBar();
1347 wxASSERT(current
== m_wndToolbar
);
1350 bool oldorientation
= ((current
->GetWindowStyle() & wxTB_VERTICAL
) == wxTB_VERTICAL
);
1351 if (oldorientation
!= orientation
) {
1353 SetToolBar(NULL
); // Remove old one if present
1354 m_wndToolbar
= NULL
;
1356 current
->ClearTools();
1360 if (!m_wndToolbar
) {
1361 m_wndToolbar
= CreateToolBar(
1362 (orientation
? wxTB_VERTICAL
: wxTB_HORIZONTAL
) |
1363 wxNO_BORDER
| wxTB_TEXT
| wxTB_3DBUTTONS
|
1364 wxTB_FLAT
| wxCLIP_CHILDREN
| wxTB_NODIVIDER
);
1367 m_wndToolbar
->SetToolBitmapSize(wxSize(32, 32));
1370 Apply_Toolbar_Skin(m_wndToolbar
);
1372 m_wndToolbar
->DeleteTool(ID_BUTTONIMPORT
);
1379 void CamuleDlg::OnMainGUISizeChange(wxSizeEvent
& evt
)
1381 wxFrame::OnSize(evt
);
1382 if (m_transferwnd
&& m_transferwnd
->clientlistctrl
) {
1383 // Transfer window's splitter set again if it's hidden.
1384 if (m_transferwnd
->clientlistctrl
->GetListView() == vtNone
) {
1385 int height
= m_transferwnd
->clientlistctrl
->GetSize().GetHeight();
1386 wxSplitterWindow
* splitter
=
1387 CastChild(wxT("splitterWnd"), wxSplitterWindow
);
1388 height
+= splitter
->GetWindow1()->GetSize().GetHeight();
1389 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"));
1411 void CamuleDlg::OnExit(wxCommandEvent
& WXUNUSED(evt
))
1416 // File_checked_for_headers