1 /* Copyright (C) 2007-2011 The SpringLobby Team. All rights reserved. */
2 //
3 // Class: MainWindow
4 //
5 
6 #ifdef _MSC_VER
7 #ifndef NOMINMAX
8     #define NOMINMAX
9 #endif // NOMINMAX
10 #include <winsock2.h>
11 #endif // _MSC_VER
12 
13 #include <wx/frame.h>
14 #include <wx/intl.h>
15 #include <wx/textdlg.h>
16 #include <wx/imaglist.h>
17 #include <wx/image.h>
18 #include <wx/icon.h>
19 #include <wx/sizer.h>
20 #include <wx/menu.h>
21 #include <wx/log.h>
22 #include <wx/dcmemory.h>
23 #include <wx/choicdlg.h>
24 #include <wx/wupdlock.h>
25 #include <wx/aui/auibook.h>
26 #include <wx/tooltip.h>
27 #include <wx/aboutdlg.h>
28 
29 #include <stdexcept>
30 #include <iostream>
31 
32 #include "aui/auimanager.h"
33 #include "aui/slbook.h"
34 #include "aui/artprovider.h"
35 #include "gui/statusbar.h"
36 #include "springlobbyapp.h"
37 #include "mainwindow.h"
38 #include "settings.h"
39 #include "server.h"
40 #include "utils/debug.h"
41 #include "utils/platform.h"
42 #include "battlelist/battlelisttab.h"
43 #include "mainchattab.h"
44 #include "hosting/mainjoinbattletab.h"
45 #include "hosting/mainsingleplayertab.h"
46 #include "battlelist/battlelisttab.h"
47 #include "options/mainoptionstab.h"
48 #include "uiutils.h"
49 #include "utils/misc.h"
50 #include "chatpanel.h"
51 #include "playback/playbacktraits.h"
52 #include "playback/playbacktab.h"
53 #include "infodialog.h"
54 #include "maindownloadtab.h"
55 #include "user.h"
56 #include "mapselectdialog.h"
57 
58 #include "images/chat_icon.png.h"
59 #include "images/join_icon.png.h"
60 #include "images/single_player_icon.png.h"
61 #include "images/options_icon.png.h"
62 #include "images/downloads_icon.png.h"
63 #include "images/replay_icon.png.h"
64 #include "images/broom_tab_icon.png.h"
65 #include "images/floppy_icon.png.h"
66 
67 #include "springsettings/frame.h"
68 #include "utils/customdialogs.h"
69 #include "utils/platform.h"
70 
71 #include "updater/updatehelper.h"
72 #include "channel/autojoinchanneldialog.h"
73 #include "channel/channelchooserdialog.h"
74 #include "helper/imageviewer.h"
75 
76 #if defined(__WXMSW__)
77     #include <wx/msw/winundef.h>
78     #include <iostream>
79 #endif
80 #include <wx/aboutdlg.h>
81 
82 SLCONFIG("/GUI/UseTabIcons", true, "Show icons in main tabs");
83 
84 BEGIN_EVENT_TABLE(MainWindow, wxFrame)
85 
86   EVT_MENU( MENU_JOIN,					MainWindow::OnMenuJoin				)
87   EVT_MENU( MENU_CHAT,					MainWindow::OnMenuChat				)
88   EVT_MENU( MENU_CONNECT,				MainWindow::OnMenuConnect			)
89   EVT_MENU( MENU_DISCONNECT,			MainWindow::OnMenuDisconnect		)
90   EVT_MENU( MENU_SAVE_OPTIONS,			MainWindow::OnMenuSaveOptions		)
91   EVT_MENU( MENU_QUIT,					MainWindow::OnMenuQuit				)
92   EVT_MENU( MENU_USYNC,					MainWindow::OnUnitSyncReload		)
93   EVT_MENU( MENU_TRAC,					MainWindow::OnReportBug				)
94   EVT_MENU( MENU_DOC,					MainWindow::OnShowDocs				)
95   EVT_MENU( MENU_SETTINGSPP,			MainWindow::OnShowSettingsPP		)
96   EVT_MENU( MENU_VERSION,				MainWindow::OnMenuVersion			)
97   EVT_MENU( MENU_ABOUT,					MainWindow::OnMenuAbout				)
98   EVT_MENU( MENU_PATHINFO,				MainWindow::OnMenuPathInfo			)
99   EVT_MENU( MENU_RESET_LAYOUT,			MainWindow::OnMenuResetLayout		)
100 //  EVT_MENU( MENU_SHOW_TOOLTIPS,		MainWindow::OnShowToolTips			)
101   EVT_MENU( MENU_AUTOJOIN_CHANNELS,		MainWindow::OnMenuAutojoinChannels	)
102   EVT_MENU( MENU_SELECT_LOCALE,			MainWindow::OnMenuSelectLocale		)
103   EVT_MENU( MENU_CHANNELCHOOSER,		MainWindow::OnShowChannelChooser	)
104   EVT_MENU( MENU_SCREENSHOTS,			MainWindow::OnShowScreenshots		)
105   EVT_MENU( MENU_PREFERENCES,			MainWindow::OnMenuPreferences		)
106   EVT_MENU( MENU_GENERAL_HELP,			MainWindow::OnMenuFirstStart		)
107   EVT_MENU( MENU_SERVER_TAB,			MainWindow::OnMenuServerTab			)
108   EVT_SET_FOCUS(                        MainWindow::OnSetFocus              )
109   EVT_KILL_FOCUS(                       MainWindow::OnKillFocus             )
110   EVT_AUINOTEBOOK_PAGE_CHANGED( MAIN_TABS, MainWindow::OnTabsChanged )
111   EVT_CLOSE( MainWindow::OnClose )
112 END_EVENT_TABLE()
113 
114 MainWindow::TabNames MainWindow::m_tab_names;
115 
MainWindow()116 MainWindow::MainWindow( )
117 	: wxFrame(NULL, -1, GetAppName() ),
118 	WindowAttributesPickle( _T("MAINWINDOW"), this, wxSize(720, 576) ),
119 	m_opts_dialog(NULL),
120 	m_autojoin_dialog(NULL),
121 	se_frame(NULL),
122 	m_channel_chooser(NULL),
123 	m_log_win(NULL),
124 	m_has_focus(true)
125 {
126 	SetIcons( icons().GetIcon(icons().ICON_SPRINGLOBBY) );
127 
128 	GetAui().manager = new AuiManagerContainer::ManagerType( this );
129 
130 	wxMenu *menuServer = new wxMenu;
131 	menuServer->Append(MENU_CONNECT, _("&Connect..."));
132 	menuServer->Append(MENU_DISCONNECT, _("&Disconnect"));
133 	menuServer->Append(MENU_SERVER_TAB, _("&Reopen server panel"));
134 	menuServer->AppendSeparator();
135 #ifndef NDEBUG
136 	//this is a prime spot to add experimental stuff, or stubs used to test things not really meant to be in mainwindow
137 	menuServer->Append(MENU_SAVE_OPTIONS, _("&Save options"));
138 	menuServer->AppendSeparator();
139 #endif
140 	menuServer->Append(MENU_QUIT, _("&Quit"));
141 
142 	m_menuEdit = new wxMenu;
143 	m_menuEdit->Append(MENU_AUTOJOIN_CHANNELS, _("&Autojoin channels"));
144 	m_menuEdit->Append(MENU_PREFERENCES, _("&Preferences"));
145 	m_menuEdit->Append(MENU_SELECT_LOCALE, _("&Change language"));
146 	m_settings_menu = new wxMenuItem( m_menuEdit, MENU_SETTINGSPP, _("&Spring settings"), wxEmptyString, wxITEM_NORMAL );
147 	m_menuEdit->Append( MENU_RESET_LAYOUT, _("&Reset layout") );
148 	m_menuEdit->Append (m_settings_menu);
149 
150 
151 
152 	m_menuTools = new wxMenu;
153 	m_menuTools->Append(MENU_JOIN, _("&Join channel..."));
154 	m_menuTools->Append(MENU_CHANNELCHOOSER, _("Channel &list"));
155 	m_menuTools->Append(MENU_CHAT, _("Open private &chat..."));
156 	m_menuTools->Append(MENU_SCREENSHOTS, _("&View screenshots"));
157 	m_menuTools->AppendSeparator();
158 	m_menuTools->Append(MENU_USYNC, _("&Reload maps/games"));
159     m_menuTools->AppendSeparator();
160 
161 	m_menuTools->Append(MENU_VERSION, _("Check for new Version"));
162 
163 	wxMenu *menuHelp = new wxMenu;
164 	menuHelp->Append(MENU_GENERAL_HELP, _("&Help, tutorial and FAQ"));
165 	menuHelp->Append(MENU_ABOUT, _("&About"));
166 	menuHelp->Append(MENU_PATHINFO, _("&System Info"));
167 	menuHelp->Append(MENU_TRAC, _("&Report a bug..."));
168 	menuHelp->Append(MENU_DOC, _("&Documentation"));
169 
170 	m_menubar = new wxMenuBar;
171 	m_menubar->Append(menuServer, _("&Server"));
172 	m_menubar->Append(m_menuEdit, _("&Edit"));
173 
174 	m_menubar->Append(m_menuTools, _("&Tools"));
175 	m_menubar->Append(menuHelp, _("&Help"));
176 	SetMenuBar(m_menubar);
177 
178 	m_main_sizer = new wxBoxSizer( wxHORIZONTAL );
179 	m_func_tabs = new SLNotebook(  this, _T("mainfunctabs"), MAIN_TABS, wxDefaultPosition, wxDefaultSize,
180 		wxAUI_NB_WINDOWLIST_BUTTON | wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_MOVE | wxAUI_NB_TAB_EXTERNAL_MOVE | wxAUI_NB_SCROLL_BUTTONS | wxAUI_NB_LEFT );
181 	m_func_tabs->SetArtProvider(new SLArtProvider);
182 
183 	//IMPORTANT: event handling needs to be disabled while constructing, otherwise deadlock occurs
184 	SetEvtHandlerEnabled( false );
185 
186 	m_chat_tab = new MainChatTab( m_func_tabs );
187 	m_list_tab = new BattleListTab( m_func_tabs );
188 	m_join_tab = new MainJoinBattleTab( m_func_tabs );
189 	m_sp_tab = new MainSinglePlayerTab( m_func_tabs );
190 //	m_savegame_tab = new SavegameTab( m_func_tabs );
191 	m_replay_tab = new ReplayTab ( m_func_tabs );
192 	m_torrent_tab = new MainDownloadTab( m_func_tabs);
193 
194     //use Insert so no Changepage events are triggered
195     m_func_tabs->InsertPage( PAGE_CHAT,     m_chat_tab,     m_tab_names[PAGE_CHAT],     true  );
196     m_func_tabs->InsertPage( PAGE_LIST,     m_list_tab,     m_tab_names[PAGE_LIST],     false  );
197     m_func_tabs->InsertPage( PAGE_JOIN,     m_join_tab,     m_tab_names[PAGE_JOIN],     false );
198     m_func_tabs->InsertPage( PAGE_SINGLE,   m_sp_tab,       m_tab_names[PAGE_SINGLE],   false );
199 //    m_func_tabs->InsertPage( PAGE_SAVEGAME, m_savegame_tab, m_tab_names[PAGE_SAVEGAME], false );
200     m_func_tabs->InsertPage( PAGE_REPLAY,   m_replay_tab,   m_tab_names[PAGE_REPLAY],   false );
201     m_func_tabs->InsertPage( PAGE_TORRENT,  m_torrent_tab,  m_tab_names[PAGE_TORRENT],  false );
202 
203     LoadPerspectives();
204 	SetTabIcons();
205 	m_main_sizer->Add( m_func_tabs, 1, wxEXPAND | wxALL, 0 );
206 
207 	SetSizer( m_main_sizer );
208 
209 	Layout();
210 
211 	se_frame_active = false;
212 
213 	wxToolTip::Enable(sett().GetShowTooltips());
214 
215 	m_channel_chooser = new ChannelChooserDialog( this, -1, _("Choose channels to join") );
216 
217 	m_statusbar = new Statusbar( this );
218     SetStatusBar( m_statusbar );
219     // re-enable eventhandling
220     SetEvtHandlerEnabled( true );
221 
222 	UpdateMainAppHasFocus(m_has_focus);
223     Connect( MainwindowMessageEvent, wxCommandEventHandler( MainWindow::OnMessage ), NULL, this );
224 
225         //this should take off the firstload time considerably *ie nil it :P )
226         mapSelectDialog(true, this);
227 }
228 
GetTabIcon(const unsigned char * data,size_t size) const229 wxBitmap MainWindow::GetTabIcon( const unsigned char* data, size_t size ) const
230 {
231     if ( cfg().ReadBool(_T( "/GUI/UseTabIcons" )) )
232         return charArr2wxBitmap( data , size );
233     else
234         return wxNullBitmap;
235 }
236 
SetTabIcons()237 void MainWindow::SetTabIcons()
238 {
239     m_func_tabs->SetPageBitmap( PAGE_CHAT    , GetTabIcon( chat_icon_png          , sizeof(chat_icon_png)  ) );
240     m_func_tabs->SetPageBitmap( PAGE_LIST    , GetTabIcon( join_icon_png          , sizeof(join_icon_png)  ) );
241     m_func_tabs->SetPageBitmap( PAGE_JOIN    , GetTabIcon( broom_tab_icon_png     , sizeof(broom_tab_icon_png) ) );
242     m_func_tabs->SetPageBitmap( PAGE_SINGLE  , GetTabIcon( single_player_icon_png , sizeof (single_player_icon_png) ) );
243     m_func_tabs->SetPageBitmap( PAGE_TORRENT , GetTabIcon( downloads_icon_png     , sizeof (downloads_icon_png) ) );
244     m_func_tabs->SetPageBitmap( PAGE_REPLAY  , GetTabIcon( replay_icon_png        , sizeof (replay_icon_png) ) );
245     //m_func_tabs->SetPageBitmap( ??         , GetTabIcon( floppy_icon_png        , sizeof (floppy_icon_png) ) );
246     //m_func_tabs->SetPageBitmap( ??         , GetTabIcon( options_icon_png       , sizeof (options_icon_png) ) );
247     Refresh();
248 }
249 
forceSettingsFrameClose()250 void MainWindow::forceSettingsFrameClose()
251 {
252 }
253 
SetLogWin(wxLogWindow * log,wxLogChain * logchain)254 void MainWindow::SetLogWin( wxLogWindow* log, wxLogChain* logchain  )
255 {
256     m_log_win = log;
257     m_log_chain = logchain;
258     if ( m_log_win )
259         m_log_win->GetFrame()->SetParent( this );
260 }
261 
~MainWindow()262 MainWindow::~MainWindow()
263 {
264 	SetEvtHandlerEnabled( false );
265 	if ( m_opts_dialog )
266 	{
267 		m_opts_dialog->Show(false);
268 		m_opts_dialog->Destroy();
269 	}
270 }
271 
OnClose(wxCloseEvent &)272 void MainWindow::OnClose( wxCloseEvent& /*unused*/ )
273 {
274 	GlobalEvent::Send(GlobalEvent::OnQuit);
275 //	GlobalEvent::Disconnect(MainWindow::OnClose, GlobalEvent::)
276 //	SetEvtHandlerEnabled(false);
277 	{
278 		wxWindowUpdateLocker lock( this );
279 		SavePerspectives();
280 		AuiManagerContainer::ManagerType* manager=GetAui().manager;
281 		if(manager){
282 			GetAui().manager=NULL;
283 			manager->UnInit();
284 			delete manager;
285 		}
286 
287 		ui().Quit();
288 		forceSettingsFrameClose();
289 		freeStaticBox();
290 
291 		delete m_autojoin_dialog;
292 		m_autojoin_dialog = 0;
293 
294 		if ( m_log_win ) {
295 			m_log_win->GetFrame()->Destroy();
296 			if ( m_log_chain ) // if logwin was created, it's the current "top" log
297 				m_log_chain->DetachOldLog();  //so we need to tellwx not to delete it on its own
298 				//since we absolutely need to destroy the logwin here, set a fallback for the time until app cleanup
299 			#if(wxUSE_STD_IOSTREAM)
300 				wxLog::SetActiveTarget( new wxLogStream( &std::cout ) );
301 			#endif
302 		}
303 	}
304 	Destroy();
305 }
306 
OnSetFocus(wxFocusEvent &)307 void MainWindow::OnSetFocus(wxFocusEvent&)
308 {
309 	m_has_focus = true;
310 	UpdateMainAppHasFocus(m_has_focus);
311 }
312 
OnKillFocus(wxFocusEvent &)313 void MainWindow::OnKillFocus(wxFocusEvent&)
314 {
315 	m_has_focus = false;
316     UpdateMainAppHasFocus(m_has_focus);
317 }
318 
OnMessage(wxCommandEvent & event)319 void MainWindow::OnMessage(wxCommandEvent &event)
320 {
321     customMessageBoxNoModal(SL_MAIN_ICON, event.GetString());
322 }
323 
AddMessageEvent(const wxString & message)324 void MainWindow::AddMessageEvent(const wxString& message)
325 {
326     wxCommandEvent evt(MainwindowMessageEvent, wxNewId());
327     evt.SetString(message);
328     AddPendingEvent(evt);
329 }
330 
HasFocus() const331 bool MainWindow::HasFocus() const
332 {
333 	return m_has_focus;
334 }
335 
DrawBmpOnBmp(wxBitmap & canvas,wxBitmap & object,int x,int y)336 void DrawBmpOnBmp( wxBitmap& canvas, wxBitmap& object, int x, int y )
337 {
338   wxMemoryDC dc;
339   dc.SelectObject( canvas );
340   dc.DrawBitmap( object, x, y, true );
341   dc.SelectObject( wxNullBitmap );
342 }
343 
344 //void MainWindow::DrawTxtOnBmp( wxBitmap& canvas, wxString text, int x, int y )
345 //{
346 //  wxMemoryDC dc;
347 //  dc.SelectObject( canvas );
348 //
349 //  dc.DrawText( text, x, y);
350 //  dc.SelectObject( wxNullBitmap );
351 //}
352 
353 
354 /*
355 //! @brief Get the ChatPanel dedicated to server output and input
356 ChatPanel& servwin()
357 {
358   return ui().mw().GetChatTab().ServerChat();
359 }
360 */
361 
362 //! @brief Returns the curent MainChatTab object
GetChatTab()363 MainChatTab& MainWindow::GetChatTab()
364 {
365   ASSERT_EXCEPTION( m_chat_tab != 0, _T("m_chat_tab = 0") );
366   return *m_chat_tab;
367 }
368 
369 //! @brief Returns the curent BattleListTab object
GetBattleListTab()370 BattleListTab& MainWindow::GetBattleListTab()
371 {
372 	ASSERT_EXCEPTION( m_list_tab != 0, _T( "m_list_tab = 0" ) );
373 	return *m_list_tab;
374 }
375 
GetJoinTab()376 MainJoinBattleTab& MainWindow::GetJoinTab()
377 {
378   ASSERT_EXCEPTION( m_join_tab != 0, _T("m_join_tab = 0") );
379   return *m_join_tab;
380 }
381 
382 
GetSPTab()383 MainSinglePlayerTab& MainWindow::GetSPTab()
384 {
385   ASSERT_EXCEPTION( m_sp_tab != 0, _T("m_sp_tab = 0") );
386   return *m_sp_tab;
387 }
388 
GetReplayTab()389 MainWindow::ReplayTab& MainWindow::GetReplayTab()
390 {
391     ASSERT_EXCEPTION( m_replay_tab != 0, _T("m_replay_tab = 0") );
392     return *m_replay_tab;
393 }
394 
395 //MainWindow::SavegameTab& MainWindow::GetSavegameTab()
396 //{
397 //    ASSERT_EXCEPTION( m_replay_tab != 0, _T("m_replay_tab = 0") );
398 //    return *m_savegame_tab;
399 //}
400 
GetDownloadTab()401 MainDownloadTab& MainWindow::GetDownloadTab()
402 {
403   ASSERT_EXCEPTION( m_torrent_tab  != 0, _T("m_torrent_tab = 0") );
404   return *m_torrent_tab ;
405 }
406 
GetActiveChatPanel()407 ChatPanel* MainWindow::GetActiveChatPanel()
408 {
409   unsigned int index = m_func_tabs->GetSelection();
410   if ( index == PAGE_CHAT ) return m_chat_tab->GetActiveChatPanel();
411   //! TODO (koshi) this doesn't work when in broom an and sending "/help (ShowMessage() )
412   if ( index == PAGE_JOIN ) return m_join_tab->GetActiveChatPanel();
413   return 0;
414 }
415 
GetChannelChatPanel(const wxString & channel)416 ChatPanel* MainWindow::GetChannelChatPanel( const wxString& channel )
417 {
418   return m_chat_tab->GetChannelChatPanel( channel );
419 }
420 
421 //! @brief Open a new chat tab with a channel chat
422 //!
423 //! @param channel The channel name
424 //! @note This does NOT join the chatt.
425 //! @sa Server::JoinChannel OpenPrivateChat
OpenChannelChat(Channel & channel,bool doFocus)426 void MainWindow::OpenChannelChat( Channel& channel, bool doFocus )
427 {
428     ASSERT_LOGIC( m_chat_tab != 0, _T("m_chat_tab") );
429     if ( doFocus )
430         m_func_tabs->SetSelection( PAGE_CHAT );
431 	m_chat_tab->AddChatPanel( channel, doFocus );
432 }
433 
434 
435 //! @brief Open a new chat tab with a private chat
436 //!
437 //! @param nick The user to whom the chatwindow should be opened to
OpenPrivateChat(const User & user,bool doFocus)438 void MainWindow::OpenPrivateChat( const User& user, bool doFocus )
439 {
440   ASSERT_LOGIC( m_chat_tab != 0, _T("m_chat_tab") );
441   m_func_tabs->SetSelection( PAGE_CHAT );
442   ChatPanel* cp = m_chat_tab->AddChatPanel( user );
443   if ( doFocus )
444     cp->FocusInputBox();
445 
446 }
447 
448 //! @brief Displays the lobby singleplayer tab.
ShowSingleplayer()449 void MainWindow::ShowSingleplayer()
450 {
451     ShowTab( PAGE_SINGLE );
452 }
453 
ShowTab(const unsigned int idx)454 void MainWindow::ShowTab( const unsigned int idx )
455 {
456     if ( idx < m_tab_names.GetCount() )
457         m_func_tabs->SetSelection( idx );
458     else
459         wxLogError( _T("tab selection oob: %d"), idx );
460 }
461 
462 //! @brief Displays the lobby configuration.
ShowConfigure(const unsigned int page)463 void MainWindow::ShowConfigure( const unsigned int page )
464 {
465 	OptionsDialog* opts = new OptionsDialog( this );
466 	//possibly out of bounds is captured by m_opts_tab itslef
467 	opts->SetSelection( page );
468 	opts->Show();
469 }
470 
ShowChannelChooser()471 void MainWindow::ShowChannelChooser()
472 {
473 	if ( (m_channel_chooser == NULL) || (m_channel_chooser && m_channel_chooser->IsShown()) )
474 		return;
475 
476 	if ( !ui().IsConnected() ) {
477 		customMessageBox( SL_MAIN_ICON, _("You need to be connected to a server to view the channel list"), _("Not connected") );
478 	} else {
479 		m_channel_chooser->ClearChannels();
480 		serverSelector().GetServer().RequestChannels();
481 		m_channel_chooser->Show( true );
482 	}
483 }
484 
485 //! @brief Called when join channel menuitem is clicked
OnMenuJoin(wxCommandEvent &)486 void MainWindow::OnMenuJoin( wxCommandEvent& /*unused*/ )
487 {
488 
489   if ( !ui().IsConnected() ) return;
490   wxString answer;
491   if ( ui().AskText( _("Join channel..."), _("Name of channel to join"), answer ) ) {
492     ui().JoinChannel( answer, wxEmptyString );
493   }
494 
495 }
496 
497 
OnMenuChat(wxCommandEvent &)498 void MainWindow::OnMenuChat( wxCommandEvent& /*unused*/ )
499 {
500 
501   if ( !ui().IsConnected() ) return;
502   wxString answer;
503   if ( ui().AskText( _("Open Private Chat..."), _("Name of user"), answer ) ) {
504 	if (serverSelector().GetServer().UserExists( answer ) ) {
505         //true puts focus on new tab
506 	  OpenPrivateChat( serverSelector().GetServer().GetUser( answer ), true  );
507     }
508   }
509 
510 }
511 
OnMenuAbout(wxCommandEvent &)512 void MainWindow::OnMenuAbout( wxCommandEvent& /*unused*/ )
513 {
514     wxAboutDialogInfo info;
515 	info.SetName( GetAppName() );
516 	info.SetVersion (GetSpringLobbyVersion());
517 	info.SetDescription( IdentityString( _("%s is a cross-plattform lobby client for the Spring RTS engine") ) );
518 	//info.SetCopyright(wxEmptyString;
519 	info.SetLicence(_T("GPL"));
520 	info.AddDeveloper(_T("abma"));
521 	info.AddDeveloper(_T("BrainDamage"));
522 	info.AddDeveloper(_T("dizekat"));
523 	info.AddDeveloper(_T("insaneinside"));
524 	info.AddDeveloper(_T("Kaot"));
525 	info.AddDeveloper(_T("koshi"));
526 	info.AddDeveloper(_T("semi_"));
527 	info.AddDeveloper(_T("tc-"));
528     info.AddTranslator(_T("chaosch (simplified chinese)"));
529 	info.AddTranslator(_T("lejocelyn (french)"));
530 	info.AddTranslator(_T("Suprano (german)"));
531     info.AddTranslator(_T("tc- (swedish)"));
532 	info.AddTranslator(_("The numerous contributors from launchpad.net"));
533 	//! \todo customisations
534 	info.SetIcon( icons().GetIcon(icons().ICON_SPRINGLOBBY) );
535 	wxAboutBox(info);
536 }
537 
OnMenuConnect(wxCommandEvent &)538 void MainWindow::OnMenuConnect( wxCommandEvent& /*unused*/ )
539 {
540   ui().ShowConnectWindow();
541 }
542 
543 
OnMenuDisconnect(wxCommandEvent &)544 void MainWindow::OnMenuDisconnect( wxCommandEvent& /*unused*/ )
545 {
546   ui().Disconnect();
547 }
548 
OnMenuServerTab(wxCommandEvent &)549 void MainWindow::OnMenuServerTab( wxCommandEvent& /*unused*/ )
550 {
551   ui().ReopenServerTab();
552 }
553 
OnMenuSaveOptions(wxCommandEvent &)554 void MainWindow::OnMenuSaveOptions( wxCommandEvent& /*unused*/ )
555 {
556   sett().SaveSettings();
557 }
558 
OnMenuQuit(wxCommandEvent &)559 void MainWindow::OnMenuQuit( wxCommandEvent& /*unused*/ )
560 {
561   Close();
562 }
563 
564 #include "utils/uievents.h"
565 
OnMenuVersion(wxCommandEvent &)566 void MainWindow::OnMenuVersion( wxCommandEvent& /*unused*/ )
567 {
568 	ui().CheckForUpdates();
569 }
570 
OnUnitSyncReload(wxCommandEvent &)571 void MainWindow::OnUnitSyncReload( wxCommandEvent& /*unused*/ )
572 {
573 	LSL::usync().ReloadUnitSyncLib();
574 	GlobalEvent::Send(GlobalEvent::OnUnitsyncReloaded);
575 }
576 
OnShowScreenshots(wxCommandEvent &)577 void MainWindow::OnShowScreenshots( wxCommandEvent& /*unused*/ )
578 {
579     wxArrayString ar;
580     for( auto i : LSL::usync().GetScreenshotFilenames())
581         ar.Add(TowxString(i));
582     if ( ar.Count() == 0 ) {
583         customMessageBoxNoModal( SL_MAIN_ICON, _("There were no screenshots found in your spring data directory."), _("No files found") );
584         return;
585     }
586     ar.Sort();
587     ImageViewerDialog* img  = new ImageViewerDialog( ar, true, this, -1, _T("Screenshots") );
588     img->Show( true );
589 }
590 
591 
OnReportBug(wxCommandEvent &)592 void MainWindow::OnReportBug( wxCommandEvent& /*unused*/ )
593 {
594 	OpenWebBrowser( _T("https://github.com/springlobby/springlobby/issues") );
595 }
596 
597 
OnShowDocs(wxCommandEvent &)598 void MainWindow::OnShowDocs( wxCommandEvent& /*unused*/ )
599 {
600 	OpenWebBrowser( _T("https://github.com/springlobby/springlobby/wiki/") );
601 }
602 
OnTabsChanged(wxAuiNotebookEvent & event)603 void MainWindow::OnTabsChanged( wxAuiNotebookEvent& event )
604 {
605   int newsel = event.GetSelection();
606 
607   if ( newsel == 0 || newsel == 1 )
608   {
609 	if ( !ui().IsConnected() && ui().IsMainWindowCreated() ) ui().Connect();
610   }
611 
612 	ChatPanel* panel = ui().GetActiveChatPanel(); //set input focus to edit field on tab change
613 	if (panel!=NULL) {
614 		panel->SetFocus();
615 	}
616 }
617 
OnShowSettingsPP(wxCommandEvent &)618 void MainWindow::OnShowSettingsPP( wxCommandEvent&  )
619 {
620 	if ( se_frame && se_frame_active ) {
621 		se_frame->updateAllControls();
622 		se_frame->Raise();
623 		return;
624 	}
625 
626 	se_frame = new settings_frame(this,wxT("SpringSettings"));
627 	se_frame_active = true;
628 	se_frame->updateAllControls();
629 	se_frame->Show();
630 }
631 
OnMenuAutojoinChannels(wxCommandEvent &)632 void MainWindow::OnMenuAutojoinChannels( wxCommandEvent& /*unused*/ )
633 {
634     m_autojoin_dialog = new AutojoinChannelDialog (this);
635     m_autojoin_dialog->Show();
636 }
637 
OnMenuSelectLocale(wxCommandEvent &)638 void MainWindow::OnMenuSelectLocale( wxCommandEvent& /*unused*/ )
639 {
640     if ( wxGetApp().SelectLanguage() ) {
641 		customMessageBoxNoModal( SL_MAIN_ICON,
642 								 IdentityString( _("You need to restart %s for the language change to take effect.") ),
643 								 _("Restart required"),
644 								 wxICON_EXCLAMATION | wxOK );
645     }
646 }
647 
OnShowChannelChooser(wxCommandEvent &)648 void MainWindow::OnShowChannelChooser( wxCommandEvent& /*unused*/ )
649 {
650     ShowChannelChooser();
651 }
652 
OnChannelList(const wxString & channel,const int & numusers,const wxString & topic)653 void MainWindow::OnChannelList( const wxString& channel, const int& numusers, const wxString& topic )
654 {
655     m_channel_chooser->AddChannel( channel, numusers, topic );
656 }
657 
OnChannelListStart()658 void MainWindow::OnChannelListStart( )
659 {
660     m_channel_chooser->ClearChannels();
661 }
662 
AddPerspectivePostfix(const wxString & pers_name) const663 wxString MainWindow::AddPerspectivePostfix( const wxString& pers_name ) const
664 {
665     wxString perspective_name  = pers_name.IsEmpty() ? sett().GetLastPerspectiveName() : pers_name;
666     if ( m_join_tab &&  m_join_tab->UseBattlePerspective() )
667         perspective_name += BattlePostfix;
668     return perspective_name;
669 }
670 
671 
OnMenuResetLayout(wxCommandEvent &)672 void MainWindow::OnMenuResetLayout( wxCommandEvent& /*event*/ )
673 {
674 	cfg().Write(_T( "/ResetLayout" ), true);
675 	sett().SaveSettings();
676 	customMessageBoxNoModal( SL_MAIN_ICON, IdentityString( _("Please restart %s now") ), wxEmptyString );
677 }
678 
GetTabNames()679 const MainWindow::TabNames& MainWindow::GetTabNames()
680 {
681     return m_tab_names;
682 }
683 
684 #ifdef __WXMSW__
685 	#include <hosting/battleroomtab.h>
686 #endif
687 
LoadPerspectives(const wxString & pers_name)688 void MainWindow::LoadPerspectives( const wxString& pers_name )
689 {
690     sett().SetLastPerspectiveName( pers_name );
691     wxString perspective_name = AddPerspectivePostfix( pers_name );
692 
693     LoadNotebookPerspective( m_func_tabs, perspective_name );
694     m_sp_tab->LoadPerspective( perspective_name );
695     m_join_tab->LoadPerspective( perspective_name );
696     wxWindow* active_chat_tab = static_cast<wxWindow*> ( m_chat_tab->GetActiveChatPanel() );
697     if ( active_chat_tab )
698         active_chat_tab->Refresh();
699     //chat tab saving won't work w/o further work
700 //    m_chat_tab->LoadPerspective( perspective_name );
701 }
702 
SavePerspectives(const wxString & pers_name)703 void MainWindow::SavePerspectives( const wxString& pers_name )
704 {
705     sett().SetLastPerspectiveName( pers_name );
706     wxString perspective_name = AddPerspectivePostfix( pers_name );
707 
708     m_sp_tab->SavePerspective( perspective_name );
709     m_join_tab->SavePerspective( perspective_name );
710 //    m_chat_tab->SavePerspective( perspective_name );
711     SaveNotebookPerspective( m_func_tabs, perspective_name );
712 }
713 
FocusBattleRoomTab()714 void MainWindow::FocusBattleRoomTab()
715 {
716 	m_func_tabs->SetSelection( PAGE_JOIN );
717 	GetJoinTab().FocusBattleRoomTab();
718 }
719 
OnMenuPreferences(wxCommandEvent &)720 void MainWindow::OnMenuPreferences( wxCommandEvent& /*event*/ )
721 {
722 	assert(wxThread::IsMain());
723 	m_opts_dialog = new OptionsDialog( this );
724 	m_opts_dialog->Show();
725 }
726 
OnMenuFirstStart(wxCommandEvent &)727 void MainWindow::OnMenuFirstStart( wxCommandEvent& /*event*/ )
728 {
729 	OpenWebBrowser( _T("https://github.com/springlobby/springlobby/wiki/Userdoc") );
730 }
731 
OnMenuPathInfo(wxCommandEvent &)732 void MainWindow::OnMenuPathInfo( wxCommandEvent& /*event*/ )
733 {
734 	InfoDialog( this ).ShowModal();
735 }
736