2 // This file is part of the aMule Project.
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 )
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
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.
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"
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
)
60 CDlgFriend::CDlgFriend(const CMD4Hash
& hash
, const wxString
& name
, uint32 ip
, uint16 port
, bool IsLinked
, bool HasFriendSlot
)
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);
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
102 theApp
->friendlist
->AddFriend(toadd
->m_hash
, 0, toadd
->m_ip
, toadd
->m_port
, 0,toadd
->m_name
);
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() ) {
123 // This links the friend to the client also
125 theApp
->friendlist
->AddFriend(toadd
);
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
)
140 sint32 itemnr
= FindItem(-1, reinterpret_cast<wxUIntPtr
>(toremove
));
147 theApp
->friendlist
->RemoveFriend(toremove
->m_hash
, toremove
->m_ip
, toremove
->m_port
);
154 void CFriendListCtrl::RefreshFriend(CDlgFriend
* toupdate
)
156 sint32 itemnr
= FindItem(-1, reinterpret_cast<wxUIntPtr
>(toupdate
));
158 SetItem(itemnr
, 0, toupdate
->m_name
);
159 SetItemTextColour(itemnr
, toupdate
->islinked
? *wxBLUE
: *wxBLACK
);
163 theApp
->friendlist
->UpdateFriendName(toupdate
->m_hash
, toupdate
->m_name
, toupdate
->m_ip
, toupdate
->m_port
);
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
) {
179 theApp
->amuledlg
->m_chatwnd
->StartSession(cur_friend
);
184 void CFriendListCtrl::LoadList()
186 //#warning EC: ASK THE LIST TO CORE!
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);
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
) {
210 else if (cur_friend
->m_ip
== dwIP
&& cur_friend
->m_port
== nPort
) {
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
);
249 menu
->Enable(MP_FRIENDSLOT
, false);
253 PopupMenu(menu
, event
.GetPosition());
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
);
265 theApp
->friendlist
->StartChatSession(cur_friend
->m_hash
, cur_friend
->m_ip
, cur_friend
->m_port
);
268 index
= GetNextItem( index
, wxLIST_NEXT_ALL
, wxLIST_STATE_SELECTED
);
273 void CFriendListCtrl::OnRemoveFriend(wxCommandEvent
& WXUNUSED(event
))
276 if (GetSelectedItemCount() == 1) {
277 question
= _("Are you sure that you wish to delete the selected friend?");
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
313 theApp
->friendlist
->FindFriend
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 ) {
335 CDlgFriend
* cur_friend
= (CDlgFriend
*)GetItemData(index
);
336 theApp
->friendlist
->RequestSharedFileList(cur_friend
->m_hash
, cur_friend
->m_ip
, cur_friend
->m_port
);
338 index
= GetNextItem( index
, wxLIST_NEXT_ALL
, wxLIST_STATE_SELECTED
);
344 void CFriendListCtrl::OnSetFriendslot(wxCommandEvent
& NOT_ON_REMOTEGUI(event
))
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
);
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
);
361 index
= GetNextItem( index
, wxLIST_NEXT_ALL
, wxLIST_STATE_SELECTED
);
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
);
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()) {
385 evt
.SetId( MP_REMOVEFRIEND
);
386 OnRemoveFriend( evt
);
392 // File_checked_for_headers