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>
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"
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
)
59 CDlgFriend::CDlgFriend(const CMD4Hash
& hash
, const wxString
& name
, uint32 ip
, uint16 port
, bool IsLinked
, bool HasFriendSlot
)
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);
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
101 theApp
->friendlist
->AddFriend(toadd
->m_hash
, 0, toadd
->m_ip
, toadd
->m_port
, 0,toadd
->m_name
);
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() ) {
122 // This links the friend to the client also
124 theApp
->friendlist
->AddFriend(toadd
);
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
)
139 sint32 itemnr
= FindItem(-1, reinterpret_cast<wxUIntPtr
>(toremove
));
146 theApp
->friendlist
->RemoveFriend(toremove
->m_hash
, toremove
->m_ip
, toremove
->m_port
);
153 void CFriendListCtrl::RefreshFriend(CDlgFriend
* toupdate
)
155 sint32 itemnr
= FindItem(-1, reinterpret_cast<wxUIntPtr
>(toupdate
));
157 SetItem(itemnr
, 0, toupdate
->m_name
);
158 SetItemTextColour(itemnr
, toupdate
->islinked
? *wxBLUE
: *wxBLACK
);
162 theApp
->friendlist
->UpdateFriendName(toupdate
->m_hash
, toupdate
->m_name
, toupdate
->m_ip
, toupdate
->m_port
);
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
) {
178 theApp
->amuledlg
->m_chatwnd
->StartSession(cur_friend
);
183 void CFriendListCtrl::LoadList()
185 //#warning EC: ASK THE LIST TO CORE!
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);
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
) {
209 else if (cur_friend
->m_ip
== dwIP
&& cur_friend
->m_port
== nPort
) {
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
);
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
);
263 theApp
->friendlist
->StartChatSession(cur_friend
->m_hash
, cur_friend
->m_ip
, cur_friend
->m_port
);
266 index
= GetNextItem( index
, wxLIST_NEXT_ALL
, wxLIST_STATE_SELECTED
);
271 void CFriendListCtrl::OnRemoveFriend(wxCommandEvent
& WXUNUSED(event
))
274 if (GetSelectedItemCount() == 1) {
275 question
= _("Are you sure that you wish to delete the selected friend?");
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
311 theApp
->friendlist
->FindFriend
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 ) {
333 CDlgFriend
* cur_friend
= (CDlgFriend
*)GetItemData(index
);
334 theApp
->friendlist
->RequestSharedFileList(cur_friend
->m_hash
, cur_friend
->m_ip
, cur_friend
->m_port
);
336 index
= GetNextItem( index
, wxLIST_NEXT_ALL
, wxLIST_STATE_SELECTED
);
342 void CFriendListCtrl::OnSetFriendslot(wxCommandEvent
&
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
);
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
);
363 index
= GetNextItem( index
, wxLIST_NEXT_ALL
, wxLIST_STATE_SELECTED
);
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
);
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()) {
387 evt
.SetId( MP_REMOVEFRIEND
);
388 OnRemoveFriend( evt
);
394 // File_checked_for_headers