2 // This file is part of the aMule Project.
4 // Copyright (c) 2004-2008 Angel Vidal ( kry@amule.org )
5 // Copyright (c) 2003-2008 Patrizio Bassi ( hetfield@amule.org )
6 // Copyright (c) 2003-2008 aMule Team ( admin@amule.org / http://www.amule.org )
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.
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
29 #include "MuleTrayIcon.h"
31 #include <common/ClientVersion.h>
32 #include <common/Constants.h>
34 #include "pixmaps/mule_TrayIcon_big.ico.xpm"
35 #include "pixmaps/mule_Tr_yellow_big.ico.xpm"
36 #include "pixmaps/mule_Tr_grey_big.ico.xpm"
40 #include "amule.h" // Needed for theApp
41 #include "amuleDlg.h" // Needed for IsShown
42 #include "Preferences.h" // Needed for thePrefs
43 #include "ServerConnect.h" // Needed for CServerConnect
44 #include "Server.h" // Needed for CServer
45 #include "StatisticsDlg.h" // Needed for CStatisticsDlg::getColors()
46 #include "Statistics.h" // Needed for theStats
47 #include <common/Format.h> // Needed for CFormat
51 // Pop-up menu clickable entries
54 TRAY_MENU_CLIENTINFO
=0,
55 TRAY_MENU_CLIENTINFO_ITEM
= 13007,
75 /****************************************************/
76 /******************* Event Table ********************/
77 /****************************************************/
79 BEGIN_EVENT_TABLE(CMuleTrayIcon
, wxTaskBarIcon
)
80 EVT_TASKBAR_LEFT_DCLICK(CMuleTrayIcon::SwitchShow
)
81 EVT_MENU( TRAY_MENU_EXIT
, CMuleTrayIcon::Close
)
82 EVT_MENU( TRAY_MENU_CONNECT
, CMuleTrayIcon::ServerConnection
)
83 EVT_MENU( TRAY_MENU_DISCONNECT
, CMuleTrayIcon::ServerConnection
)
84 EVT_MENU( TRAY_MENU_HIDE
, CMuleTrayIcon::ShowHide
)
85 EVT_MENU( TRAY_MENU_SHOW
, CMuleTrayIcon::ShowHide
)
86 EVT_MENU( UPLOAD_ITEM1
, CMuleTrayIcon::SetUploadSpeed
)
87 EVT_MENU( UPLOAD_ITEM2
, CMuleTrayIcon::SetUploadSpeed
)
88 EVT_MENU( UPLOAD_ITEM3
, CMuleTrayIcon::SetUploadSpeed
)
89 EVT_MENU( UPLOAD_ITEM4
, CMuleTrayIcon::SetUploadSpeed
)
90 EVT_MENU( UPLOAD_ITEM5
, CMuleTrayIcon::SetUploadSpeed
)
91 EVT_MENU( UPLOAD_ITEM6
, CMuleTrayIcon::SetUploadSpeed
)
92 EVT_MENU( DOWNLOAD_ITEM1
, CMuleTrayIcon::SetDownloadSpeed
)
93 EVT_MENU( DOWNLOAD_ITEM2
, CMuleTrayIcon::SetDownloadSpeed
)
94 EVT_MENU( DOWNLOAD_ITEM3
, CMuleTrayIcon::SetDownloadSpeed
)
95 EVT_MENU( DOWNLOAD_ITEM4
, CMuleTrayIcon::SetDownloadSpeed
)
96 EVT_MENU( DOWNLOAD_ITEM5
, CMuleTrayIcon::SetDownloadSpeed
)
97 EVT_MENU( DOWNLOAD_ITEM6
, CMuleTrayIcon::SetDownloadSpeed
)
100 /****************************************************/
101 /************ Constructor / Destructor **************/
102 /****************************************************/
104 long GetSpeedFromString(wxString label
){
106 label
.Replace(wxT("kB/s"),wxT(""),TRUE
);
113 void CMuleTrayIcon::SetUploadSpeed(wxCommandEvent
& event
){
115 wxObject
* obj
=event
.GetEventObject();
117 wxMenu
*menu
= dynamic_cast<wxMenu
*>(obj
);
119 wxMenuItem
* item
=menu
->FindItem(event
.GetId());
122 if (item
->GetItemLabelText()==(_("Unlimited"))) {
126 temp
=GetSpeedFromString(item
->GetItemLabelText());
128 thePrefs::SetMaxUpload(temp
);
131 // Send preferences to core.
132 theApp
->glob_prefs
->SendToRemote();
139 void CMuleTrayIcon::SetDownloadSpeed(wxCommandEvent
& event
){
141 wxObject
* obj
=event
.GetEventObject();
143 wxMenu
*menu
= dynamic_cast<wxMenu
*>(obj
);
145 wxMenuItem
* item
=menu
->FindItem(event
.GetId());
148 if (item
->GetItemLabelText()==(_("Unlimited"))) {
152 temp
=GetSpeedFromString(item
->GetItemLabelText());
154 thePrefs::SetMaxDownload(temp
);
157 // Send preferences to core.
158 theApp
->glob_prefs
->SendToRemote();
166 void CMuleTrayIcon::ServerConnection(wxCommandEvent
& WXUNUSED(event
))
169 theApp
->amuledlg
->OnBnConnect(evt
);
173 void CMuleTrayIcon::ShowHide(wxCommandEvent
& WXUNUSED(event
))
175 theApp
->amuledlg
->DoIconize(theApp
->amuledlg
->IsShown());
179 void CMuleTrayIcon::Close(wxCommandEvent
& WXUNUSED(event
))
181 if (theApp
->amuledlg
->IsEnabled()) {
182 theApp
->amuledlg
->Close();
187 CMuleTrayIcon::CMuleTrayIcon()
190 Old_SpeedSize
= 0xFFFF; // must be > any possible one.
191 // Create the background icons (speed improvement)
192 HighId_Icon_size
= wxIcon(mule_TrayIcon_big_ico_xpm
).GetHeight();
193 LowId_Icon_size
= wxIcon(mule_Tr_yellow_big_ico_xpm
).GetHeight();
194 Disconnected_Icon_size
= wxIcon(mule_Tr_grey_big_ico_xpm
).GetHeight();
197 CMuleTrayIcon::~CMuleTrayIcon()
200 // Issue has been fixed in wx SVN 53563, that's wx 2.8.8
201 #if !wxCHECK_VERSION(2, 8, 8)
202 // FIXME: EVIL HACK: We need to ensure that the superclass doesn't
203 // try to destroy a dangling pointer. See also CMuleTrayIcon::UpdateTray
204 // for comments on this issue.
206 if (wxTopLevelWindows
.IndexOf((wxWindow
*)m_iconWnd
) == wxNOT_FOUND
) {
214 /****************************************************/
215 /***************** Public Functions *****************/
216 /****************************************************/
218 void CMuleTrayIcon::SetTrayIcon(int Icon
, uint32 percent
)
223 case TRAY_ICON_HIGHID
:
224 // Most likely case, test first
225 Bar_ySize
= HighId_Icon_size
;
227 case TRAY_ICON_LOWID
:
228 Bar_ySize
= LowId_Icon_size
;
230 case TRAY_ICON_DISCONNECTED
:
231 Bar_ySize
= Disconnected_Icon_size
;
237 // Lookup this values for speed improvement: don't draw if not needed
238 int NewSize
= (Bar_ySize
* percent
) / 100;
240 if ((Old_Icon
!= Icon
) || (Old_SpeedSize
!= NewSize
)) {
242 if ((Old_SpeedSize
> NewSize
) || (Old_Icon
!= Icon
)) {
243 // We have to rebuild the icon, because bar is lower now.
245 case TRAY_ICON_HIGHID
:
246 // Most likely case, test first
247 CurrentIcon
= wxIcon(mule_TrayIcon_big_ico_xpm
);
249 case TRAY_ICON_LOWID
:
250 CurrentIcon
= wxIcon(mule_Tr_yellow_big_ico_xpm
);
252 case TRAY_ICON_DISCONNECTED
:
253 CurrentIcon
= wxIcon(mule_Tr_grey_big_ico_xpm
);
261 Old_SpeedSize
= NewSize
;
263 // Do whatever to the icon before drawing it (percent)
266 TempBMP
.CopyFromIcon(CurrentIcon
);
268 TempBMP
.SetMask(NULL
);
270 IconWithSpeed
.SelectObject(TempBMP
);
273 // Speed bar is: centered, taking 80% of the icon heigh, and
274 // right-justified taking a 10% of the icon width.
278 int Bar_xPos
= CurrentIcon
.GetWidth() - 5;
280 IconWithSpeed
.SetBrush(*(wxTheBrushList
->FindOrCreateBrush(CStatisticsDlg::getColors(11))));
281 IconWithSpeed
.SetPen(*wxTRANSPARENT_PEN
);
283 IconWithSpeed
.DrawRectangle(Bar_xPos
+ 1, Bar_ySize
- NewSize
, Bar_xSize
-2 , NewSize
);
285 // Unselect the icon.
286 IconWithSpeed
.SelectObject(wxNullBitmap
);
290 // Set a new mask with transparency set to red.
291 wxMask
* new_mask
= new wxMask(TempBMP
, wxColour(0xFF, 0x00, 0x00));
293 TempBMP
.SetMask(new_mask
);
294 CurrentIcon
.CopyFromBitmap(TempBMP
);
300 void CMuleTrayIcon::SetTrayToolTip(const wxString
& Tip
)
306 /****************************************************/
307 /**************** Private Functions *****************/
308 /****************************************************/
310 void CMuleTrayIcon::UpdateTray()
313 // Issue has been fixed in wx SVN 53563, that's wx 2.8.8
314 #if !wxCHECK_VERSION(2, 8, 8)
315 // FIXME: EVIL HACK: As of wxGTK-2.8.7, closing of the trayicon
316 // window (caused for instance by a crashing kicker) is not
317 // handled, with the result that the pointer to the trayicon
318 // window becomes a dangling pointer. Since we have access to
319 // the pointer, and it's created as a top-level window, it's
320 // relatively easy to force the recreation of a valid window.
321 // Ugly as hell though ....
323 // This has been repported as bug #1872724:
324 // http://sourceforge.net/tracker/index.php?func=detail&aid=1872724&group_id=9863&atid=109863
326 if (wxTopLevelWindows
.IndexOf((wxWindow
*)m_iconWnd
) == wxNOT_FOUND
) {
327 AddLogLineCS(_("Traybar-icon lost, trying to recreate ..."));
334 // Icon update and Tip update
339 SetIcon(CurrentIcon
, CurrentTip
);
344 wxMenu
* CMuleTrayIcon::CreatePopupMenu()
346 // Creates dinamically the menu to show the user.
347 wxMenu
*traymenu
= new wxMenu();
348 traymenu
->SetTitle(_("aMule Tray Menu"));
350 // Build the Top string name
351 wxString label
= MOD_VERSION_LONG
;
352 traymenu
->Append(TRAY_MENU_INFO
, label
);
353 traymenu
->AppendSeparator();
354 label
= wxString(_("Speed limits:")) + wxT(" ");
356 // Check for upload limits
357 unsigned int max_upload
= thePrefs::GetMaxUpload();
358 if ( max_upload
== UNLIMITED
) {
359 label
+= _("UL: None");
362 label
+= wxString::Format(_("UL: %u"), max_upload
);
366 // Check for download limits
367 unsigned int max_download
= thePrefs::GetMaxDownload();
368 if ( max_download
== UNLIMITED
) {
369 label
+= _("DL: None");
372 label
+= wxString::Format(_("DL: %u"), max_download
);
375 traymenu
->Append(TRAY_MENU_INFO
, label
);
376 label
= wxString::Format(_("Download speed: %.1f"), theStats::GetDownloadRate() / 1024.0);
377 traymenu
->Append(TRAY_MENU_INFO
, label
);
378 label
= wxString::Format(_("Upload speed: %.1f"), theStats::GetUploadRate() / 1024.0);
379 traymenu
->Append(TRAY_MENU_INFO
, label
);
380 traymenu
->AppendSeparator();
383 wxMenu
* ClientInfoMenu
= new wxMenu();
384 ClientInfoMenu
->SetTitle(_("Client Information"));
388 wxString temp
= CFormat(_("Nickname: %s")) % ( thePrefs::GetUserNick().IsEmpty() ? wxString(_("No Nickname Selected!")) : thePrefs::GetUserNick() );
390 ClientInfoMenu
->Append(TRAY_MENU_CLIENTINFO_ITEM
,temp
);
395 wxString temp
= _("ClientID: ");
397 if (theApp
->IsConnectedED2K()) {
398 unsigned long id
= theApp
->GetED2KID();
399 temp
+= wxString::Format(wxT("%lu"), id
);
401 temp
+= _("Not connected");
403 ClientInfoMenu
->Append(TRAY_MENU_CLIENTINFO_ITEM
,temp
);
406 // Current Server and Server IP
408 wxString temp_name
= _("ServerName: ");
409 wxString temp_ip
= _("ServerIP: ");
411 if ( theApp
->serverconnect
->GetCurrentServer() ) {
412 temp_name
+= theApp
->serverconnect
->GetCurrentServer()->GetListName();
413 temp_ip
+= theApp
->serverconnect
->GetCurrentServer()->GetFullIP();
415 temp_name
+= _("Not connected");
416 temp_ip
+= _("Not Connected");
418 ClientInfoMenu
->Append(TRAY_MENU_CLIENTINFO_ITEM
,temp_name
);
419 ClientInfoMenu
->Append(TRAY_MENU_CLIENTINFO_ITEM
,temp_ip
);
424 wxString temp
= CFormat(_("IP: %s")) % ( (theApp
->GetPublicIP()) ? Uint32toStringIP(theApp
->GetPublicIP()) : wxString(_("Unknown")) );
426 ClientInfoMenu
->Append(TRAY_MENU_CLIENTINFO_ITEM
,temp
);
432 if (thePrefs::GetPort()) {
433 temp
= CFormat(_("TCP port: %d")) % thePrefs::GetPort();
435 temp
=_("TCP port: Not ready");
437 ClientInfoMenu
->Append(TRAY_MENU_CLIENTINFO_ITEM
,temp
);
443 if (thePrefs::GetEffectiveUDPPort()) {
444 temp
= CFormat(_("UDP port: %d")) % thePrefs::GetEffectiveUDPPort();
446 temp
=_("UDP port: Not ready");
448 ClientInfoMenu
->Append(TRAY_MENU_CLIENTINFO_ITEM
,temp
);
454 if (thePrefs::IsOnlineSignatureEnabled()) {
455 temp
=_("Online Signature: Enabled");
458 temp
=_("Online Signature: Disabled");
460 ClientInfoMenu
->Append(TRAY_MENU_CLIENTINFO_ITEM
,temp
);
465 wxString temp
= CFormat(_("Uptime: %s")) % CastSecondsToHM(theStats::GetUptimeSeconds());
466 ClientInfoMenu
->Append(TRAY_MENU_CLIENTINFO_ITEM
,temp
);
469 // Number of shared files
471 wxString temp
= CFormat(_("Shared files: %d")) % theStats::GetSharedFileCount();
472 ClientInfoMenu
->Append(TRAY_MENU_CLIENTINFO_ITEM
,temp
);
475 // Number of queued clients
477 wxString temp
= CFormat(_("Queued clients: %d")) % theStats::GetWaitingUserCount();
478 ClientInfoMenu
->Append(TRAY_MENU_CLIENTINFO_ITEM
,temp
);
483 wxString temp
= CastItoXBytes( theStats::GetSessionReceivedBytes() + thePrefs::GetTotalDownloaded() );
484 temp
= CFormat(_("Total DL: %s")) % temp
;
485 ClientInfoMenu
->Append(TRAY_MENU_CLIENTINFO_ITEM
,temp
);
490 wxString temp
= CastItoXBytes( theStats::GetSessionSentBytes() + thePrefs::GetTotalUploaded() );
491 temp
= CFormat(_("Total UL: %s")) % temp
;
492 ClientInfoMenu
->Append(TRAY_MENU_CLIENTINFO_ITEM
,temp
);
495 traymenu
->Append(TRAY_MENU_CLIENTINFO
,ClientInfoMenu
->GetTitle(),ClientInfoMenu
);
498 traymenu
->AppendSeparator();
500 // Upload Speed sub-menu
501 wxMenu
* UploadSpeedMenu
= new wxMenu();
502 UploadSpeedMenu
->SetTitle(_("Upload limit"));
504 // Download Speed sub-menu
505 wxMenu
* DownloadSpeedMenu
= new wxMenu();
506 DownloadSpeedMenu
->SetTitle(_("Download limit"));
508 // Upload Speed sub-menu
510 UploadSpeedMenu
->Append(UPLOAD_ITEM1
, _("Unlimited"));
512 uint32 max_ul_speed
= thePrefs::GetMaxGraphUploadRate();
514 if ( max_ul_speed
== UNLIMITED
) {
517 else if ( max_ul_speed
< 10 ) {
521 for ( int i
= 0; i
< 5; i
++ ) {
522 unsigned int tempspeed
= (unsigned int)((double)max_ul_speed
/ 5) * (5 - i
);
523 wxString temp
= wxString::Format(wxT("%u kB/s"), tempspeed
);
524 UploadSpeedMenu
->Append((int)UPLOAD_ITEM1
+i
+1,temp
);
527 traymenu
->Append(0,UploadSpeedMenu
->GetTitle(),UploadSpeedMenu
);
529 // Download Speed sub-menu
531 DownloadSpeedMenu
->Append(DOWNLOAD_ITEM1
, _("Unlimited"));
533 uint32 max_dl_speed
= thePrefs::GetMaxGraphDownloadRate();
535 if ( max_dl_speed
== UNLIMITED
) {
538 else if ( max_dl_speed
< 10 ) {
542 for ( int i
= 0; i
< 5; i
++ ) {
543 unsigned int tempspeed
= (unsigned int)((double)max_dl_speed
/ 5) * (5 - i
);
544 wxString temp
= wxString::Format(wxT("%d kB/s"), tempspeed
);
545 DownloadSpeedMenu
->Append((int)DOWNLOAD_ITEM1
+i
+1,temp
);
549 traymenu
->Append(0,DownloadSpeedMenu
->GetTitle(),DownloadSpeedMenu
);
551 traymenu
->AppendSeparator();
553 if (theApp
->IsConnected()) {
554 //Disconnection Speed item
555 traymenu
->Append(TRAY_MENU_DISCONNECT
, _("Disconnect"));
558 traymenu
->Append(TRAY_MENU_CONNECT
, _("Connect"));
562 traymenu
->AppendSeparator();
564 if (theApp
->amuledlg
->IsShown()) {
566 traymenu
->Append(TRAY_MENU_HIDE
, _("Hide aMule"));
569 traymenu
->Append(TRAY_MENU_SHOW
, _("Show aMule"));
573 traymenu
->AppendSeparator();
576 traymenu
->Append(TRAY_MENU_EXIT
, _("Exit"));
581 void CMuleTrayIcon::SwitchShow(wxTaskBarIconEvent
&)
583 theApp
->amuledlg
->DoIconize(theApp
->amuledlg
->IsShown());
585 // File_checked_for_headers