1 /* Copyright (C) 2007 The SpringLobby Team. All rights reserved. */
2 //
3 // Class: MainChatTab
4 //
5
6 #include <stdexcept>
7 #include <wx/intl.h>
8 #include <wx/imaglist.h>
9 #include <wx/sizer.h>
10 #include <wx/notebook.h>
11 #include <wx/image.h>
12 #include <wx/log.h>
13
14 #include "aui/auimanager.h"
15 #include "mainchattab.h"
16 #include "utils/debug.h"
17 #include "utils/conversion.h"
18 #include <lslutils/misc.h>
19 #include "utils/controls.h"
20 #include "mainwindow.h"
21 #include "channel/channel.h"
22 #include "user.h"
23 #include "chatpanel.h"
24 #include "server.h"
25 #include "settings.h"
26 #include "aui/artprovider.h"
27 #include "aui/slbook.h"
28
29 #include "images/close.xpm"
30 #include "images/server.xpm"
31 #include "images/channel.xpm"
32 #include "images/userchat.xpm"
33
BEGIN_EVENT_TABLE(MainChatTab,wxPanel)34 BEGIN_EVENT_TABLE( MainChatTab, wxPanel )
35
36 EVT_AUINOTEBOOK_PAGE_CHANGED ( CHAT_TABS, MainChatTab::OnTabsChanged )
37 EVT_AUINOTEBOOK_PAGE_CLOSE ( CHAT_TABS, MainChatTab::OnTabClose )
38
39 END_EVENT_TABLE()
40
41
42 MainChatTab::MainChatTab( wxWindow* parent )
43 : wxScrolledWindow( parent, -1, wxDefaultPosition, wxDefaultSize, 0, wxPanelNameStr )
44 {
45 GetAui().manager->AddPane( this, wxLEFT, _T( "mainchattab" ) );
46
47 m_newtab_sel = -1;
48 m_server_chat = 0;
49
50 m_main_sizer = new wxBoxSizer( wxVERTICAL );
51
52 m_chat_tabs = new SLChatNotebook( this, CHAT_TABS, wxDefaultPosition, wxDefaultSize, wxAUI_NB_DEFAULT_STYLE | wxAUI_NB_TOP | wxAUI_NB_TAB_EXTERNAL_MOVE | wxAUI_NB_WINDOWLIST_BUTTON );
53 m_chat_tabs ->SetArtProvider( new SLArtProvider );
54
55 wxBitmap userchat ( userchat_xpm ); //*charArr2wxBitmap(userchat_png, sizeof(userchat_png) );
56 m_imagelist = new wxImageList( 12, 12 );
57 m_imagelist->Add( wxBitmap( close_xpm ) );
58 m_imagelist->Add( wxBitmap( server_xpm ) );
59 m_imagelist->Add( wxBitmap( channel_xpm ) );
60 m_imagelist->Add( wxBitmap( userchat_xpm ) );
61
62 m_imagelist->Add( wxBitmap ( ReplaceChannelStatusColour( wxBitmap( channel_xpm ), sett().GetChatColorJoinPart() ) ) );
63 m_imagelist->Add( wxBitmap ( ReplaceChannelStatusColour( wxBitmap( userchat_xpm ), sett().GetChatColorJoinPart() ) ) );
64
65 m_imagelist->Add( wxBitmap ( ReplaceChannelStatusColour( wxBitmap( channel_xpm ), sett().GetChatColorMine() ) ) );
66 m_imagelist->Add( wxBitmap ( ReplaceChannelStatusColour( wxBitmap( userchat_xpm ), sett().GetChatColorMine() ) ) );
67
68 m_imagelist->Add( wxBitmap ( ReplaceChannelStatusColour( wxBitmap( channel_xpm ), sett().GetChatColorHighlight() ) ) );
69 m_imagelist->Add( wxBitmap ( ReplaceChannelStatusColour( wxBitmap( userchat_xpm ), sett().GetChatColorHighlight() ) ) );
70
71 m_imagelist->Add( wxBitmap ( ReplaceChannelStatusColour( wxBitmap( server_xpm ), sett().GetChatColorError() ) ) );
72
73 m_main_sizer->Add( m_chat_tabs, 1, wxEXPAND );
74
75 SetSizer( m_main_sizer );
76 m_main_sizer->SetSizeHints( this );
77 SetScrollRate( SCROLL_RATE, SCROLL_RATE );
78
79 Layout();
80 }
81
82
~MainChatTab()83 MainChatTab::~MainChatTab()
84 {
85
86 }
87
ServerChat()88 ChatPanel& MainChatTab::ServerChat()
89 {
90 ASSERT_LOGIC( m_server_chat != 0, _T( "m_server_chat = 0" ) );
91 return *m_server_chat;
92 }
93
94
GetActiveChatPanel()95 ChatPanel* MainChatTab::GetActiveChatPanel()
96 {
97 int selection = m_chat_tabs->GetSelection();
98 if ( selection < 0 )
99 return NULL;
100 else
101 return static_cast< ChatPanel* >( m_chat_tabs->GetPage( selection ) );
102 }
103
104
GetChannelChatPanel(const wxString & channel)105 ChatPanel* MainChatTab::GetChannelChatPanel( const wxString& channel )
106 {
107 for ( unsigned int i = 0; i < m_chat_tabs->GetPageCount(); i++ ) {
108 ChatPanel* tmp = ( ChatPanel* )m_chat_tabs->GetPage( i );
109 if ( tmp->GetPanelType() == CPT_Channel ) {
110 wxString name = m_chat_tabs->GetPageText( i );
111 if ( name.Lower() == channel.Lower() ) return ( ChatPanel* )m_chat_tabs->GetPage( i );
112 }
113 }
114 return 0;
115 }
116
UpdateNicklistHighlights()117 void MainChatTab::UpdateNicklistHighlights()
118 {
119 for ( unsigned int i = 0; i < m_chat_tabs->GetPageCount(); i++ ) {
120 ChatPanel* tmp = ( ChatPanel* )m_chat_tabs->GetPage( i );
121 if ( tmp->GetPanelType() == CPT_Channel ) {
122 tmp->UpdateNicklistHighlights();
123 }
124 }
125 if ( m_server_chat != 0 )
126 {
127 m_server_chat->UpdateNicklistHighlights();
128 }
129 }
130
GetUserChatPanel(const wxString & user)131 ChatPanel* MainChatTab::GetUserChatPanel( const wxString& user )
132 {
133 for ( unsigned int i = 0; i < m_chat_tabs->GetPageCount(); i++ ) {
134 ChatPanel* tmp = ( ChatPanel* )m_chat_tabs->GetPage( i );
135 if ( tmp->GetPanelType() == CPT_User ) {
136 wxString name = m_chat_tabs->GetPageText( i );
137 if ( name.Lower() == user.Lower() ) return ( ChatPanel* )m_chat_tabs->GetPage( i );
138 }
139 }
140 return 0;
141 }
142
143
OnUserConnected(User & user)144 void MainChatTab::OnUserConnected( User& user )
145 {
146 ChatPanel* panel = GetUserChatPanel( user.GetNick() );
147 if ( panel != 0 )
148 {
149 panel->SetUser( &user );
150 panel->OnUserConnected();
151 //TODO enable send button (koshi)
152 }
153 if ( m_server_chat != 0 )
154 {
155 m_server_chat->OnChannelJoin( user );
156 }
157 }
158
159
OnUserDisconnected(User & user)160 void MainChatTab::OnUserDisconnected( User& user )
161 {
162 ChatPanel* panel = GetUserChatPanel( user.GetNick() );
163 if ( panel != 0 )
164 {
165 panel->OnUserDisconnected();
166 panel->SetUser( 0 );
167 //TODO disable send button (koshi)
168 }
169 if ( m_server_chat != 0 )
170 {
171 m_server_chat->Parted( user, wxEmptyString );
172 }
173 }
174
LeaveChannels()175 void MainChatTab::LeaveChannels()
176 {
177 for ( unsigned int i = 0; i < m_chat_tabs->GetPageCount(); i++ ) {
178 ChatPanel* tmp = ( ChatPanel* )m_chat_tabs->GetPage( i );
179 if ( tmp->GetPanelType() == CPT_Channel )
180 {
181 tmp->StatusMessage( _( "Disconnected from server, chat closed." ) );
182 tmp->SetChannel( 0 );
183 } else if ( tmp->GetPanelType() == CPT_User )
184 {
185 tmp->StatusMessage( _( "Disconnected from server, chat closed." ) );
186 tmp->SetUser( 0 );
187 }
188 }
189 }
190
RejoinChannels()191 void MainChatTab::RejoinChannels()
192 {
193 for ( unsigned int i = 0; i < m_chat_tabs->GetPageCount(); i++ )
194 {
195 ChatPanel* tmp = ( ChatPanel* )m_chat_tabs->GetPage( i );
196 if ( tmp->GetPanelType() == CPT_Channel )
197 {
198
199 // TODO: This will not rejoin passworded channels.
200 wxString name = m_chat_tabs->GetPageText( i );
201 bool alreadyin = false;
202 try
203 {
204 serverSelector().GetServer().GetChannel( name ).GetMe();
205 alreadyin = true;
206 }
207 catch ( ... ) {}
208 if ( !alreadyin )
209 {
210 serverSelector().GetServer().JoinChannel( name, wxEmptyString );
211 tmp->SetChannel( &serverSelector().GetServer().GetChannel( name ) );
212 }
213
214 } else if ( tmp->GetPanelType() == CPT_User )
215 {
216
217 wxString name = m_chat_tabs->GetPageText( i );
218 if ( serverSelector().GetServer().UserExists( name ) ) tmp->SetUser( &serverSelector().GetServer().GetUser( name ) );
219
220 }
221 }
222 }
223
224
AddChatPanel(Channel & channel,bool doFocus)225 ChatPanel* MainChatTab::AddChatPanel( Channel& channel, bool doFocus )
226 {
227
228 for ( unsigned int i = 0; i < m_chat_tabs->GetPageCount(); i++ ) {
229 if ( m_chat_tabs->GetPageText( i ) == channel.GetName() ) {
230 ChatPanel* tmp = ( ChatPanel* )m_chat_tabs->GetPage( i );
231 if ( tmp->GetPanelType() == CPT_Channel ) {
232 if ( doFocus )
233 m_chat_tabs->SetSelection( i );
234 tmp->SetChannel( &channel );
235 return tmp;
236 }
237 }
238 }
239
240 ChatPanel* chat = new ChatPanel( m_chat_tabs, channel, m_imagelist );
241 m_chat_tabs->InsertPage( m_chat_tabs->GetPageCount() - 1, chat, channel.GetName(), doFocus, wxBitmap( channel_xpm ) );
242 if ( doFocus )
243 chat->FocusInputBox();
244 return chat;
245 }
246
AddChatPanel(Server & server,const wxString & name)247 ChatPanel* MainChatTab::AddChatPanel( Server& server, const wxString& name )
248 {
249
250 for ( unsigned int i = 0; i < m_chat_tabs->GetPageCount(); i++ ) {
251 //if ( m_chat_tabs->GetPageText( i ) == name ) {
252 if ( true ) { // wipe all old server tabs
253 ChatPanel* tmp = ( ChatPanel* )m_chat_tabs->GetPage( i );
254 if ( tmp->GetPanelType() == CPT_Server ) {
255 m_chat_tabs->DeletePage( i );
256 i--;
257 }
258 }
259 }
260
261 ChatPanel* chat = new ChatPanel( m_chat_tabs, server, m_imagelist );
262 m_server_chat = chat;
263 m_chat_tabs->InsertPage( m_chat_tabs->GetPageCount() - 1, chat, name, true, wxBitmap( server_xpm ) );
264 return chat;
265 }
266
AddChatPanel(const User & user)267 ChatPanel* MainChatTab::AddChatPanel( const User& user )
268 {
269 for ( unsigned int i = 0; i < m_chat_tabs->GetPageCount(); i++ ) {
270 if ( m_chat_tabs->GetPageText( i ) == user.GetNick() ) {
271 ChatPanel* tmp = ( ChatPanel* )m_chat_tabs->GetPage( i );
272 if ( tmp->GetPanelType() == CPT_User ) {
273 m_chat_tabs->SetSelection( i );
274 tmp->SetUser( &user );
275 return tmp;
276 }
277 }
278 }
279 int selection = m_chat_tabs->GetSelection();
280 ChatPanel* chat = new ChatPanel( m_chat_tabs, user, m_imagelist );
281 m_chat_tabs->InsertPage( m_chat_tabs->GetPageCount() - 1, chat, user.GetNick(), true, wxBitmap( userchat_xpm ) );
282 if ( selection > 0 ) m_chat_tabs->SetSelection( selection );
283 return chat;
284 }
285
286
BroadcastMessage(const wxString & message)287 void MainChatTab::BroadcastMessage( const wxString& message )
288 {
289 // spam the message in all channels
290 for ( unsigned int i = 0; i < m_chat_tabs->GetPageCount(); i++ )
291 {
292 ChatPanel* tmp = ( ChatPanel* )m_chat_tabs->GetPage( i );
293 tmp->StatusMessage( message );
294 }
295 }
296
297
GetCurrentPanel()298 ChatPanel* MainChatTab::GetCurrentPanel()
299 {
300 int sel = m_chat_tabs->GetSelection();
301 if ( sel < 0 ) return 0;
302 return ( ChatPanel* )m_chat_tabs->GetPage( sel );
303 }
304
305
OnTabClose(wxAuiNotebookEvent & event)306 void MainChatTab::OnTabClose( wxAuiNotebookEvent& event )
307 {
308 int selection = event.GetSelection();
309 ChatPanel* panel = ( ChatPanel* )m_chat_tabs->GetPage( selection );
310 if ( panel )
311 {
312 panel->Part();
313 if( panel->IsServerPanel() )
314 m_server_chat = 0;
315 }
316
317 }
318
OnTabsChanged(wxAuiNotebookEvent & event)319 void MainChatTab::OnTabsChanged( wxAuiNotebookEvent& event )
320 {
321 wxLogDebugFunc( wxEmptyString );
322
323 int oldsel = event.GetOldSelection();
324 if ( oldsel < 0 ) return;
325 int newsel = event.GetSelection();
326 if ( newsel < 0 ) return;
327
328 // change icon to default the icon to show that no new events happened
329 size_t ImageIndex = ( ( ChatPanel* )m_chat_tabs->GetPage( newsel ) )->GetIconIndex();
330 if ( ImageIndex == 4 || ImageIndex == 6 || ImageIndex == 8 )
331 {
332 GetActiveChatPanel()->SetIconIndex( 2 );
333 m_chat_tabs->SetPageBitmap( newsel, wxBitmap( channel_xpm ) );
334 }
335 else if ( ImageIndex == 5 || ImageIndex == 7 || ImageIndex == 9 )
336 {
337 GetActiveChatPanel()->SetIconIndex( 3 );
338 m_chat_tabs->SetPageBitmap( newsel, wxBitmap( userchat_xpm ) );
339 }
340 else if ( ImageIndex == 10 )
341 {
342 GetActiveChatPanel()->SetIconIndex( 1 );
343 m_chat_tabs->SetPageBitmap( newsel, wxBitmap( server_xpm ) );
344 }
345
346 wxWindow* newpage = m_chat_tabs->GetPage( newsel );
347 if ( newpage == 0 ) { // Not sure what to do here
348 wxLogError( _T( "Newpage NULL." ) );
349 return;
350 }
351
352 GetActiveChatPanel()->FocusInputBox();
353
354 }
355
356
ReplaceChannelStatusColour(wxBitmap img,const wxColour & colour) const357 wxImage MainChatTab::ReplaceChannelStatusColour( wxBitmap img, const wxColour& colour ) const
358 {
359 wxImage ret = img.ConvertToImage();
360 wxImage::HSVValue origcolour = wxImage::RGBtoHSV( wxImage::RGBValue( colour.Red(), colour.Green(), colour.Blue() ) );
361
362 double bright = origcolour.value - 0.1 * origcolour.value;
363 bright = LSL::Util::Clamp( bright, 0.0, 1.0 );
364 wxImage::HSVValue hsvdarker1( origcolour.hue, origcolour.saturation, bright );
365 bright = origcolour.value - 0.5 * origcolour.value;
366 bright = LSL::Util::Clamp( bright, 0.0, 1.0 );
367 wxImage::HSVValue hsvdarker2( origcolour.hue, origcolour.saturation, bright );
368
369 wxImage::RGBValue rgbdarker1 = wxImage::HSVtoRGB( hsvdarker1 );
370 wxImage::RGBValue rgbdarker2 = wxImage::HSVtoRGB( hsvdarker2 );
371
372
373 ret.Replace( 164, 147, 0, rgbdarker2.red, rgbdarker2.green, rgbdarker2.blue );
374
375 ret.Replace( 255, 228, 0, rgbdarker1.red, rgbdarker1.green, rgbdarker1.blue );
376
377 ret.Replace( 255, 253, 234, colour.Red(), colour.Green(), colour.Blue() );
378
379 ret.Replace( 255, 228, 0, rgbdarker1.red, rgbdarker1.green, rgbdarker1.blue );
380
381 // server icon
382
383 ret.Replace( 211, 211, 211, rgbdarker2.red, rgbdarker2.green, rgbdarker2.blue );
384
385 ret.Replace( 249, 249, 249, rgbdarker1.red, rgbdarker1.green, rgbdarker1.blue );
386
387 ret.Replace( 0, 180, 255, colour.Red(), colour.Green(), colour.Blue() );
388
389
390 return ret;
391 }
392
RemoveChatPanel(ChatPanel * panel)393 bool MainChatTab::RemoveChatPanel( ChatPanel* panel )
394 {
395 for ( unsigned int i = 0; i < m_chat_tabs->GetPageCount(); i++ ) {
396 ChatPanel* tmp = ( ChatPanel* )m_chat_tabs->GetPage( i );
397 if ( tmp == panel && panel != 0 )
398 {
399 m_chat_tabs->DeletePage( i );
400 return true;
401 }
402 }
403 return false;
404 }
405
LoadPerspective(const wxString & perspective_name)406 void MainChatTab::LoadPerspective( const wxString& perspective_name )
407 {
408 LoadNotebookPerspective( m_chat_tabs, perspective_name );
409 }
410
SavePerspective(const wxString & perspective_name)411 void MainChatTab::SavePerspective( const wxString& perspective_name )
412 {
413 SaveNotebookPerspective( m_chat_tabs, perspective_name );
414 }
415
AdvanceSelection(bool forward)416 void MainChatTab::AdvanceSelection( bool forward )
417 {
418 m_chat_tabs->AdvanceSelection( forward );
419 }
420