2 // This file is part of the aMule Project.
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 )
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>
28 #include <wx/datetime.h>
30 #include "pixmaps/chat.ico.xpm"
31 #include "ChatSelector.h" // Interface declarations
32 #include "Preferences.h" // Needed for CPreferences
33 #include "amule.h" // Needed for theApp
34 #include "ClientRef.h" // Needed for CClientRef
35 #include "OtherFunctions.h"
36 #include "muuli_wdr.h" // Needed for amuleSpecial
37 #include "UserEvents.h"
38 #include "Constants.h" // Needed for MS_NONE
40 //#warning Needed while not ported
41 #include "ClientList.h"
42 #include <common/Format.h> // Needed for CFormat
46 #define COLOR_BLACK wxTextAttr( wxColor( 0, 0, 0 ) )
47 #define COLOR_BLUE wxTextAttr( wxColor( 0, 0, 255 ) )
48 #define COLOR_GREEN wxTextAttr( wxColor( 0, 102, 0 ) )
49 #define COLOR_RED wxTextAttr( wxColor( 255, 0, 0 ) )
51 CChatSession::CChatSession(wxWindow
* parent
, wxWindowID id
, const wxString
& value
, const wxPoint
& pos
, const wxSize
& size
, long style
, const wxValidator
& validator
, const wxString
& name
)
52 : CMuleTextCtrl( parent
, id
, value
, pos
, size
, style
| wxTE_READONLY
| wxTE_RICH
| wxTE_MULTILINE
, validator
, name
)
56 SetBackgroundColour(*wxWHITE
);
60 CChatSession::~CChatSession()
64 theApp
->clientlist
->SetChatState(m_client_id
,MS_NONE
);
69 void CChatSession::AddText(const wxString
& text
, const wxTextAttr
& style
, bool newline
)
71 // Split multi-line messages into individual lines
72 wxStringTokenizer
tokens( text
, wxT("\n") );
74 while ( tokens
.HasMoreTokens() ) {
75 // Check if we should add a time-stamp
76 if ( GetNumberOfLines() > 1 ) {
77 // Check if the last line ended with a newline
78 wxString line
= GetLineText( GetNumberOfLines() - 1 );
79 if ( line
.IsEmpty() ) {
80 SetDefaultStyle( COLOR_BLACK
);
82 AppendText( wxT(" [") + wxDateTime::Now().FormatISOTime() + wxT("] ") );
86 SetDefaultStyle(style
);
88 AppendText( tokens
.GetNextToken() );
90 // Only add newlines after the last line if it is desired
91 if ( tokens
.HasMoreTokens() || newline
) {
92 AppendText( wxT("\n") );
100 CChatSelector::CChatSelector(wxWindow
* parent
, wxWindowID id
, const wxPoint
& pos
, wxSize siz
, long style
)
101 : CMuleNotebook(parent
, id
, pos
, siz
, style
)
103 wxImageList
* imagelist
= new wxImageList(16,16);
105 // Chat icon -- default state
106 imagelist
->Add(wxBitmap(chat_ico_xpm
));
107 // Close icon -- on mouseover
108 imagelist
->Add(amuleSpecial(4));
110 AssignImageList(imagelist
);
113 CChatSession
* CChatSelector::StartSession(uint64 client_id
, const wxString
& client_name
, bool show
)
115 // Check to see if we've already opened a session for this user
116 if ( GetPageByClientID( client_id
) ) {
118 SetSelection( GetTabByClientID( client_id
) );
124 CChatSession
* chatsession
= new CChatSession(this);
126 chatsession
->m_client_id
= client_id
;
129 text
= wxT(" *** ") + (CFormat(_("Chat-Session Started: %s (%s:%u) - %s %s"))
131 % Uint32toStringIP(IP_FROM_GUI_ID(client_id
))
132 % PORT_FROM_GUI_ID(client_id
)
133 % wxDateTime::Now().FormatISODate()
134 % wxDateTime::Now().FormatISOTime());
136 chatsession
->AddText( text
, COLOR_RED
);
137 AddPage(chatsession
, client_name
, show
, 0);
139 CUserEvents::ProcessEvent(CUserEvents::NewChatSession
, &client_name
);
145 CChatSession
* CChatSelector::GetPageByClientID(uint64 client_id
)
147 for ( unsigned int i
= 0; i
< (unsigned int ) GetPageCount(); i
++ ) {
148 CChatSession
* page
= static_cast<CChatSession
*>(GetPage(i
));
150 if( page
->m_client_id
== client_id
) {
159 int CChatSelector::GetTabByClientID(uint64 client_id
)
161 for ( unsigned int i
= 0; i
< (unsigned int) GetPageCount(); i
++ ) {
162 CChatSession
* page
= static_cast<CChatSession
*>(GetPage(i
));
164 if( page
->m_client_id
== client_id
) {
173 bool CChatSelector::ProcessMessage(uint64 sender_id
, const wxString
& message
)
175 CChatSession
* session
= GetPageByClientID(sender_id
);
177 // Try to get the name (core sent it?)
178 int separator
= message
.Find(wxT("|"));
179 wxString client_name
;
180 wxString client_message
;
181 if (separator
!= -1) {
182 client_name
= message
.Left(separator
);
183 client_message
= message
.Mid(separator
+1);
185 // No need to define client_name. If needed, will be build on tab creation.
186 client_message
= message
;
189 bool newtab
= !session
;
192 // This must be a mesage from a client that is not already chatting
193 if (client_name
.IsEmpty()) {
194 // Core did not send us the name.
195 // This must NOT happen.
196 // Build a client name based on the ID
197 uint32 ip
= IP_FROM_GUI_ID(sender_id
);
198 client_name
= CFormat(wxT("IP: %s Port: %u")) % Uint32toStringIP(ip
) % PORT_FROM_GUI_ID(sender_id
);
201 session
= StartSession( sender_id
, client_name
, true );
204 // Other client connected after disconnection or a new session
205 if ( !session
->m_active
) {
206 session
->m_active
= true;
208 session
->AddText( _("*** Connected to Client ***"), COLOR_RED
);
211 // Page text is client name
212 session
->AddText( GetPageText(GetTabByClientID(sender_id
)), COLOR_BLUE
, false );
213 session
->AddText( wxT(": ") + client_message
, COLOR_BLACK
);
218 bool CChatSelector::SendMessage( const wxString
& message
, const wxString
& client_name
, uint64 to_id
)
220 // Dont let the user send empty messages
221 // This is also a user-fix for people who mash the enter-key ...
222 if ( message
.IsEmpty() ) {
227 // Checks if there's a page with this client, and selects it or creates it
228 StartSession(to_id
, client_name
, true);
231 int usedtab
= GetSelection();
232 // Workaround for a problem with wxNotebook, where an invalid selection is returned
233 if (usedtab
>= (int)GetPageCount()) {
234 usedtab
= GetPageCount() - 1;
240 CChatSession
* ci
= static_cast<CChatSession
*>(GetPage(usedtab
));
244 //#warning EC needed here.
247 if (theApp
->clientlist
->SendChatMessage(ci
->m_client_id
, message
)) {
248 ci
->AddText( thePrefs::GetUserNick(), COLOR_GREEN
, false );
249 ci
->AddText( wxT(": ") + message
, COLOR_BLACK
);
251 ci
->AddText( _("*** Connecting to Client ***"), COLOR_RED
);
258 //#warning Creteil? I know you are here Creteil... follow the white rabbit.
259 /* Madcat - knock knock ...
274 void CChatSelector::ConnectionResult(bool success
, const wxString
& message
, uint64 id
)
276 CChatSession
* ci
= GetPageByClientID(id
);
282 ci
->AddText( _("*** Failed to Connect to client / Connection lost ***"), COLOR_RED
);
284 ci
->m_active
= false;
286 // Kry - Woops, fix for the everlasting void message sending.
287 if ( !message
.IsEmpty() ) {
288 ci
->AddText( _("*** Connected to Client ***"), COLOR_RED
);
289 ci
->AddText( thePrefs::GetUserNick(), COLOR_GREEN
, false );
290 ci
->AddText( wxT(": ") + message
, COLOR_BLACK
);
296 void CChatSelector::EndSession(uint64 client_id
)
300 usedtab
= GetTabByClientID(client_id
);
302 usedtab
= GetSelection();
313 // Refresh the tab assosiated with a client
314 void CChatSelector::RefreshFriend(uint64 toupdate_id
, const wxString
& new_name
)
316 wxASSERT( toupdate_id
);
318 int tab
= GetTabByClientID(toupdate_id
);
321 // This client has a tab.
322 SetPageText(tab
,new_name
);
324 // This client has no tab (friend disconnecting, etc)
325 // Nothing to be done here.
330 void CChatSelector::ShowCaptchaResult(uint64 id
, bool ok
)
332 CChatSession
* ci
= GetPageByClientID(id
);
335 ? _("*** You have passed the captcha check and the user has received your message. ***")
336 : _("*** Your response to the captcha was wrong and your message has been ignored. You can request a new captcha by sending a new message. ***"),
343 bool CChatSelector::GetCurrentClient(CClientRef
&) const
348 bool CChatSelector::GetCurrentClient(CClientRef
& clientref
) const
350 // Get the chat session associated with the active tab
351 CChatSession
* ci
= static_cast<CChatSession
*>(GetPage(GetSelection()));
353 // Get the client that the session is open to
355 CUpDownClient
* client
= theApp
->clientlist
->FindClientByIP(IP_FROM_GUI_ID(ci
->m_client_id
), PORT_FROM_GUI_ID(ci
->m_client_id
));
357 clientref
.Link(client
CLIENT_DEBUGSTRING("CChatSelector::GetCurrentClient"));
365 // File_checked_for_headers