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 
BEGIN_EVENT_TABLE(CChatWnd,wxPanel)43 BEGIN_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)
55 END_EVENT_TABLE()
56 
57 
58 CChatWnd::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 
StartSession(CFriend * friend_client,bool setfocus)72 void 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 
OnNMRclickChatTab(wxMouseEvent & evt)87 void 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 
OnPopupClose(wxCommandEvent & WXUNUSED (evt))123 void CChatWnd::OnPopupClose(wxCommandEvent& WXUNUSED(evt))
124 {
125 	chatselector->DeletePage(chatselector->GetSelection());
126 }
127 
128 
OnPopupCloseAll(wxCommandEvent & WXUNUSED (evt))129 void CChatWnd::OnPopupCloseAll(wxCommandEvent& WXUNUSED(evt))
130 {
131 	chatselector->DeleteAllPages();
132 }
133 
134 
OnPopupCloseOthers(wxCommandEvent & WXUNUSED (evt))135 void 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 
OnAddFriend(wxCommandEvent & WXUNUSED (evt))146 void 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 
OnBnClickedCsend(wxCommandEvent & WXUNUSED (evt))158 void CChatWnd::OnBnClickedCsend(wxCommandEvent& WXUNUSED(evt))
159 {
160 	wxString message = CastChild(IDC_CMESSAGE, wxTextCtrl)->GetValue();
161 
162 	SendMessage(message);
163 }
164 
165 
OnBnClickedCclose(wxCommandEvent & WXUNUSED (evt))166 void CChatWnd::OnBnClickedCclose(wxCommandEvent& WXUNUSED(evt))
167 {
168 	chatselector->EndSession();
169 }
170 
171 
OnAllPagesClosed(wxNotebookEvent & WXUNUSED (evt))172 void CChatWnd::OnAllPagesClosed(wxNotebookEvent& WXUNUSED(evt))
173 {
174 	CastChild(IDC_CMESSAGE, wxTextCtrl)->Clear();
175 	// Check to disable the window controls
176 	CheckNewButtonsState();
177 }
178 
179 
UpdateFriend(CFriend * toupdate)180 void 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 
RemoveFriend(CFriend * todel)192 void CChatWnd::RemoveFriend(CFriend* todel)
193 {
194 	chatselector->EndSession(GUI_ID(todel->GetIP(), todel->GetPort()));
195 	friendlistctrl->RemoveFriend(todel);
196 }
197 
198 
ProcessMessage(uint64 sender,const wxString & message)199 void 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 
ConnectionResult(bool success,const wxString & message,uint64 id)211 void CChatWnd::ConnectionResult(bool success, const wxString& message, uint64 id)
212 {
213 	chatselector->ConnectionResult(success, message, id);
214 }
215 
216 
SendMessage(const wxString & message,const wxString & client_name,uint64 to_id)217 void 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 
CheckNewButtonsState()230 void 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 
IsIdValid(uint64 id)253 bool CChatWnd::IsIdValid(uint64 id)
254 {
255 	return chatselector->GetTabByClientID(id) >= 0;
256 }
257 
258 
ShowCaptchaResult(uint64 id,bool ok)259 void CChatWnd::ShowCaptchaResult(uint64 id, bool ok)
260 {
261 	chatselector->ShowCaptchaResult(id, ok);
262 }
263 
EndSession(uint64 id)264 void CChatWnd::EndSession(uint64 id)
265 {
266 	chatselector->EndSession(id);
267 }
268 
269 // File_checked_for_headers
270