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(), toadd
->m_name
);
95 SetItemPtrData(itemnr
, reinterpret_cast<wxUIntPtr
>(toadd
));
100 theApp
->friendlist
->AddFriend(toadd
->m_hash
, 0, toadd
->m_ip
, toadd
->m_port
, 0,toadd
->m_name
);
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() ) {
121 // This links the friend to the client also
123 theApp
->friendlist
->AddFriend(toadd
);
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
)
138 sint32 itemnr
= FindItem(-1, reinterpret_cast<wxUIntPtr
>(toremove
));
145 theApp
->friendlist
->RemoveFriend(toremove
->m_hash
, toremove
->m_ip
, toremove
->m_port
);
152 void CFriendListCtrl::RefreshFriend(CDlgFriend
* toupdate
)
154 sint32 itemnr
= FindItem(-1, reinterpret_cast<wxUIntPtr
>(toupdate
));
156 SetItem(itemnr
, 0, toupdate
->m_name
);
160 theApp
->friendlist
->UpdateFriendName(toupdate
->m_hash
, toupdate
->m_name
, toupdate
->m_ip
, toupdate
->m_port
);
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
) {
176 theApp
->amuledlg
->m_chatwnd
->StartSession(cur_friend
);
181 void CFriendListCtrl::LoadList()
183 //#warning EC: ASK THE LIST TO CORE!
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);
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
) {
207 else if (cur_friend
->m_ip
== dwIP
&& cur_friend
->m_port
== nPort
) {
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
);
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
);
261 theApp
->friendlist
->StartChatSession(cur_friend
->m_hash
, cur_friend
->m_ip
, cur_friend
->m_port
);
264 index
= GetNextItem( index
, wxLIST_NEXT_ALL
, wxLIST_STATE_SELECTED
);
269 void CFriendListCtrl::OnRemoveFriend(wxCommandEvent
& WXUNUSED(event
))
272 if (GetSelectedItemCount() == 1) {
273 question
= _("Are you sure that you wish to delete the selected friend?");
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
309 theApp
->friendlist
->FindFriend
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 ) {
331 CDlgFriend
* cur_friend
= (CDlgFriend
*)GetItemData(index
);
332 theApp
->friendlist
->RequestSharedFileList(cur_friend
->m_hash
, cur_friend
->m_ip
, cur_friend
->m_port
);
334 index
= GetNextItem( index
, wxLIST_NEXT_ALL
, wxLIST_STATE_SELECTED
);
340 void CFriendListCtrl::OnSetFriendslot(wxCommandEvent
&
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"), 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
;
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()) {
384 evt
.SetId( MP_REMOVEFRIEND
);
385 OnRemoveFriend( evt
);
391 // File_checked_for_headers