Upstream tarball 9882
[amule.git] / src / ChatSelector.cpp
blob3c97614eac25f36220a803e96a725c1c186509f4
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 if (theApp->clientlist->SendChatMessage(ci->m_client_id, message)) {
246 ci->AddText( thePrefs::GetUserNick(), COLOR_GREEN, false );
247 ci->AddText( wxT(": ") + message, COLOR_BLACK );
248 } else {
249 ci->AddText( _("*** Connecting to Client ***"), COLOR_RED );
251 #endif
253 return true;
256 //#warning Creteil? I know you are here Creteil... follow the white rabbit.
257 /* Madcat - knock knock ...
258 ,-.,-.
259 \ \\ \
260 \ \\_\
262 __| a a|
263 /` `'. = y)=
264 / `"`}
265 _| \ }
266 { \ ), //
267 '-', /__\ ( (
268 jgs (______)\_)_)
272 void CChatSelector::ConnectionResult(bool success, const wxString& message, uint64 id)
274 CChatSession* ci = GetPageByClientID(id);
275 if ( !ci ) {
276 return;
279 if ( !success ) {
280 ci->AddText( _("*** Failed to Connect to client / Connection lost ***"), COLOR_RED );
282 ci->m_active = false;
283 } else {
284 // Kry - Woops, fix for the everlasting void message sending.
285 if ( !message.IsEmpty() ) {
286 ci->AddText( _("*** Connected to Client ***"), COLOR_RED );
287 ci->AddText( thePrefs::GetUserNick(), COLOR_GREEN, false );
288 ci->AddText( wxT(": ") + message, COLOR_BLACK );
294 void CChatSelector::EndSession(uint64 client_id)
296 int usedtab;
297 if (client_id) {
298 usedtab = GetTabByClientID(client_id);
299 } else {
300 usedtab = GetSelection();
303 if (usedtab == -1) {
304 return;
307 DeletePage(usedtab);
311 // Refresh the tab assosiated with a client
312 void CChatSelector::RefreshFriend(uint64 toupdate_id, const wxString& new_name)
314 wxASSERT( toupdate_id );
316 int tab = GetTabByClientID(toupdate_id);
318 if (tab != -1) {
319 // This client has a tab.
320 SetPageText(tab,new_name);
321 } else {
322 // This client has no tab (friend disconnecting, etc)
323 // Nothing to be done here.
328 void CChatSelector::ShowCaptchaResult(uint64 id, bool ok)
330 CChatSession* ci = GetPageByClientID(id);
331 if (ci) {
332 ci->AddText(ok
333 ? _("*** You have passed the captcha check and the user has received your message. ***")
334 : _("*** Your response to the captcha was wrong and your message has been ignored. You can request a new captcha by sending a new message. ***"),
335 COLOR_RED );
340 CUpDownClient* CChatSelector::GetCurrentClient() const
342 #ifdef CLIENT_GUI
343 return NULL;
344 #else
345 // Get the chat session associated with the active tab
346 CChatSession* ci = (CChatSession*)GetPage(GetSelection());
348 // Get the client that the session is open to
349 return ci ? theApp->clientlist->FindClientByIP(IP_FROM_GUI_ID(ci->m_client_id), PORT_FROM_GUI_ID(ci->m_client_id))
350 : NULL;
351 #endif
354 // File_checked_for_headers