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