1// 2// This file is part of the aMule Project. 3// 4// Copyright (c) 2003-2011 aMule Team ( admin@amule.org / http://www.amule.org ) 5// Copyright (c) 2002-2011 Merkur ( devs@emule-project.net / http://www.emule-project.net ) 6// 7// Any parts of this program derived from the xMule, lMule or eMule project, 8// or contributed by third-party developers are copyrighted by their 9// respective authors. 10// 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. 15// 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. 20// 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 24// 25 26#include <common/MenuIDs.h> // IDs for the chat-popup menu 27 28#include <wx/app.h> 29 30#include "ChatWnd.h" // Interface declarations 31 32#include "amule.h" // Needed for theApp 33#include "amuleDlg.h" // Needed for CamuleDlg 34#include "ClientList.h" // Needed for CClientList 35#include "ClientRef.h" // Needed for CClientRef 36#include "FriendListCtrl.h" // Needed for CFriendListCtrl 37#include "FriendList.h" // Needed for CFriendList 38#include "Friend.h" // Needed for CFriend 39#include "ChatSelector.h" // Needed for CChatSelector 40#include "muuli_wdr.h" // Needed for messagePage 41#include "OtherFunctions.h" 42 43BEGIN_EVENT_TABLE(CChatWnd, wxPanel) 44 EVT_RIGHT_DOWN(CChatWnd::OnNMRclickChatTab) 45 46 EVT_MENU(MP_CLOSE_TAB, CChatWnd::OnPopupClose) 47 EVT_MENU(MP_CLOSE_ALL_TABS, CChatWnd::OnPopupCloseAll) 48 EVT_MENU(MP_CLOSE_OTHER_TABS, CChatWnd::OnPopupCloseOthers) 49 EVT_MENU(MP_ADDFRIEND, CChatWnd::OnAddFriend ) 50 51 EVT_TEXT_ENTER(IDC_CMESSAGE, CChatWnd::OnBnClickedCsend) 52 EVT_BUTTON(IDC_CSEND, CChatWnd::OnBnClickedCsend) 53 EVT_BUTTON(IDC_CCLOSE, CChatWnd::OnBnClickedCclose) 54 EVT_MULENOTEBOOK_ALL_PAGES_CLOSED(IDC_CHATSELECTOR, CChatWnd::OnAllPagesClosed) 55END_EVENT_TABLE() 56 57 58CChatWnd::CChatWnd(wxWindow* pParent) 59: wxPanel(pParent, -1) 60{ 61 wxSizer* content = messagePage(this, true); 62 content->Show(this, true); 63 64 chatselector = CastChild( IDC_CHATSELECTOR, CChatSelector ); 65 // We want to use our own popup menu 66 chatselector->SetPopupHandler(this); 67 m_menu = NULL; 68 69 friendlistctrl = CastChild( ID_FRIENDLIST, CFriendListCtrl ); 70} 71 72void CChatWnd::StartSession(CFriend* friend_client, bool setfocus) 73{ 74 75 if ( !friend_client->GetName().IsEmpty() ) { 76 if (setfocus) { 77 theApp->amuledlg->SetActiveDialog(CamuleDlg::DT_CHAT_WND, this); 78 } 79 chatselector->StartSession(GUI_ID(friend_client->GetIP(), friend_client->GetPort()), friend_client->GetName(), true); 80 } 81 82 // Check to enable the window controls if needed 83 CheckNewButtonsState(); 84} 85 86 87void CChatWnd::OnNMRclickChatTab(wxMouseEvent& evt) 88{ 89 // Only handle events from the chat-notebook 90 if (evt.GetEventObject() != (wxObject*)chatselector) 91 return; 92 93 if (chatselector->GetSelection() == -1) { 94 return; 95 } 96 97 // Avoid opening another menu when it's already open 98 if (m_menu == NULL) { 99 m_menu = new wxMenu(_("Chat")); 100 101 m_menu->Append(MP_CLOSE_TAB, wxString(_("Close tab"))); 102 m_menu->Append(MP_CLOSE_ALL_TABS, wxString(_("Close all tabs"))); 103 m_menu->Append(MP_CLOSE_OTHER_TABS, wxString(_("Close other tabs"))); 104 105 m_menu->AppendSeparator(); 106 107 wxMenuItem * addFriend = m_menu->Append(MP_ADDFRIEND, _("Add to Friends")); 108 109 // Disable this client if it is already a friend 110 CClientRef client; 111 if (chatselector->GetCurrentClient(client) && client.IsFriend()) { 112 addFriend->Enable(false); 113 } 114 115 PopupMenu(m_menu, evt.GetPosition()); 116 117 delete m_menu; 118 m_menu = NULL; 119 } 120} 121 122 123void CChatWnd::OnPopupClose(wxCommandEvent& WXUNUSED(evt)) 124{ 125 chatselector->DeletePage(chatselector->GetSelection()); 126} 127 128 129void CChatWnd::OnPopupCloseAll(wxCommandEvent& WXUNUSED(evt)) 130{ 131 chatselector->DeleteAllPages(); 132} 133 134 135void CChatWnd::OnPopupCloseOthers(wxCommandEvent& WXUNUSED(evt)) 136{ 137 wxNotebookPage* current = chatselector->GetPage(chatselector->GetSelection()); 138 139 for (int i = chatselector->GetPageCount() - 1; i >= 0; i--) { 140 if (current != chatselector->GetPage(i)) 141 chatselector->DeletePage( i ); 142 } 143} 144 145 146void CChatWnd::OnAddFriend(wxCommandEvent& WXUNUSED(evt)) 147{ 148 // Get the client that the session is open to 149 CClientRef client; 150 151 // Add the client as friend unless it's already a friend 152 if (chatselector->GetCurrentClient(client) && !client.IsFriend()) { 153 theApp->friendlist->AddFriend(client); 154 } 155} 156 157 158void CChatWnd::OnBnClickedCsend(wxCommandEvent& WXUNUSED(evt)) 159{ 160 wxString message = CastChild(IDC_CMESSAGE, wxTextCtrl)->GetValue(); 161 162 SendMessage(message); 163} 164 165 166void CChatWnd::OnBnClickedCclose(wxCommandEvent& WXUNUSED(evt)) 167{ 168 chatselector->EndSession(); 169} 170 171 172void CChatWnd::OnAllPagesClosed(wxNotebookEvent& WXUNUSED(evt)) 173{ 174 CastChild(IDC_CMESSAGE, wxTextCtrl)->Clear(); 175 // Check to disable the window controls 176 CheckNewButtonsState(); 177} 178 179 180void CChatWnd::UpdateFriend(CFriend* toupdate) 181{ 182 if (toupdate->GetLinkedClient().IsLinked()) { 183 chatselector->RefreshFriend(GUI_ID(toupdate->GetIP(), toupdate->GetPort()), toupdate->GetName()); 184 } else { 185 // drop Chat session 186 chatselector->EndSession(GUI_ID(toupdate->GetIP(), toupdate->GetPort())); 187 } 188 friendlistctrl->UpdateFriend(toupdate); 189} 190 191 192void CChatWnd::RemoveFriend(CFriend* todel) 193{ 194 chatselector->EndSession(GUI_ID(todel->GetIP(), todel->GetPort())); 195 friendlistctrl->RemoveFriend(todel); 196} 197 198 199void CChatWnd::ProcessMessage(uint64 sender, const wxString& message) 200{ 201 if ( !theApp->amuledlg->IsDialogVisible(CamuleDlg::DT_CHAT_WND) ) { 202 theApp->amuledlg->SetMessageBlink(true); 203 } 204 if (chatselector->ProcessMessage(sender, message)) { 205 // Check to enable the window controls if needed 206 CheckNewButtonsState(); 207 } 208} 209 210 211void CChatWnd::ConnectionResult(bool success, const wxString& message, uint64 id) 212{ 213 chatselector->ConnectionResult(success, message, id); 214} 215 216 217void CChatWnd::SendMessage(const wxString& message, const wxString& client_name, uint64 to_id) 218{ 219 220 if (chatselector->SendMessage( message, client_name, to_id )) { 221 CastChild(IDC_CMESSAGE, wxTextCtrl)->Clear(); 222 } 223 224 // Check to enable the window controls if needed 225 CheckNewButtonsState(); 226 CastChild(IDC_CMESSAGE, wxTextCtrl)->SetFocus(); 227} 228 229 230void CChatWnd::CheckNewButtonsState() 231{ 232 switch (chatselector->GetPageCount()) { 233 case 0: 234 GetParent()->FindWindow(IDC_CSEND)->Enable(false); 235 GetParent()->FindWindow(IDC_CCLOSE)->Enable(false); 236 GetParent()->FindWindow(IDC_CMESSAGE)->Enable(false); 237 break; 238 case 1: 239 GetParent()->FindWindow(IDC_CSEND)->Enable(true); 240 GetParent()->FindWindow(IDC_CCLOSE)->Enable(true); 241 GetParent()->FindWindow(IDC_CMESSAGE)->Enable(true); 242 break; 243 default: 244 // Nothing to be done here. Keep current state, which should be enabled. 245 wxASSERT(GetParent()->FindWindow(IDC_CSEND)->IsEnabled()); 246 wxASSERT(GetParent()->FindWindow(IDC_CCLOSE)->IsEnabled()); 247 wxASSERT(GetParent()->FindWindow(IDC_CMESSAGE)->IsEnabled()); 248 break; 249 } 250} 251 252 253bool CChatWnd::IsIdValid(uint64 id) 254{ 255 return chatselector->GetTabByClientID(id) >= 0; 256} 257 258 259void CChatWnd::ShowCaptchaResult(uint64 id, bool ok) 260{ 261 chatselector->ShowCaptchaResult(id, ok); 262} 263 264void CChatWnd::EndSession(uint64 id) 265{ 266 chatselector->EndSession(id); 267} 268 269// File_checked_for_headers 270