Upstream tarball 9613
[amule.git] / src / FriendListCtrl.cpp
bloba29b65220033a55cb3fb42ca3cc762755a57f97f
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>
31 #include "amule.h" // Needed for theApp
32 #include "amuleDlg.h" // Needed for CamuleDlg
33 #include "ClientDetailDialog.h" // Needed for CClientDetailDialog
34 #include "AddFriend.h" // Needed for CAddFriend
35 #include "ChatWnd.h" // Needed for CChatWnd
36 #include "updownclient.h" // Needed for CUpDownClient
37 #include "Friend.h" // Needed for CFriend
38 #include "muuli_wdr.h"
39 #include "SafeFile.h"
41 //#warning REMOVE WHEN EC IS CODED!
42 #include "FriendList.h" // Needed for the friends list
44 BEGIN_EVENT_TABLE(CFriendListCtrl, CMuleListCtrl)
45 EVT_RIGHT_DOWN(CFriendListCtrl::OnRightClick)
46 EVT_LIST_ITEM_ACTIVATED(ID_FRIENDLIST, CFriendListCtrl::OnItemActivated)
48 EVT_MENU(MP_MESSAGE, CFriendListCtrl::OnSendMessage)
49 EVT_MENU(MP_REMOVEFRIEND, CFriendListCtrl::OnRemoveFriend)
50 EVT_MENU(MP_ADDFRIEND, CFriendListCtrl::OnAddFriend)
51 EVT_MENU(MP_DETAIL, CFriendListCtrl::OnShowDetails)
52 EVT_MENU(MP_SHOWLIST, CFriendListCtrl::OnViewFiles)
53 EVT_MENU(MP_FRIENDSLOT, CFriendListCtrl::OnSetFriendslot)
55 EVT_CHAR(CFriendListCtrl::OnKeyPressed)
56 END_EVENT_TABLE()
59 CDlgFriend::CDlgFriend(const CMD4Hash& hash, const wxString& name, uint32 ip, uint16 port, bool IsLinked, bool HasFriendSlot)
61 m_hash = hash;
63 if (name.IsEmpty()) {
64 m_name = wxT("?");
65 } else {
66 m_name = name;
69 m_ip = ip;
70 m_port = port;
71 islinked = IsLinked;
72 hasfriendslot = HasFriendSlot;
76 CFriendListCtrl::CFriendListCtrl(wxWindow* parent, int id, const wxPoint& pos, wxSize siz, int flags)
77 : CMuleListCtrl(parent, id, pos, siz, flags)
79 InsertColumn(0, _("Username"), wxLIST_FORMAT_LEFT, siz.GetWidth() - 4);
81 LoadList();
84 CFriendListCtrl::~CFriendListCtrl()
86 for ( int i = 0; i < GetItemCount(); i++ ) {
87 delete (CDlgFriend*)GetItemData(i);
92 void CFriendListCtrl::AddFriend(CDlgFriend* toadd, bool send_to_core)
94 uint32 itemnr = InsertItem(GetItemCount(), toadd->m_name);
95 SetItemPtrData(itemnr, reinterpret_cast<wxUIntPtr>(toadd));
97 //#warning CORE/GUI
98 if (send_to_core) {
99 #ifndef CLIENT_GUI
100 theApp->friendlist->AddFriend(toadd->m_hash, 0, toadd->m_ip, toadd->m_port, 0,toadd->m_name);
101 #endif
106 void CFriendListCtrl::AddFriend(const CMD4Hash& userhash, const wxString& name, uint32 lastUsedIP, uint32 lastUsedPort, bool IsLinked, bool HasFriendSlot, bool send_to_core)
108 CDlgFriend* NewFriend = new CDlgFriend( userhash, name, lastUsedIP, lastUsedPort, IsLinked, HasFriendSlot);
110 AddFriend( NewFriend, send_to_core);
114 void CFriendListCtrl::AddFriend(CUpDownClient* toadd)
116 if ( toadd->IsFriend() ) {
117 return;
120 //#warning CORE/GUI
121 // This links the friend to the client also
122 #ifndef CLIENT_GUI
123 theApp->friendlist->AddFriend(toadd);
124 #endif
126 CDlgFriend* NewFriend = new CDlgFriend( toadd->GetUserHash(), toadd->GetUserName(), toadd->GetIP(), toadd->GetUserPort(), true, false);
128 AddFriend( NewFriend, false/*already sent to core*/ );
132 void CFriendListCtrl::RemoveFriend(CDlgFriend* toremove)
134 if (!toremove) {
135 return;
138 sint32 itemnr = FindItem(-1, reinterpret_cast<wxUIntPtr>(toremove));
140 if ( itemnr == -1 )
141 return;
143 //#warning CORE/GUI
144 #ifndef CLIENT_GUI
145 theApp->friendlist->RemoveFriend(toremove->m_hash, toremove->m_ip, toremove->m_port);
146 #endif
148 DeleteItem(itemnr);
152 void CFriendListCtrl::RefreshFriend(CDlgFriend* toupdate)
154 sint32 itemnr = FindItem(-1, reinterpret_cast<wxUIntPtr>(toupdate));
155 if (itemnr != -1) {
156 SetItem(itemnr, 0, toupdate->m_name);
158 //#warning CORE/GUI
159 #ifndef CLIENT_GUI
160 theApp->friendlist->UpdateFriendName(toupdate->m_hash, toupdate->m_name, toupdate->m_ip, toupdate->m_port);
161 #endif
165 void CFriendListCtrl::OnItemActivated(wxListEvent& WXUNUSED(event))
167 int cursel = GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
169 CDlgFriend* cur_friend = (CDlgFriend*)GetItemData(cursel);
171 /* ignore this one, it is not activated anymore :) */
172 if (cur_friend == NULL) {
173 return;
176 theApp->amuledlg->m_chatwnd->StartSession(cur_friend);
181 void CFriendListCtrl::LoadList()
183 //#warning EC: ASK THE LIST TO CORE!
185 #ifndef CLIENT_GUI
186 for(FriendList::iterator it = theApp->friendlist->m_FriendList.begin(); it != theApp->friendlist->m_FriendList.end(); ++it) {
187 CFriend* core_friend = *it;
188 AddFriend(core_friend->GetUserHash(), core_friend->GetName(), core_friend->GetIP(), core_friend->GetPort(), (core_friend->GetLinkedClient() != NULL), core_friend->HasFriendSlot(), false);
190 #endif
194 CDlgFriend* CFriendListCtrl::FindFriend(const CMD4Hash& userhash, uint32 dwIP, uint16 nPort)
196 for ( int i = 0; i < GetItemCount(); i++ ) {
197 CDlgFriend* cur_friend = (CDlgFriend*)GetItemData(i);
199 // to avoid that unwanted clients become a friend, we have to distinguish between friends with
200 // a userhash and of friends which are identified by IP+port only.
201 if ( !userhash.IsEmpty() && !cur_friend->m_hash.IsEmpty() ) {
202 // check for a friend which has the same userhash as the specified one
203 if (cur_friend->m_hash == userhash) {
204 return cur_friend;
207 else if (cur_friend->m_ip == dwIP && cur_friend->m_port == nPort) {
208 return cur_friend;
212 return NULL;
215 bool CFriendListCtrl::IsAlreadyFriend( uint32 dwLastUsedIP, uint32 nLastUsedPort )
217 return (FindFriend( CMD4Hash(), dwLastUsedIP, nLastUsedPort ) != NULL);
220 void CFriendListCtrl::OnRightClick(wxMouseEvent& event)
222 int cursel = CheckSelection(event);
224 CDlgFriend* cur_friend = NULL;
226 wxMenu* menu = new wxMenu(_("Friends"));
228 if ( cursel != -1 ) {
229 cur_friend = (CDlgFriend*)GetItemData(cursel);
230 menu->Append(MP_DETAIL, _("Show &Details"));
231 menu->Enable(MP_DETAIL, cur_friend->islinked);
234 menu->Append(MP_ADDFRIEND, _("Add a friend"));
236 if (cursel != (-1)) {
237 menu->Append(MP_REMOVEFRIEND, _("Remove Friend"));
238 menu->Append(MP_MESSAGE, _("Send &Message"));
239 menu->Append(MP_SHOWLIST, _("View Files"));
240 menu->AppendCheckItem(MP_FRIENDSLOT, _("Establish Friend Slot"));
242 if (cur_friend->islinked) {
243 menu->Enable(MP_FRIENDSLOT, true);
244 menu->Check(MP_FRIENDSLOT, cur_friend->hasfriendslot);
245 } else {
246 menu->Enable(MP_FRIENDSLOT, false);
250 PopupMenu(menu, event.GetPosition());
253 void CFriendListCtrl::OnSendMessage(wxCommandEvent& WXUNUSED(event)) {
254 long index = GetNextItem( -1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
256 while( index != -1 ) {
257 CDlgFriend* cur_friend = (CDlgFriend*)GetItemData(index);
258 theApp->amuledlg->m_chatwnd->StartSession(cur_friend);
259 //#warning CORE/GUI!
260 #ifndef CLIENT_GUI
261 theApp->friendlist->StartChatSession(cur_friend->m_hash, cur_friend->m_ip, cur_friend->m_port);
262 #endif
264 index = GetNextItem( index, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
269 void CFriendListCtrl::OnRemoveFriend(wxCommandEvent& WXUNUSED(event))
271 wxString question;
272 if (GetSelectedItemCount() == 1) {
273 question = _("Are you sure that you wish to delete the selected friend?");
274 } else {
275 question = _("Are you sure that you wish to delete the selected friends?");
278 if ( wxMessageBox( question, _("Cancel"), wxICON_QUESTION | wxYES_NO, this) == wxYES ) {
279 long index = GetNextItem( -1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
281 while( index != -1 ) {
282 CDlgFriend* cur_friend = (CDlgFriend*)GetItemData(index);
283 RemoveFriend(cur_friend);
284 // -1 because we changed the list and removed that item.
285 index = GetNextItem( -1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
291 void CFriendListCtrl::OnAddFriend(wxCommandEvent& WXUNUSED(event))
293 CAddFriend(this).ShowModal();
297 void CFriendListCtrl::OnShowDetails(wxCommandEvent& WXUNUSED(event))
299 long index = GetNextItem( -1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
301 while( index != -1 ) {
302 CDlgFriend* cur_friend = (CDlgFriend*)GetItemData(index);
303 if (cur_friend->islinked) {
304 //#warning EC: We need a reply packet with a full CUpDownClient
305 #ifndef CLIENT_GUI
306 CClientDetailDialog
308 this,
309 theApp->friendlist->FindFriend
311 cur_friend->m_hash,
312 cur_friend->m_ip,
313 cur_friend->m_port
314 )->GetLinkedClient()
315 ).ShowModal();
316 #endif
318 index = GetNextItem( index, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
324 void CFriendListCtrl::OnViewFiles(wxCommandEvent& WXUNUSED(event))
326 long index = GetNextItem( -1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
328 while( index != -1 ) {
329 //#warning CORE/GUI!
330 #ifndef CLIENT_GUI
331 CDlgFriend* cur_friend = (CDlgFriend*)GetItemData(index);
332 theApp->friendlist->RequestSharedFileList(cur_friend->m_hash, cur_friend->m_ip, cur_friend->m_port);
333 #endif
334 index = GetNextItem( index, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
340 void CFriendListCtrl::OnSetFriendslot(wxCommandEvent&
341 #ifndef CLIENT_GUI
342 event
343 #endif
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"), 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;
378 void CFriendListCtrl::OnKeyPressed(wxKeyEvent& event)
380 // Check if delete was pressed
381 if ((event.GetKeyCode() == WXK_DELETE) || (event.GetKeyCode() == WXK_NUMPAD_DELETE)) {
382 if (GetItemCount()) {
383 wxCommandEvent evt;
384 evt.SetId( MP_REMOVEFRIEND );
385 OnRemoveFriend( evt );
387 } else {
388 event.Skip();
391 // File_checked_for_headers