2 // This file is part of the aMule Project.
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 )
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
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.
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
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
)
54 SetBackgroundColour(*wxWHITE
);
58 CChatSession::~CChatSession()
62 theApp
->clientlist
->SetChatState(m_client_id
,MS_NONE
);
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
) ) {
116 SetSelection( GetTabByClientID( client_id
) );
122 CChatSession
* chatsession
= new CChatSession(this);
124 chatsession
->m_client_id
= client_id
;
127 text
= wxT(" *** ") + (CFormat(_("Chat-Session Started: %s (%s:%u) - %s %s"))
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
);
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
) {
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
) {
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);
183 // No need to define client_name. If needed, will be build on tab creation.
184 client_message
= message
;
187 bool newtab
= !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
);
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() ) {
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;
238 CChatSession
* ci
= (CChatSession
*)GetPage( usedtab
);
242 //#warning EC needed here.
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
);
249 ci
->AddText( _("*** Connecting to Client ***"), COLOR_RED
);
256 //#warning Creteil? I know you are here Creteil... follow the white rabbit.
257 /* Madcat - knock knock ...
272 void CChatSelector::ConnectionResult(bool success
, const wxString
& message
, uint64 id
)
274 CChatSession
* ci
= GetPageByClientID(id
);
280 ci
->AddText( _("*** Failed to Connect to client / Connection lost ***"), COLOR_RED
);
282 ci
->m_active
= false;
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
)
298 usedtab
= GetTabByClientID(client_id
);
300 usedtab
= GetSelection();
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
);
319 // This client has a tab.
320 SetPageText(tab
,new_name
);
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
);
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. ***"),
340 CUpDownClient
* CChatSelector::GetCurrentClient() const
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
))
354 // File_checked_for_headers