Upstream tarball 9744
[amule.git] / src / FriendListCtrl.cpp
blobf514c0363be61575613b2daef086cd326da7acae
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(), wxEmptyString);
95 SetItemPtrData(itemnr, reinterpret_cast<wxUIntPtr>(toadd));
96 RefreshFriend(toadd); // set name and colour
98 //#warning CORE/GUI
99 if (send_to_core) {
100 #ifndef CLIENT_GUI
101 theApp->friendlist->AddFriend(toadd->m_hash, 0, toadd->m_ip, toadd->m_port, 0,toadd->m_name);
102 #endif
107 void CFriendListCtrl::AddFriend(const CMD4Hash& userhash, const wxString& name, uint32 lastUsedIP, uint32 lastUsedPort, bool IsLinked, bool HasFriendSlot, bool send_to_core)
109 CDlgFriend* NewFriend = new CDlgFriend( userhash, name, lastUsedIP, lastUsedPort, IsLinked, HasFriendSlot);
111 AddFriend( NewFriend, send_to_core);
115 void CFriendListCtrl::AddFriend(CUpDownClient* toadd)
117 if ( toadd->IsFriend() ) {
118 return;
121 //#warning CORE/GUI
122 // This links the friend to the client also
123 #ifndef CLIENT_GUI
124 theApp->friendlist->AddFriend(toadd);
125 #endif
127 CDlgFriend* NewFriend = new CDlgFriend( toadd->GetUserHash(), toadd->GetUserName(), toadd->GetIP(), toadd->GetUserPort(), true, false);
129 AddFriend( NewFriend, false/*already sent to core*/ );
133 void CFriendListCtrl::RemoveFriend(CDlgFriend* toremove)
135 if (!toremove) {
136 return;
139 sint32 itemnr = FindItem(-1, reinterpret_cast<wxUIntPtr>(toremove));
141 if ( itemnr == -1 )
142 return;
144 //#warning CORE/GUI
145 #ifndef CLIENT_GUI
146 theApp->friendlist->RemoveFriend(toremove->m_hash, toremove->m_ip, toremove->m_port);
147 #endif
149 DeleteItem(itemnr);
153 void CFriendListCtrl::RefreshFriend(CDlgFriend* toupdate)
155 sint32 itemnr = FindItem(-1, reinterpret_cast<wxUIntPtr>(toupdate));
156 if (itemnr != -1) {
157 SetItem(itemnr, 0, toupdate->m_name);
158 SetItemTextColour(itemnr, toupdate->islinked ? *wxBLUE : *wxBLACK);
160 //#warning CORE/GUI
161 #ifndef CLIENT_GUI
162 theApp->friendlist->UpdateFriendName(toupdate->m_hash, toupdate->m_name, toupdate->m_ip, toupdate->m_port);
163 #endif
167 void CFriendListCtrl::OnItemActivated(wxListEvent& WXUNUSED(event))
169 int cursel = GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
171 CDlgFriend* cur_friend = (CDlgFriend*)GetItemData(cursel);
173 /* ignore this one, it is not activated anymore :) */
174 if (cur_friend == NULL) {
175 return;
178 theApp->amuledlg->m_chatwnd->StartSession(cur_friend);
183 void CFriendListCtrl::LoadList()
185 //#warning EC: ASK THE LIST TO CORE!
187 #ifndef CLIENT_GUI
188 for(FriendList::iterator it = theApp->friendlist->m_FriendList.begin(); it != theApp->friendlist->m_FriendList.end(); ++it) {
189 CFriend* core_friend = *it;
190 AddFriend(core_friend->GetUserHash(), core_friend->GetName(), core_friend->GetIP(), core_friend->GetPort(), (core_friend->GetLinkedClient() != NULL), core_friend->HasFriendSlot(), false);
192 #endif
196 CDlgFriend* CFriendListCtrl::FindFriend(const CMD4Hash& userhash, uint32 dwIP, uint16 nPort)
198 for ( int i = 0; i < GetItemCount(); i++ ) {
199 CDlgFriend* cur_friend = (CDlgFriend*)GetItemData(i);
201 // to avoid that unwanted clients become a friend, we have to distinguish between friends with
202 // a userhash and of friends which are identified by IP+port only.
203 if ( !userhash.IsEmpty() && !cur_friend->m_hash.IsEmpty() ) {
204 // check for a friend which has the same userhash as the specified one
205 if (cur_friend->m_hash == userhash) {
206 return cur_friend;
209 else if (cur_friend->m_ip == dwIP && cur_friend->m_port == nPort) {
210 return cur_friend;
214 return NULL;
217 bool CFriendListCtrl::IsAlreadyFriend( uint32 dwLastUsedIP, uint32 nLastUsedPort )
219 return (FindFriend( CMD4Hash(), dwLastUsedIP, nLastUsedPort ) != NULL);
222 void CFriendListCtrl::OnRightClick(wxMouseEvent& event)
224 int cursel = CheckSelection(event);
226 CDlgFriend* cur_friend = NULL;
228 wxMenu* menu = new wxMenu(_("Friends"));
230 if ( cursel != -1 ) {
231 cur_friend = (CDlgFriend*)GetItemData(cursel);
232 menu->Append(MP_DETAIL, _("Show &Details"));
233 menu->Enable(MP_DETAIL, cur_friend->islinked);
236 menu->Append(MP_ADDFRIEND, _("Add a friend"));
238 if (cursel != (-1)) {
239 menu->Append(MP_REMOVEFRIEND, _("Remove Friend"));
240 menu->Append(MP_MESSAGE, _("Send &Message"));
241 menu->Append(MP_SHOWLIST, _("View Files"));
242 menu->AppendCheckItem(MP_FRIENDSLOT, _("Establish Friend Slot"));
244 if (cur_friend->islinked) {
245 menu->Enable(MP_FRIENDSLOT, true);
246 menu->Check(MP_FRIENDSLOT, cur_friend->hasfriendslot);
247 } else {
248 menu->Enable(MP_FRIENDSLOT, false);
252 PopupMenu(menu, event.GetPosition());
255 void CFriendListCtrl::OnSendMessage(wxCommandEvent& WXUNUSED(event)) {
256 long index = GetNextItem( -1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
258 while( index != -1 ) {
259 CDlgFriend* cur_friend = (CDlgFriend*)GetItemData(index);
260 theApp->amuledlg->m_chatwnd->StartSession(cur_friend);
261 //#warning CORE/GUI!
262 #ifndef CLIENT_GUI
263 theApp->friendlist->StartChatSession(cur_friend->m_hash, cur_friend->m_ip, cur_friend->m_port);
264 #endif
266 index = GetNextItem( index, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
271 void CFriendListCtrl::OnRemoveFriend(wxCommandEvent& WXUNUSED(event))
273 wxString question;
274 if (GetSelectedItemCount() == 1) {
275 question = _("Are you sure that you wish to delete the selected friend?");
276 } else {
277 question = _("Are you sure that you wish to delete the selected friends?");
280 if ( wxMessageBox( question, _("Cancel"), wxICON_QUESTION | wxYES_NO, this) == wxYES ) {
281 long index = GetNextItem( -1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
283 while( index != -1 ) {
284 CDlgFriend* cur_friend = (CDlgFriend*)GetItemData(index);
285 RemoveFriend(cur_friend);
286 // -1 because we changed the list and removed that item.
287 index = GetNextItem( -1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
293 void CFriendListCtrl::OnAddFriend(wxCommandEvent& WXUNUSED(event))
295 CAddFriend(this).ShowModal();
299 void CFriendListCtrl::OnShowDetails(wxCommandEvent& WXUNUSED(event))
301 long index = GetNextItem( -1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
303 while( index != -1 ) {
304 CDlgFriend* cur_friend = (CDlgFriend*)GetItemData(index);
305 if (cur_friend->islinked) {
306 //#warning EC: We need a reply packet with a full CUpDownClient
307 #ifndef CLIENT_GUI
308 CClientDetailDialog
310 this,
311 theApp->friendlist->FindFriend
313 cur_friend->m_hash,
314 cur_friend->m_ip,
315 cur_friend->m_port
316 )->GetLinkedClient()
317 ).ShowModal();
318 #endif
320 index = GetNextItem( index, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
326 void CFriendListCtrl::OnViewFiles(wxCommandEvent& WXUNUSED(event))
328 long index = GetNextItem( -1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
330 while( index != -1 ) {
331 //#warning CORE/GUI!
332 #ifndef CLIENT_GUI
333 CDlgFriend* cur_friend = (CDlgFriend*)GetItemData(index);
334 theApp->friendlist->RequestSharedFileList(cur_friend->m_hash, cur_friend->m_ip, cur_friend->m_port);
335 #endif
336 index = GetNextItem( index, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
342 void CFriendListCtrl::OnSetFriendslot(wxCommandEvent&
343 #ifndef CLIENT_GUI
344 event
345 #endif
348 // Clean friendslots
349 long index = GetNextItem( -1, wxLIST_NEXT_ALL, wxLIST_STATE_DONTCARE);
350 while (index != -1) {
351 CDlgFriend* friend_item = (CDlgFriend*)GetItemData(index);
352 friend_item->hasfriendslot = false;
353 index = GetNextItem( index, wxLIST_NEXT_ALL, wxLIST_STATE_DONTCARE);
355 // Now set the proper one
356 index = GetNextItem( -1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
357 //#warning CORE/GUI!
358 #ifndef CLIENT_GUI
359 CDlgFriend* cur_friend = (CDlgFriend*)GetItemData(index);
360 cur_friend->hasfriendslot = event.IsChecked();
361 theApp->friendlist->SetFriendSlot(cur_friend->m_hash, cur_friend->m_ip, cur_friend->m_port, cur_friend->hasfriendslot);
362 #endif
363 index = GetNextItem( index, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
364 if (index != -1) {
365 wxMessageBox(_("You are not allowed to set more than one friendslot.\n Only one slot was assigned."), _("Multiple selection"), wxOK | wxICON_ERROR, this);
370 void CFriendListCtrl::SetLinked(const CMD4Hash& userhash, uint32 dwIP, uint16 nPort, bool new_state)
372 CDlgFriend* client = FindFriend(CMD4Hash(), dwIP, nPort);
373 if (client) {
374 client->m_hash = userhash;
375 client->islinked = new_state;
376 RefreshFriend(client);
381 void CFriendListCtrl::OnKeyPressed(wxKeyEvent& event)
383 // Check if delete was pressed
384 if ((event.GetKeyCode() == WXK_DELETE) || (event.GetKeyCode() == WXK_NUMPAD_DELETE)) {
385 if (GetItemCount()) {
386 wxCommandEvent evt;
387 evt.SetId( MP_REMOVEFRIEND );
388 OnRemoveFriend( evt );
390 } else {
391 event.Skip();
394 // File_checked_for_headers