1// 2// This file is part of the aMule Project. 3// 4// Copyright (c) 2004-2011 aMule Team ( admin@amule.org / http://www.amule.org ) 5// 6// Any parts of this program derived from the xMule, lMule or eMule project, 7// or contributed by third-party developers are copyrighted by their 8// respective authors. 9// 10// This program is free software; you can redistribute it and/or modify 11// it under the terms of the GNU General Public License as published by 12// the Free Software Foundation; either version 2 of the License, or 13// (at your option) any later version. 14// 15// This program is distributed in the hope that it will be useful, 16// but WITHOUT ANY WARRANTY; without even the implied warranty of 17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18// GNU General Public License for more details. 19// 20// You should have received a copy of the GNU General Public License 21// along with this program; if not, write to the Free Software 22// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 23// 24 25#include "amule.h" // Interface declarations. 26 27#include <common/EventIDs.h> 28#include <common/ClientVersion.h> 29 30#include <wx/clipbrd.h> // Needed for wxClipBoard 31#include <wx/tokenzr.h> // Needed for wxStringTokenizer 32 33#include "SharedFilesWnd.h" // Needed for CSharedFilesWnd 34#include "Timer.h" // Needed for CTimer 35#include "PartFile.h" // Needed for CPartFile 36 37#include "muuli_wdr.h" // Needed for IDs 38#include "amuleDlg.h" // Needed for CamuleDlg 39#include "PartFileConvert.h" 40#include "ThreadTasks.h" 41#include "Logger.h" // Needed for EVT_MULE_LOGGING 42#include "GuiEvents.h" // Needed for EVT_MULE_NOTIFY 43 44#ifdef __WXMAC__ 45 #include <CoreFoundation/CFBundle.h> // Do_not_auto_remove 46 #include <ApplicationServices/ApplicationServices.h> // For LSRegisterURL // Do_not_auto_remove 47#endif 48 49#ifndef CLIENT_GUI 50#include "InternalEvents.h" // Needed for wxEVT_* 51 52BEGIN_EVENT_TABLE(CamuleGuiApp, wxApp) 53 54 // Socket handlers 55 // Listen Socket 56 EVT_SOCKET(ID_LISTENSOCKET_EVENT, CamuleGuiApp::ListenSocketHandler) 57 58 // UDP Socket (servers) 59 EVT_SOCKET(ID_SERVERUDPSOCKET_EVENT, CamuleGuiApp::UDPSocketHandler) 60 // UDP Socket (clients) 61 EVT_SOCKET(ID_CLIENTUDPSOCKET_EVENT, CamuleGuiApp::UDPSocketHandler) 62 63 // Socket timers (TCP + UDP) 64 EVT_MULE_TIMER(ID_SERVER_RETRY_TIMER_EVENT, CamuleGuiApp::OnTCPTimer) 65 66 // Core timer 67 EVT_MULE_TIMER(ID_CORE_TIMER_EVENT, CamuleGuiApp::OnCoreTimer) 68 69 EVT_MULE_NOTIFY(CamuleGuiApp::OnNotifyEvent) 70 71 // Async dns handling 72 EVT_MULE_INTERNAL(wxEVT_CORE_UDP_DNS_DONE, -1, CamuleGuiApp::OnUDPDnsDone) 73 74 EVT_MULE_INTERNAL(wxEVT_CORE_SOURCE_DNS_DONE, -1, CamuleGuiApp::OnSourceDnsDone) 75 76 EVT_MULE_INTERNAL(wxEVT_CORE_SERVER_DNS_DONE, -1, CamuleGuiApp::OnServerDnsDone) 77 78 // Hash ended notifier 79 EVT_MULE_HASHING(CamuleGuiApp::OnFinishedHashing) 80 EVT_MULE_AICH_HASHING(CamuleGuiApp::OnFinishedAICHHashing) 81 82 // File completion ended notifier 83 EVT_MULE_FILE_COMPLETED(CamuleGuiApp::OnFinishedCompletion) 84 85 // HTTPDownload finished 86 EVT_MULE_INTERNAL(wxEVT_CORE_FINISHED_HTTP_DOWNLOAD, -1, CamuleGuiApp::OnFinishedHTTPDownload) 87 88 // Disk space preallocation finished 89 EVT_MULE_ALLOC_FINISHED(CamuleGuiApp::OnFinishedAllocation) 90END_EVENT_TABLE() 91 92 93IMPLEMENT_APP(CamuleGuiApp) 94 95#endif // CLIENT_GUI 96 97CamuleGuiBase::CamuleGuiBase() 98{ 99 amuledlg = NULL; 100 m_FileDetailDialogActive = 0; 101} 102 103 104CamuleGuiBase::~CamuleGuiBase() 105{ 106 #ifndef CLIENT_GUI 107 CPartFileConvert::StopThread(); 108 #endif 109} 110 111 112int CamuleGuiBase::ShowAlert(wxString msg, wxString title, int flags) 113{ 114 return wxMessageBox(msg, title, flags); 115} 116 117 118int CamuleGuiBase::InitGui(bool geometry_enabled, wxString &geom_string) 119{ 120 // Standard size is 800x600 at position (0,0) 121 int geometry_x = 0; 122 int geometry_y = 0; 123 unsigned int geometry_width = 800; 124 unsigned int geometry_height = 600; 125 126 if ( geometry_enabled ) { 127 // I plan on moving this to a separate function, as it just clutters up OnInit() 128 /* 129 This implementation might work with mac, provided that the 130 SetSize() function works as expected. 131 */ 132 133 // Remove possible prefix 134 if ( geom_string.GetChar(0) == '=' ) { 135 geom_string.Remove( 0, 1 ); 136 } 137 138 // Stupid ToLong functions forces me to use longs =( 139 long width = geometry_width; 140 long height = geometry_height; 141 142 // Get the avilable display area 143 wxRect display = wxGetClientDisplayRect(); 144 145 // We want to place aMule inside the client area by default 146 long x = display.x; 147 long y = display.y; 148 149 // Tokenize the string 150 wxStringTokenizer tokens(geom_string, wxT("xX+-")); 151 152 // First part: Program width 153 if ( tokens.GetNextToken().ToLong( &width ) ) { 154 wxString prefix = geom_string[ tokens.GetPosition() - 1 ]; 155 if ( prefix == wxT("x") || prefix == wxT("X") ) { 156 // Second part: Program height 157 if ( tokens.GetNextToken().ToLong( &height ) ) { 158 prefix = geom_string[ tokens.GetPosition() - 1 ]; 159 if ( prefix == wxT("+") || prefix == wxT("-") ) { 160 // Third part: X-Offset 161 if ( tokens.GetNextToken().ToLong( &x ) ) { 162 if ( prefix == wxT("-") ) 163 x = display.GetRight() - ( width + x ); 164 prefix = geom_string[ tokens.GetPosition() - 1 ]; 165 if ( prefix == wxT("+") || prefix == wxT("-") ) { 166 // Fourth part: Y-Offset 167 if ( tokens.GetNextToken().ToLong( &y ) ) { 168 if ( prefix == wxT("-") ) 169 y = display.GetBottom() - ( height + y ); 170 } 171 } 172 } 173 } 174 // We need at least height and width to override default geometry 175 geometry_enabled = true; 176 geometry_x = x; 177 geometry_y = y; 178 geometry_width = width; 179 geometry_height = height; 180 } 181 } 182 } 183 } 184 185 ResetTitle(); 186 187 // Should default/last-used position be overridden? 188 if ( geometry_enabled ) { 189 amuledlg = new CamuleDlg(NULL, m_FrameTitle, 190 wxPoint(geometry_x,geometry_y), 191 wxSize( geometry_width, geometry_height - 58 )); 192 } else { 193 amuledlg = new CamuleDlg(NULL, m_FrameTitle); 194 } 195 196 return 0; 197} 198 199// Sets m_FrameTitle 200void CamuleGuiBase::ResetTitle() 201{ 202#ifdef SVNDATE 203 #ifdef CLIENT_GUI 204 m_FrameTitle = CFormat(wxT("aMule remote control %s %s")) % wxT( VERSION ) % wxT( SVNDATE ); 205 #else 206 m_FrameTitle = CFormat(wxT("aMule %s %s")) % wxT( VERSION ) % wxT( SVNDATE ); 207 #endif 208#else 209 #ifdef CLIENT_GUI 210 m_FrameTitle = _("aMule remote control"); 211 #else 212 m_FrameTitle = _("aMule"); 213 #endif 214 215 if (thePrefs::ShowVersionOnTitle()) { 216 m_FrameTitle += wxT(' '); 217 m_FrameTitle += wxT( VERSION ); 218 } 219#endif 220} 221 222 223// Sets the contents of the clipboard. Prior content erased. 224bool CamuleGuiBase::CopyTextToClipboard(wxString strText) 225{ 226 bool ClipBoardOpen = wxTheClipboard->Open(); 227 if (ClipBoardOpen) { 228 wxTheClipboard->UsePrimarySelection(false); 229 wxTheClipboard->SetData(new wxTextDataObject(strText)); 230 wxTheClipboard->Close(); 231 } 232 233 return ClipBoardOpen; 234} 235 236 237void CamuleGuiBase::AddGuiLogLine(const wxString& line) 238{ 239 if (amuledlg) { 240 while ( !m_logLines.empty() ) { 241 amuledlg->AddLogLine(m_logLines.front()); 242 m_logLines.pop_front(); 243 } 244 amuledlg->AddLogLine(line); 245 } else { 246 m_logLines.push_back(line); 247 } 248} 249 250 251#ifndef CLIENT_GUI 252 253int CamuleGuiApp::InitGui(bool geometry_enable, wxString &geometry_string) 254{ 255 CamuleGuiBase::InitGui(geometry_enable, geometry_string); 256 SetTopWindow(amuledlg); 257 return 0; 258} 259 260 261int CamuleGuiApp::ShowAlert(wxString msg, wxString title, int flags) 262{ 263 return CamuleGuiBase::ShowAlert(msg, title, flags); 264} 265 266 267int CamuleGuiApp::OnExit() 268{ 269 delete core_timer; 270 271 return CamuleApp::OnExit(); 272} 273 274 275void CamuleGuiApp::ShutDown(wxCloseEvent &WXUNUSED(evt)) 276{ 277 amuledlg->DlgShutDown(); 278 amuledlg->Destroy(); 279 CamuleApp::ShutDown(); 280} 281 282 283bool CamuleGuiApp::OnInit() 284{ 285 amuledlg = NULL; 286 287 if ( !CamuleApp::OnInit() ) { 288 return false; 289 } 290 291 // Create the Core timer 292 core_timer = new CTimer(this,ID_CORE_TIMER_EVENT); 293 if (!core_timer) { 294 AddLogLineCS(_("Fatal Error: Failed to create Core Timer")); 295 OnExit(); 296 } 297 298 // Start the Core and Gui timers 299 300 // Note: wxTimer can be off by more than 10% !!! 301 // In addition to the systematic error introduced by wxTimer, we are losing 302 // timer cycles due to high CPU load. I've observed about 0.5% random loss of cycles under 303 // low load, and more than 6% lost cycles with heavy download traffic and/or other tasks 304 // in the system, such as a video player or a VMware virtual machine. 305 // The upload queue process loop has now been rewritten to compensate for timer errors. 306 // When adding functionality, assume that the timer is only approximately correct; 307 // for measurements, always use the system clock [::GetTickCount()]. 308 core_timer->Start(CORE_TIMER_PERIOD); 309 amuledlg->StartGuiTimer(); 310 311#ifdef __WXMAC__ 312 // This tells the OS to notice the ed2kHelperScript.app inside aMule.app. 313 // ed2kHelperScript.app describes itself (Info.plist) as handling ed2k URLs. 314 // So, from then on the OS will know to pass ed2k URLs to the helper app. 315 CFURLRef ed2kHelperUrl = CFBundleCopyAuxiliaryExecutableURL( 316 CFBundleGetMainBundle(), CFSTR("ed2kHelperScript.app")); 317 if (ed2kHelperUrl) { 318 LSRegisterURL(ed2kHelperUrl, true); 319 CFRelease(ed2kHelperUrl); 320 } 321#endif 322 323 return true; 324} 325 326 327wxString CamuleGuiApp::GetLog(bool reset) 328{ 329 if ( reset ) { 330 amuledlg->ResetLog(ID_LOGVIEW); 331 } 332 return CamuleApp::GetLog(reset); 333} 334 335 336wxString CamuleGuiApp::GetServerLog(bool reset) 337{ 338 if ( reset ) { 339 amuledlg->ResetLog(ID_SERVERINFO); 340 } 341 return CamuleApp::GetServerLog(reset); 342} 343 344 345void CamuleGuiApp::AddServerMessageLine(wxString &msg) 346{ 347 amuledlg->AddServerMessageLine(msg); 348 CamuleApp::AddServerMessageLine(msg); 349} 350 351#endif /* CLIENT_GUI */ 352// File_checked_for_headers 353