Upstream tarball 9440
[amule.git] / src / ChatSelector.cpp
blobc027ae24a4c7985b41b2a541f5b4f576fb6ba586
1 //
2 // This file is part of the aMule Project.
3 //
4 // Copyright (c) 2003-2008 aMule Team ( admin@amule.org / http://www.amule.org )
5 // Copyright (c) 2002-2008 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.
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.
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
26 #include <wx/tokenzr.h>
27 #include <wx/imaglist.h>
29 #include "pixmaps/chat.ico.xpm"
30 #include "ChatSelector.h" // Interface declarations
31 #include "Preferences.h" // Needed for CPreferences
32 #include "amule.h" // Needed for theApp
33 #include "updownclient.h" // Needed for CUpDownClient
34 #include "OtherFunctions.h"
35 #include "muuli_wdr.h" // Needed for amuleSpecial
36 #include "UserEvents.h"
38 //#warning Needed while not ported
39 #include "ClientList.h"
40 #include <common/Format.h> // Needed for CFormat
43 // Default colors,
44 #define COLOR_BLACK wxTextAttr( wxColor( 0, 0, 0 ) )
45 #define COLOR_BLUE wxTextAttr( wxColor( 0, 0, 255 ) )
46 #define COLOR_GREEN wxTextAttr( wxColor( 0, 102, 0 ) )
47 #define COLOR_RED wxTextAttr( wxColor( 255, 0, 0 ) )
49 CChatSession::CChatSession(wxWindow* parent, wxWindowID id, const wxString& value, const wxPoint& pos, const wxSize& size, long style, const wxValidator& validator, const wxString& name)
50 : CMuleTextCtrl( parent, id, value, pos, size, style | wxTE_READONLY | wxTE_RICH | wxTE_MULTILINE, validator, name )
52 m_client_id = 0;
53 m_active = false;
54 SetBackgroundColour(*wxWHITE);
58 CChatSession::~CChatSession()
60 //#warning EC NEEDED
61 #ifndef CLIENT_GUI
62 theApp->clientlist->SetChatState(m_client_id,MS_NONE);
63 #endif
67 void CChatSession::AddText(const wxString& text, const wxTextAttr& style, bool newline)
69 // Split multi-line messages into individual lines
70 wxStringTokenizer tokens( text, wxT("\n") );
72 while ( tokens.HasMoreTokens() ) {
73 // Check if we should add a time-stamp
74 if ( GetNumberOfLines() > 1 ) {
75 // Check if the last line ended with a newline
76 wxString line = GetLineText( GetNumberOfLines() - 1 );
77 if ( line.IsEmpty() ) {
78 SetDefaultStyle( COLOR_BLACK );
80 AppendText( wxT(" [") + wxDateTime::Now().FormatISOTime() + wxT("] ") );
84 SetDefaultStyle(style);
86 AppendText( tokens.GetNextToken() );
88 // Only add newlines after the last line if it is desired
89 if ( tokens.HasMoreTokens() || newline ) {
90 AppendText( wxT("\n") );
98 CChatSelector::CChatSelector(wxWindow* parent, wxWindowID id, const wxPoint& pos, wxSize siz, long style)
99 : CMuleNotebook(parent, id, pos, siz, style)
101 wxImageList* imagelist = new wxImageList(16,16);
103 // Chat icon -- default state
104 imagelist->Add(wxBitmap(chat_ico_xpm));
105 // Close icon -- on mouseover
106 imagelist->Add(amuleSpecial(4));
108 AssignImageList(imagelist);
111 CChatSession* CChatSelector::StartSession(uint64 client_id, const wxString& client_name, bool show)
113 // Check to see if we've already opened a session for this user
114 if ( GetPageByClientID( client_id ) ) {
115 if ( show ) {
116 SetSelection( GetTabByClientID( client_id ) );
119 return NULL;
122 CChatSession* chatsession = new CChatSession(this);
124 chatsession->m_client_id = client_id;
126 wxString text;
127 text = wxT(" *** ") + (CFormat(_("Chat-Session Started: %s (%s:%u) - %s %s"))
128 % client_name
129 % Uint32toStringIP(IP_FROM_GUI_ID(client_id))
130 % PORT_FROM_GUI_ID(client_id)
131 % wxDateTime::Now().FormatISODate()
132 % wxDateTime::Now().FormatISOTime());
134 chatsession->AddText( text, COLOR_RED );
135 AddPage(chatsession, client_name, show, 0);
137 CUserEvents::ProcessEvent(CUserEvents::NewChatSession, &client_name);
139 return chatsession;
143 CChatSession* CChatSelector::GetPageByClientID(uint64 client_id)
145 for ( unsigned int i = 0; i < (unsigned int ) GetPageCount(); i++ ) {
146 CChatSession* page = (CChatSession*)GetPage( i );
148 if( page->m_client_id == client_id ) {
149 return page;
153 return NULL;
157 int CChatSelector::GetTabByClientID(uint64 client_id)
159 for ( unsigned int i = 0; i < (unsigned int) GetPageCount(); i++ ) {
160 CChatSession* page = (CChatSession*)GetPage( i );
162 if( page->m_client_id == client_id ) {
163 return i;
167 return -1;
171 bool CChatSelector::ProcessMessage(uint64 sender_id, const wxString& message)
173 CChatSession* session = GetPageByClientID(sender_id);
175 // Try to get the name (core sent it?)
176 int separator = message.Find(wxT("|"));
177 wxString client_name;
178 wxString client_message;
179 if (separator != -1) {
180 client_name = message.Left(separator);
181 client_message = message.Mid(separator+1);
182 } else {
183 // No need to define client_name. If needed, will be build on tab creation.
184 client_message = message;
187 bool newtab = !session;
189 if ( !session ) {
190 // This must be a mesage from a client that is not already chatting
191 if (client_name.IsEmpty()) {
192 // Core did not send us the name.
193 // This must NOT happen.
194 // Build a client name based on the ID
195 uint32 ip = IP_FROM_GUI_ID(sender_id);
196 client_name = wxString::Format(wxT("IP: %u.%u.%u.%u Port: %u"),(uint8)ip,(uint8)(ip>>8),(uint8)(ip>>16),(uint8)(ip>>24),(unsigned)PORT_FROM_GUI_ID(sender_id));
199 session = StartSession( sender_id, client_name, true );
202 // Other client connected after disconnection or a new session
203 if ( !session->m_active ) {
204 session->m_active = true;
206 session->AddText( _("*** Connected to Client ***"), COLOR_RED );
209 // Page text is client name
210 session->AddText( GetPageText(GetTabByClientID(sender_id)), COLOR_BLUE, false );
211 session->AddText( wxT(": ") + client_message, COLOR_BLACK );
213 return newtab;
216 bool CChatSelector::SendMessage( const wxString& message, const wxString& client_name, uint64 to_id )
218 // Dont let the user send empty messages
219 // This is also a user-fix for people who mash the enter-key ...
220 if ( message.IsEmpty() ) {
221 return false;
224 if (to_id) {
225 // Checks if there's a page with this client, and selects it or creates it
226 StartSession(to_id, client_name, true);
229 int usedtab = GetSelection();
230 // Workaround for a problem with wxNotebook, where an invalid selection is returned
231 if (usedtab >= (int)GetPageCount()) {
232 usedtab = GetPageCount() - 1;
234 if (usedtab == -1) {
235 return false;
238 CChatSession* ci = (CChatSession*)GetPage( usedtab );
240 ci->m_active = true;
242 //#warning EC needed here.
244 #ifndef CLIENT_GUI
245 CUpDownClient* client = theApp->clientlist->FindClientByIP(IP_FROM_GUI_ID(ci->m_client_id), PORT_FROM_GUI_ID(ci->m_client_id));
247 if (!client) {
248 wxFAIL;
249 } else if (client->GetChatCaptchaState() == CA_CAPTCHARECV) {
250 client->SetChatCaptchaState(CA_SOLUTIONSENT);
251 } else if (client->GetChatCaptchaState() == CA_SOLUTIONSENT) {
252 wxFAIL; // we responsed to a captcha but didn't heard from the client afterwards - hopefully its just lag and this message will get through
253 } else {
254 client->SetChatCaptchaState(CA_ACCEPTING);
256 if (theApp->clientlist->SendMessage(ci->m_client_id, message)) {
257 ci->AddText( thePrefs::GetUserNick(), COLOR_GREEN, false );
258 ci->AddText( wxT(": ") + message, COLOR_BLACK );
259 } else {
260 ci->AddText( _("*** Connecting to Client ***"), COLOR_RED );
262 #endif
264 return true;
267 //#warning Creteil? I know you are here Creteil... follow the white rabbit.
268 /* Madcat - knock knock ...
269 ,-.,-.
270 \ \\ \
271 \ \\_\
273 __| a a|
274 /` `'. = y)=
275 / `"`}
276 _| \ }
277 { \ ), //
278 '-', /__\ ( (
279 jgs (______)\_)_)
283 void CChatSelector::ConnectionResult(bool success, const wxString& message, uint64 id)
285 CChatSession* ci = GetPageByClientID(id);
286 if ( !ci ) {
287 return;
290 if ( !success ) {
291 ci->AddText( _("*** Failed to Connect to client / Connection lost ***"), COLOR_RED );
293 ci->m_active = false;
294 } else {
295 // Kry - Woops, fix for the everlasting void message sending.
296 if ( !message.IsEmpty() ) {
297 ci->AddText( _("*** Connected to Client ***"), COLOR_RED );
298 ci->AddText( thePrefs::GetUserNick(), COLOR_GREEN, false );
299 ci->AddText( wxT(": ") + message, COLOR_BLACK );
305 void CChatSelector::EndSession(uint64 client_id)
307 int usedtab;
308 if (client_id) {
309 usedtab = GetTabByClientID(client_id);
310 } else {
311 usedtab = GetSelection();
314 if (usedtab == -1) {
315 return;
318 DeletePage(usedtab);
322 // Refresh the tab assosiated with a client
323 void CChatSelector::RefreshFriend(uint64 toupdate_id, const wxString& new_name)
325 wxASSERT( toupdate_id );
327 int tab = GetTabByClientID(toupdate_id);
329 if (tab != -1) {
330 // This client has a tab.
331 SetPageText(tab,new_name);
332 } else {
333 // This client has no tab (friend disconnecting, etc)
334 // Nothing to be done here.
339 void CChatSelector::ShowCaptchaResult(uint64 id, bool ok)
341 CChatSession* ci = GetPageByClientID(id);
342 if (ci) {
343 ci->AddText(ok
344 ? _("*** You have passed the captcha check and the user has received your message. ***")
345 : _("*** Your response to the captcha was wrong and your message has been ignored. You can request a new captcha by sending a new message. ***"),
346 COLOR_RED );
350 // File_checked_for_headers