Upstream tarball 10019
[amule.git] / src / FriendListCtrl.cpp
blob3d0d40e20ab88a1648d2669fadb9aece288f96ff
1 //
2 // This file is part of the aMule Project.
3 //
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 )
6 //
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
9 // respective authors.
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.
20 //
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
27 #include "FriendListCtrl.h" // Interface declarations
29 #include <common/MenuIDs.h>
30 #include <common/Macros.h>
32 #include "amule.h" // Needed for theApp
33 #include "amuleDlg.h" // Needed for CamuleDlg
34 #include "ClientDetailDialog.h" // Needed for CClientDetailDialog
35 #include "AddFriend.h" // Needed for CAddFriend
36 #include "ChatWnd.h" // Needed for CChatWnd
37 #include "updownclient.h" // Needed for CUpDownClient
38 #include "Friend.h" // Needed for CFriend
39 #include "muuli_wdr.h"
40 #include "SafeFile.h"
42 //#warning REMOVE WHEN EC IS CODED!
43 #include "FriendList.h" // Needed for the friends list
45 BEGIN_EVENT_TABLE(CFriendListCtrl, CMuleListCtrl)
46 EVT_RIGHT_DOWN(CFriendListCtrl::OnRightClick)
47 EVT_LIST_ITEM_ACTIVATED(ID_FRIENDLIST, CFriendListCtrl::OnItemActivated)
49 EVT_MENU(MP_MESSAGE, CFriendListCtrl::OnSendMessage)
50 EVT_MENU(MP_REMOVEFRIEND, CFriendListCtrl::OnRemoveFriend)
51 EVT_MENU(MP_ADDFRIEND, CFriendListCtrl::OnAddFriend)
52 EVT_MENU(MP_DETAIL, CFriendListCtrl::OnShowDetails)
53 EVT_MENU(MP_SHOWLIST, CFriendListCtrl::OnViewFiles)
54 EVT_MENU(MP_FRIENDSLOT, CFriendListCtrl::OnSetFriendslot)
56 EVT_CHAR(CFriendListCtrl::OnKeyPressed)
57 END_EVENT_TABLE()
60 CDlgFriend::CDlgFriend(const CMD4Hash& hash, const wxString& name, uint32 ip, uint16 port, bool IsLinked, bool HasFriendSlot)
62 m_hash = hash;
64 if (name.IsEmpty()) {
65 m_name = wxT("?");
66 } else {
67 m_name = name;
70 m_ip = ip;
71 m_port = port;
72 islinked = IsLinked;
73 hasfriendslot = HasFriendSlot;
77 CFriendListCtrl::CFriendListCtrl(wxWindow* parent, int id, const wxPoint& pos, wxSize siz, int flags)
78 : CMuleListCtrl(parent, id, pos, siz, flags)
80 InsertColumn(0, _("Username"), wxLIST_FORMAT_LEFT, siz.GetWidth() - 4);
82 LoadList();
85 CFriendListCtrl::~CFriendListCtrl()
87 for ( int i = 0; i < GetItemCount(); i++ ) {
88 delete (CDlgFriend*)GetItemData(i);
93 void CFriendListCtrl::AddFriend(CDlgFriend* toadd, bool send_to_core)
95 uint32 itemnr = InsertItem(GetItemCount(), wxEmptyString);
96 SetItemPtrData(itemnr, reinterpret_cast<wxUIntPtr>(toadd));
97 RefreshFriend(toadd); // set name and colour
99 //#warning CORE/GUI
100 if (send_to_core) {
101 #ifndef CLIENT_GUI
102 theApp->friendlist->AddFriend(toadd->m_hash, 0, toadd->m_ip, toadd->m_port, 0,toadd->m_name);
103 #endif
108 void CFriendListCtrl::AddFriend(const CMD4Hash& userhash, const wxString& name, uint32 lastUsedIP, uint32 lastUsedPort, bool IsLinked, bool HasFriendSlot, bool send_to_core)
110 CDlgFriend* NewFriend = new CDlgFriend( userhash, name, lastUsedIP, lastUsedPort, IsLinked, HasFriendSlot);
112 AddFriend( NewFriend, send_to_core);
116 void CFriendListCtrl::AddFriend(CUpDownClient* toadd)
118 if ( toadd->IsFriend() ) {
119 return;
122 //#warning CORE/GUI
123 // This links the friend to the client also
124 #ifndef CLIENT_GUI
125 theApp->friendlist->AddFriend(toadd);
126 #endif
128 CDlgFriend* NewFriend = new CDlgFriend( toadd->GetUserHash(), toadd->GetUserName(), toadd->GetIP(), toadd->GetUserPort(), true, false);
130 AddFriend( NewFriend, false/*already sent to core*/ );
134 void CFriendListCtrl::RemoveFriend(CDlgFriend* toremove)
136 if (!toremove) {
137 return;
140 sint32 itemnr = FindItem(-1, reinterpret_cast<wxUIntPtr>(toremove));
142 if ( itemnr == -1 )
143 return;
145 //#warning CORE/GUI
146 #ifndef CLIENT_GUI
147 theApp->friendlist->RemoveFriend(toremove->m_hash, toremove->m_ip, toremove->m_port);
148 #endif
150 DeleteItem(itemnr);
154 void CFriendListCtrl::RefreshFriend(CDlgFriend* toupdate)
156 sint32 itemnr = FindItem(-1, reinterpret_cast<wxUIntPtr>(toupdate));
157 if (itemnr != -1) {
158 SetItem(itemnr, 0, toupdate->m_name);
159 SetItemTextColour(itemnr, toupdate->islinked ? *wxBLUE : *wxBLACK);
161 //#warning CORE/GUI
162 #ifndef CLIENT_GUI
163 theApp->friendlist->UpdateFriendName(toupdate->m_hash, toupdate->m_name, toupdate->m_ip, toupdate->m_port);
164 #endif
168 void CFriendListCtrl::OnItemActivated(wxListEvent& WXUNUSED(event))
170 int cursel = GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
172 CDlgFriend* cur_friend = (CDlgFriend*)GetItemData(cursel);
174 /* ignore this one, it is not activated anymore :) */
175 if (cur_friend == NULL) {
176 return;
179 theApp->amuledlg->m_chatwnd->StartSession(cur_friend);
184 void CFriendListCtrl::LoadList()
186 //#warning EC: ASK THE LIST TO CORE!
188 #ifndef CLIENT_GUI
189 for(FriendList::iterator it = theApp->friendlist->m_FriendList.begin(); it != theApp->friendlist->m_FriendList.end(); ++it) {
190 CFriend* core_friend = *it;
191 AddFriend(core_friend->GetUserHash(), core_friend->GetName(), core_friend->GetIP(), core_friend->GetPort(), (core_friend->GetLinkedClient() != NULL), core_friend->HasFriendSlot(), false);
193 #endif
197 CDlgFriend* CFriendListCtrl::FindFriend(const CMD4Hash& userhash, uint32 dwIP, uint16 nPort)
199 for ( int i = 0; i < GetItemCount(); i++ ) {
200 CDlgFriend* cur_friend = (CDlgFriend*)GetItemData(i);
202 // to avoid that unwanted clients become a friend, we have to distinguish between friends with
203 // a userhash and of friends which are identified by IP+port only.
204 if ( !userhash.IsEmpty() && !cur_friend->m_hash.IsEmpty() ) {
205 // check for a friend which has the same userhash as the specified one
206 if (cur_friend->m_hash == userhash) {
207 return cur_friend;
210 else if (cur_friend->m_ip == dwIP && cur_friend->m_port == nPort) {
211 return cur_friend;
215 return NULL;
218 bool CFriendListCtrl::IsAlreadyFriend( uint32 dwLastUsedIP, uint32 nLastUsedPort )
220 return (FindFriend( CMD4Hash(), dwLastUsedIP, nLastUsedPort ) != NULL);
223 void CFriendListCtrl::OnRightClick(wxMouseEvent& event)
225 int cursel = CheckSelection(event);
227 CDlgFriend* cur_friend = NULL;
229 wxMenu* menu = new wxMenu(_("Friends"));
231 if ( cursel != -1 ) {
232 cur_friend = (CDlgFriend*)GetItemData(cursel);
233 menu->Append(MP_DETAIL, _("Show &Details"));
234 menu->Enable(MP_DETAIL, cur_friend->islinked);
237 menu->Append(MP_ADDFRIEND, _("Add a friend"));
239 if (cursel != (-1)) {
240 menu->Append(MP_REMOVEFRIEND, _("Remove Friend"));
241 menu->Append(MP_MESSAGE, _("Send &Message"));
242 menu->Append(MP_SHOWLIST, _("View Files"));
243 menu->AppendCheckItem(MP_FRIENDSLOT, _("Establish Friend Slot"));
245 if (cur_friend->islinked) {
246 menu->Enable(MP_FRIENDSLOT, true);
247 menu->Check(MP_FRIENDSLOT, cur_friend->hasfriendslot);
248 } else {
249 menu->Enable(MP_FRIENDSLOT, false);
253 PopupMenu(menu, event.GetPosition());
254 delete menu;
257 void CFriendListCtrl::OnSendMessage(wxCommandEvent& WXUNUSED(event)) {
258 long index = GetNextItem( -1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
260 while( index != -1 ) {
261 CDlgFriend* cur_friend = (CDlgFriend*)GetItemData(index);
262 theApp->amuledlg->m_chatwnd->StartSession(cur_friend);
263 //#warning CORE/GUI!
264 #ifndef CLIENT_GUI
265 theApp->friendlist->StartChatSession(cur_friend->m_hash, cur_friend->m_ip, cur_friend->m_port);
266 #endif
268 index = GetNextItem( index, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
273 void CFriendListCtrl::OnRemoveFriend(wxCommandEvent& WXUNUSED(event))
275 wxString question;
276 if (GetSelectedItemCount() == 1) {
277 question = _("Are you sure that you wish to delete the selected friend?");
278 } else {
279 question = _("Are you sure that you wish to delete the selected friends?");
282 if ( wxMessageBox( question, _("Cancel"), wxICON_QUESTION | wxYES_NO, this) == wxYES ) {
283 long index = GetNextItem( -1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
285 while( index != -1 ) {
286 CDlgFriend* cur_friend = (CDlgFriend*)GetItemData(index);
287 RemoveFriend(cur_friend);
288 // -1 because we changed the list and removed that item.
289 index = GetNextItem( -1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
295 void CFriendListCtrl::OnAddFriend(wxCommandEvent& WXUNUSED(event))
297 CAddFriend(this).ShowModal();
301 void CFriendListCtrl::OnShowDetails(wxCommandEvent& WXUNUSED(event))
303 long index = GetNextItem( -1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
305 while( index != -1 ) {
306 CDlgFriend* cur_friend = (CDlgFriend*)GetItemData(index);
307 if (cur_friend->islinked) {
308 //#warning EC: We need a reply packet with a full CUpDownClient
309 #ifndef CLIENT_GUI
310 CClientDetailDialog
312 this,
313 theApp->friendlist->FindFriend
315 cur_friend->m_hash,
316 cur_friend->m_ip,
317 cur_friend->m_port
318 )->GetLinkedClient()
319 ).ShowModal();
320 #endif
322 index = GetNextItem( index, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
328 void CFriendListCtrl::OnViewFiles(wxCommandEvent& WXUNUSED(event))
330 long index = GetNextItem( -1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
332 while( index != -1 ) {
333 //#warning CORE/GUI!
334 #ifndef CLIENT_GUI
335 CDlgFriend* cur_friend = (CDlgFriend*)GetItemData(index);
336 theApp->friendlist->RequestSharedFileList(cur_friend->m_hash, cur_friend->m_ip, cur_friend->m_port);
337 #endif
338 index = GetNextItem( index, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
344 void CFriendListCtrl::OnSetFriendslot(wxCommandEvent& NOT_ON_REMOTEGUI(event))
346 // Clean friendslots
347 long index = GetNextItem( -1, wxLIST_NEXT_ALL, wxLIST_STATE_DONTCARE);
348 while (index != -1) {
349 CDlgFriend* friend_item = (CDlgFriend*)GetItemData(index);
350 friend_item->hasfriendslot = false;
351 index = GetNextItem( index, wxLIST_NEXT_ALL, wxLIST_STATE_DONTCARE);
353 // Now set the proper one
354 index = GetNextItem( -1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
355 //#warning CORE/GUI!
356 #ifndef CLIENT_GUI
357 CDlgFriend* cur_friend = (CDlgFriend*)GetItemData(index);
358 cur_friend->hasfriendslot = event.IsChecked();
359 theApp->friendlist->SetFriendSlot(cur_friend->m_hash, cur_friend->m_ip, cur_friend->m_port, cur_friend->hasfriendslot);
360 #endif
361 index = GetNextItem( index, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
362 if (index != -1) {
363 wxMessageBox(_("You are not allowed to set more than one friendslot.\n Only one slot was assigned."), _("Multiple selection"), wxOK | wxICON_ERROR, this);
368 void CFriendListCtrl::SetLinked(const CMD4Hash& userhash, uint32 dwIP, uint16 nPort, bool new_state)
370 CDlgFriend* client = FindFriend(CMD4Hash(), dwIP, nPort);
371 if (client) {
372 client->m_hash = userhash;
373 client->islinked = new_state;
374 RefreshFriend(client);
379 void CFriendListCtrl::OnKeyPressed(wxKeyEvent& event)
381 // Check if delete was pressed
382 if ((event.GetKeyCode() == WXK_DELETE) || (event.GetKeyCode() == WXK_NUMPAD_DELETE)) {
383 if (GetItemCount()) {
384 wxCommandEvent evt;
385 evt.SetId( MP_REMOVEFRIEND );
386 OnRemoveFriend( evt );
388 } else {
389 event.Skip();
392 // File_checked_for_headers