1 
2 #include "selectusersdialog.h"
3 
4 #include <wx/string.h>
5 #include <wx/stattext.h>
6 #include <wx/gdicmn.h>
7 #include <wx/font.h>
8 #include <wx/colour.h>
9 #include <wx/settings.h>
10 #include <wx/textctrl.h>
11 #include <wx/sizer.h>
12 #include <wx/listctrl.h>
13 #include <wx/panel.h>
14 #include <wx/statline.h>
15 #include <wx/button.h>
16 #include <wx/tokenzr.h>
17 #include <wx/wupdlock.h>
18 
19 #include "iconimagelist.h"
20 #include "ui.h"
21 #include "userlist.h"
22 #include "server.h"
23 #include "user.h"
24 #include "utils/conversion.h"
25 #include "useractions.h"
26 
27 
BEGIN_EVENT_TABLE(SelectUsersDialog,wxDialog)28 BEGIN_EVENT_TABLE( SelectUsersDialog, wxDialog )
29   EVT_TEXT( FILTER_TEXT, SelectUsersDialog::OnNameFilterChange )
30   EVT_LIST_ITEM_ACTIVATED( NICK_LIST, SelectUsersDialog::OnNameActivated )
31   EVT_LIST_ITEM_DESELECTED( NICK_LIST, SelectUsersDialog::OnNameDeselected )
32   EVT_LIST_ITEM_SELECTED( NICK_LIST, SelectUsersDialog::OnNameSelected )
33   EVT_BUTTON( wxID_CANCEL, SelectUsersDialog::OnCancel )
34   EVT_BUTTON( wxID_OK, SelectUsersDialog::OnOk )
35 END_EVENT_TABLE()
36 
37 SelectUsersDialog::SelectUsersDialog( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style )
38 {
39   this->SetSizeHints( wxDefaultSize, wxDefaultSize );
40 
41   wxBoxSizer* mainSizer;
42   mainSizer = new wxBoxSizer( wxVERTICAL );
43 
44   m_users_panel = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxSize( -1,-1 ), wxTAB_TRAVERSAL );
45   wxBoxSizer* bUsersListSizer;
46   bUsersListSizer = new wxBoxSizer( wxVERTICAL );
47 
48   wxBoxSizer* filterSizer;
49   filterSizer = new wxBoxSizer( wxHORIZONTAL );
50 
51   m_filter_names_staticText = new wxStaticText( m_users_panel, wxID_ANY, _("Filter names"), wxDefaultPosition, wxDefaultSize, 0 );
52   m_filter_names_staticText->Wrap( -1 );
53   filterSizer->Add( m_filter_names_staticText, 0, wxALL|wxALIGN_BOTTOM, 5 );
54 
55   m_name_filter_text = new wxTextCtrl( m_users_panel, FILTER_TEXT, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
56   m_name_filter_text->SetToolTip( _("Enter text filter to filter the online users list") );
57 
58   filterSizer->Add( m_name_filter_text, 1, wxLEFT|wxRIGHT|wxTOP, 5 );
59 
60   bUsersListSizer->Add( filterSizer, 0, wxEXPAND, 5 );
61 
62   m_user_list = new wxListCtrl( m_users_panel, NICK_LIST, wxDefaultPosition, wxDefaultSize, wxLC_REPORT|wxSUNKEN_BORDER|wxLC_SORT_ASCENDING );
63   bUsersListSizer->Add( m_user_list, 1, wxALL|wxEXPAND, 5 );
64 
65   m_users_panel->SetSizer( bUsersListSizer );
66   m_users_panel->Layout();
67   bUsersListSizer->Fit( m_users_panel );
68   mainSizer->Add( m_users_panel, 1, wxEXPAND, 5 );
69 
70   wxBoxSizer* bNameSizer;
71   bNameSizer = new wxBoxSizer( wxHORIZONTAL );
72 
73   m_name_staticText = new wxStaticText( this, wxID_ANY, _("Name"), wxDefaultPosition, wxDefaultSize, 0 );
74   m_name_staticText->Wrap( -1 );
75   bNameSizer->Add( m_name_staticText, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
76 
77   m_selection_text = new wxTextCtrl( this, NAME_TEXT, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
78   bNameSizer->Add( m_selection_text, 1, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
79 
80   mainSizer->Add( bNameSizer, 0, wxEXPAND, 5 );
81 
82   m_buttons_hr = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
83   mainSizer->Add( m_buttons_hr, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
84 
85   m_dialog_buttons = new wxStdDialogButtonSizer();
86   m_dialog_buttonsOK = new wxButton( this, wxID_OK );
87   m_dialog_buttons->AddButton( m_dialog_buttonsOK );
88   m_dialog_buttonsCancel = new wxButton( this, wxID_CANCEL );
89   m_dialog_buttons->AddButton( m_dialog_buttonsCancel );
90   m_dialog_buttons->Realize();
91   mainSizer->Add( m_dialog_buttons, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
92 
93   this->SetSizer( mainSizer );
94   this->Layout();
95 
96   Initialize();
97 }
98 
~SelectUsersDialog()99 SelectUsersDialog::~SelectUsersDialog()
100 {
101   ClearList();
102 }
103 
Initialize()104 void SelectUsersDialog::Initialize()
105 {
106   m_user_list->InsertColumn(0, _("Nickname"), wxLIST_FORMAT_LEFT, 300);
107   m_user_list->SetImageList( &icons(), wxIMAGE_LIST_SMALL );
108   m_user_list->SetImageList( &icons(), wxIMAGE_LIST_NORMAL );
109   m_user_list->SetImageList( &icons(), wxIMAGE_LIST_STATE );
110   PopulateUsersList();
111 }
112 
PopulateUsersList()113 void SelectUsersDialog::PopulateUsersList()
114 {
115   ClearList();
116   if ( ui().IsConnected() ) {
117 	const UserList& userlist = serverSelector().GetServer().GetUserList();
118 
119     wxWindowUpdateLocker noUpdates(m_user_list);
120     for ( unsigned int i = 0; i < userlist.GetNumUsers(); ++i) {
121       wxString name = userlist.GetUser( i ).GetNick();
122       if ( !useractions().IsKnown( name ) && !ui().IsThisMe( name ) ) {
123         wxString country = userlist.GetUser( i ).GetCountry();
124         AddUserToList( name, country );
125       }
126     }
127     Sort();
128   }
129 }
130 
ClearList()131 void SelectUsersDialog::ClearList()
132 {
133     wxWindowUpdateLocker noUpdates(m_user_list);
134   long item = -1;
135   while ( true ) {
136     item = m_user_list->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_DONTCARE);
137     if ( item == -1 )
138       break;
139     RemoveUserFromList( item );
140     item = -1;
141   }
142 }
143 
AddUserToList(const wxString & nick,const wxString & flag)144 long SelectUsersDialog::AddUserToList( const wxString& nick, const wxString& flag )
145 {
146   return AddUserToList(nick, icons().GetFlagIcon(flag) );
147 }
148 
AddUserToList(const wxString & nick,const int & flag)149 long SelectUsersDialog::AddUserToList( const wxString& nick, const int& flag )
150 {
151   long item = m_user_list->InsertItem(0, nick, flag );
152   m_user_list->SetItemData(item, (wxUIntPtr)(new wxString(nick)));
153   return item;
154 }
155 
RemoveUserFromList(long item)156 void SelectUsersDialog::RemoveUserFromList( long item )
157 {
158   delete (wxString*)m_user_list->GetItemData(item);
159   m_user_list->DeleteItem(item);
160 }
161 
UpdateUsersList()162 void SelectUsersDialog::UpdateUsersList()
163 {
164 }
165 
UpdateSelection()166 void SelectUsersDialog::UpdateSelection()
167 {
168   wxArrayString text = GetSelectionFromText();
169   for ( unsigned int i = 0; i < m_selection.Count(); i++ ) {
170     if ( text.Index(m_selection[i], false) == wxNOT_FOUND ) text.Insert( m_selection[i], 0 );
171   }
172 
173   m_selection_text->SetValue(BuildSelectionText( text ));
174 }
175 
BuildSelectionText(const wxSortedArrayString & sel)176 wxString SelectUsersDialog::BuildSelectionText( const wxSortedArrayString& sel )
177 {
178   wxString str;
179   for ( unsigned int i = 0; i < sel.Count(); i++ ) {
180     if ( str != wxEmptyString ) str += _T(";");
181     str += sel[i];
182   }
183   return str;
184 }
185 
GetSelectionFromText()186 wxArrayString SelectUsersDialog::GetSelectionFromText()
187 {
188   wxArrayString s;
189   wxStringTokenizer st(m_selection_text->GetValue(), _T(";, "), wxTOKEN_DEFAULT);
190   while ( st.HasMoreTokens() ) {
191     s.Add(st.GetNextToken());
192   }
193   s.Sort();
194   return s;
195 }
196 
GetUsers(wxWindow * parent)197 wxArrayString SelectUsersDialog::GetUsers(wxWindow* parent)
198 {
199     wxArrayString s;
200     SelectUsersDialog dlg(parent);
201     if ( dlg.ShowModal() == wxID_OK ) {
202         s = dlg.GetSelection();
203         s.Sort();
204     }
205     return s;
206 }
207 
ShowModal()208 int SelectUsersDialog::ShowModal()
209 {
210   m_selection.Clear();
211   return wxDialog::ShowModal();
212 }
213 
OnNameFilterChange(wxCommandEvent &)214 void SelectUsersDialog::OnNameFilterChange( wxCommandEvent& /*unused*/ )
215 {
216   long item = -1;
217   wxString filter = m_name_filter_text->GetValue();
218 
219   wxArrayString del;
220 
221 wxWindowUpdateLocker noUpdates(m_user_list);
222   while ( true ) {
223     item = m_user_list->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_DONTCARE);
224     if ( item == -1 )
225       break;
226 
227     wxString name = m_user_list->GetItemText(item);
228     if ( name == wxEmptyString ) continue;
229 
230     filter.MakeLower();
231     name.MakeLower();
232 
233     if ( (filter != wxEmptyString) && (name.Find(filter) == wxNOT_FOUND) ) {
234       wxListItem listItem;
235       listItem.SetId(item);
236       m_user_list->GetItem(listItem);
237       int flag = listItem.GetImage();
238       name = m_user_list->GetItemText(item); // Preserve case
239       del.Add(name);
240       m_filtered_users.Add( name +_T(" ") + TowxString(flag) );
241     }
242 
243   }
244 
245   if ( del.Count() == (size_t)m_user_list->GetItemCount() ) {
246     m_user_list->DeleteAllItems();
247   } else {
248     for ( unsigned int i = 0; i < del.Count(); i++ ) {
249       long item1 = m_user_list->FindItem(-1, del[i]);
250       RemoveUserFromList(item1);
251     }
252   }
253 
254   wxSortedArrayString sel = GetSelection();
255 
256   for ( int i = m_filtered_users.Count() - 1; i >= 0; i-- )
257   {
258     wxString line = m_filtered_users[i];
259     int sep = line.Find(' ');
260     wxString name = line.Mid(0, sep);
261     if ( name.Find(filter) != wxNOT_FOUND || (filter == wxEmptyString) ) {
262       int flag = (int)FromwxString<long>( line.Mid(sep+1) ); // Flag is never < 0 or > intmax
263       AddUserToList( name, flag );
264       m_filtered_users.RemoveAt(i);
265     }
266   }
267   Sort();
268 
269   for ( unsigned int i = 0; i < sel.Count(); i++ ) {
270     long item1 = m_user_list->FindItem(-1, sel[i]);
271     if ( item1 != -1 )
272       m_user_list->SetItemState(item1, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
273   }
274 
275 }
276 
OnNameActivated(wxListEvent & event)277 void SelectUsersDialog::OnNameActivated( wxListEvent& event )
278 {
279   m_selection.Clear();
280   m_selection.Add(event.GetText());
281   EndModal(wxID_OK);
282 }
283 
OnNameDeselected(wxListEvent & event)284 void SelectUsersDialog::OnNameDeselected( wxListEvent& event )
285 {
286   m_selection.Remove(event.GetText());
287 
288   wxSortedArrayString text = GetSelectionFromText();
289   text.Remove(event.GetText());
290 
291   m_selection_text->SetValue(BuildSelectionText( text ));
292   UpdateSelection();
293 }
294 
OnNameSelected(wxListEvent & event)295 void SelectUsersDialog::OnNameSelected( wxListEvent& event )
296 {
297   m_selection.Remove(event.GetText());
298   m_selection.Add(event.GetText());
299   UpdateSelection();
300 }
301 
OnCancel(wxCommandEvent &)302 void SelectUsersDialog::OnCancel( wxCommandEvent& /*unused*/ )
303 {
304   EndModal(wxID_CANCEL);
305 }
306 
OnOk(wxCommandEvent &)307 void SelectUsersDialog::OnOk( wxCommandEvent& /*unused*/ )
308 {
309   EndModal(wxID_OK);
310 }
311 
312 
GetSelection()313 wxArrayString SelectUsersDialog::GetSelection()
314 {
315   return GetSelectionFromText();
316 }
317 
CompareName(long item1,long item2,long)318 int wxCALLBACK SelectUsersDialog::CompareName(long item1, long item2, long /*unused*/ )
319 {
320   //wxListCtrl* user_list = (wxListCtrl*)sortData;
321   wxString* s1 = (wxString*)item1;
322   wxString* s2 = (wxString*)item2;
323   return (*s1).CmpNoCase(*s2);
324 }
325 
Sort()326 void SelectUsersDialog::Sort()
327 {
328   wxWindowUpdateLocker noUpdates(m_user_list);
329   m_user_list->SortItems(CompareName, (wxUIntPtr)m_user_list);
330 }
331