Don't allow autoconf 2.70, it's known to fail
[amule.git] / src / amule-remote-gui.h
blob26bc1e3a7bb9098b520c5c2535803a990e0bc91f
1 //
2 // This file is part of the aMule Project.
3 //
4 // Copyright (c) 2005-2011 aMule Team ( admin@amule.org / http://www.amule.org )
5 //
6 // Any parts of this program derived from the xMule, lMule or eMule project,
7 // or contributed by third-party developers are copyrighted by their
8 // respective authors.
9 //
10 // This program is free software; you can redistribute it and/or modify
11 // it under the terms of the GNU General Public License as published by
12 // the Free Software Foundation; either version 2 of the License, or
13 // (at your option) any later version.
15 // This program is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
20 // You should have received a copy of the GNU General Public License
21 // along with this program; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #ifndef AMULE_REMOTE_GUI_H
26 #define AMULE_REMOTE_GUI_H
29 #include <ec/cpp/RemoteConnect.h> // Needed for CRemoteConnect
32 #include "Statistics.h"
33 #include "Preferences.h"
34 #include "Statistics.h"
35 #include "RLE.h"
36 #include "SearchList.h" // Needed for CSearchFile
37 #include "kademlia/utils/UInt128.h" // Needed for CUInt128
39 class CED2KFileLink;
40 class CServer;
41 class CKnownFile;
42 class CSearchFile;
43 class CPartFile;
44 class CClientRef;
45 class CStatistics;
46 class CPath;
48 class wxEvtHandler;
49 class wxTimer;
50 class wxTimerEvent;
52 #include <wx/dialog.h>
54 class CEConnectDlg : public wxDialog {
55 wxString host;
56 int port;
58 wxString pwd_hash;
59 wxString login, passwd;
60 bool m_save_user_pass;
62 DECLARE_EVENT_TABLE()
63 public:
64 CEConnectDlg();
66 void OnOK(wxCommandEvent& event);
68 wxString Host() { return host; }
69 int Port() { return port; }
71 wxString Login() { return login; }
72 wxString PassHash();
73 bool SaveUserPass() { return m_save_user_pass; }
76 DECLARE_LOCAL_EVENT_TYPE(wxEVT_EC_INIT_DONE, wxEVT_USER_FIRST + 1001)
78 class wxECInitDoneEvent : public wxEvent {
79 public:
80 wxECInitDoneEvent() : wxEvent(-1, wxEVT_EC_INIT_DONE)
84 wxEvent *Clone(void) const
86 return new wxECInitDoneEvent(*this);
90 class CPreferencesRem : public CPreferences, public CECPacketHandlerBase {
91 CRemoteConnect *m_conn;
92 uint32 m_exchange_send_selected_prefs;
93 uint32 m_exchange_recv_selected_prefs;
95 virtual void HandlePacket(const CECPacket *packet);
96 public:
97 CPreferencesRem(CRemoteConnect *);
99 bool CreateCategory(Category_Struct *& category, const wxString& name, const CPath& path,
100 const wxString& comment, uint32 color, uint8 prio);
101 bool UpdateCategory(uint8 cat, const wxString& name, const CPath& path,
102 const wxString& comment, uint32 color, uint8 prio);
104 void RemoveCat(uint8 cat);
106 bool LoadRemote();
107 void SendToRemote();
111 // T - type if item in container
112 // I - type of id of item
113 // G - type of tag used to create/update items
115 template <class T, class I, class G = CECTag>
116 class CRemoteContainer : public CECPacketHandlerBase {
117 protected:
118 enum {
119 IDLE, // no request in the air
120 STATUS_REQ_SENT, // sent request for item status
121 FULL_REQ_SENT // sent request for full info
122 } m_state;
124 CRemoteConnect *m_conn;
126 std::list<T *> m_items;
127 std::map<I, T *> m_items_hash;
129 // .size() is O(N) operation in stl
130 int m_item_count;
132 // use incremental tags algorithm
133 bool m_inc_tags;
135 // command that will be used in full request
136 int m_full_req_cmd, m_full_req_tag;
138 virtual void HandlePacket(const CECPacket *packet)
140 switch(this->m_state) {
141 case IDLE: wxFAIL; break; // not expecting anything
142 case STATUS_REQ_SENT:
143 // if derived class choose not to proceed, return - but with good status
144 this->m_state = IDLE;
145 if ( this->Phase1Done(packet) ) {
146 if (this->m_inc_tags) {
147 // Incremental tags: new items always carry full info.
148 ProcessUpdate(packet, NULL, m_full_req_tag);
149 } else {
150 // Non-incremental tags: we might get partial info on new items.
151 // Collect all this items in a tag, and then request full info about them.
152 CECPacket req_full(this->m_full_req_cmd);
154 ProcessUpdate(packet, &req_full, m_full_req_tag);
156 // Phase 3: request full info about files we don't have yet
157 if ( req_full.HasChildTags() ) {
158 m_conn->SendRequest(this, &req_full);
159 this->m_state = FULL_REQ_SENT;
163 break;
164 case FULL_REQ_SENT:
165 ProcessFull(packet);
166 m_state = IDLE;
167 break;
170 public:
171 CRemoteContainer(CRemoteConnect *conn, bool inc_tags)
172 : m_state(IDLE),
173 m_conn(conn),
174 m_item_count(0),
175 m_inc_tags(inc_tags),
176 m_full_req_cmd(0),
177 m_full_req_tag(0)
180 virtual ~CRemoteContainer()
183 typedef typename std::list<T *>::iterator iterator;
184 iterator begin() { return m_items.begin(); }
185 iterator end() { return m_items.end(); }
187 uint32 GetCount()
189 return m_item_count;
192 void AddItem(T *item)
194 m_items.push_back(item);
195 m_items_hash[GetItemID(item)] = item;
196 m_item_count++;
199 T *GetByID(I id)
201 // avoid creating nodes
202 return m_items_hash.count(id) ? m_items_hash[id] : NULL;
205 void Flush()
207 m_items.clear();
208 m_items_hash.clear();
209 m_item_count = 0;
213 // Flush & reload
216 We usually don't keep outdated code as comments, but this blocking implementation
217 shows the overall procedure well. It had to be scattered for the event driven implementation.
219 bool FullReload(int cmd)
221 CECPacket req(cmd);
222 CScopedPtr<const CECPacket> reply(this->m_conn->SendRecvPacket(&req));
223 if ( !reply.get() ) {
224 return false;
226 for(typename std::list<T *>::iterator j = this->m_items.begin(); j != this->m_items.end(); j++) {
227 this->DeleteItem(*j);
230 Flush();
232 ProcessFull(reply.get());
234 return true;
237 void FullReload(int cmd)
239 if ( this->m_state != IDLE ) {
240 return;
243 for(typename std::list<T *>::iterator j = this->m_items.begin(); j != this->m_items.end(); ++j) {
244 this->DeleteItem(*j);
247 Flush();
249 CECPacket req(cmd);
250 this->m_conn->SendRequest(this, &req);
251 this->m_state = FULL_REQ_SENT;
252 this->m_full_req_cmd = cmd;
256 // Following are like basicly same code as in webserver. Eventually it must
257 // be same class
259 void DoRequery(int cmd, int tag)
261 if ( this->m_state != IDLE ) {
262 return;
264 CECPacket req_sts(cmd, m_inc_tags ? EC_DETAIL_INC_UPDATE : EC_DETAIL_UPDATE);
265 this->m_conn->SendRequest(this, &req_sts);
266 this->m_state = STATUS_REQ_SENT;
267 this->m_full_req_cmd = cmd;
268 this->m_full_req_tag = tag;
271 We usually don't keep outdated code as comments, but this blocking implementation
272 shows the overall procedure well. It had to be scattered for the event driven implementation.
274 bool DoRequery(int cmd, int tag)
276 CECPacket req_sts(cmd, m_inc_tags ? EC_DETAIL_INC_UPDATE : EC_DETAIL_UPDATE);
279 // Phase 1: request status
280 CScopedPtr<const CECPacket> reply(this->m_conn->SendRecvPacket(&req_sts));
281 if ( !reply.get() ) {
282 return false;
285 if ( !this->Phase1Done(reply.get()) ) {
286 // if derived class choose not to proceed, return - but with good status
287 return true;
290 // Phase 2: update status, mark new files for subsequent query
291 CECPacket req_full(cmd);
293 ProcessUpdate(reply.get(), &req_full, tag);
295 reply.reset();
297 if ( !m_inc_tags ) {
298 // Phase 3: request full info about files we don't have yet
299 if ( req_full.GetTagCount() ) {
300 reply.reset(this->m_conn->SendRecvPacket(&req_full));
301 if ( !reply.get() ) {
302 return false;
304 ProcessFull(reply.get());
307 return true;
311 void ProcessFull(const CECPacket *reply)
313 for (CECPacket::const_iterator it = reply->begin(); it != reply->end(); ++it) {
314 const G *tag = static_cast<const G *>(&*it);
315 // initialize item data from EC tag
316 AddItem(CreateItem(tag));
320 void RemoveItem(iterator & it)
322 I item_id = GetItemID(*it);
323 // reduce count
324 m_item_count--;
325 // remove from map
326 m_items_hash.erase(item_id);
327 // item may contain data that need to be freed externally, before
328 // dtor is called and memory freed
329 DeleteItem(*it);
331 m_items.erase(it);
334 virtual void ProcessUpdate(const CECTag *reply, CECPacket *full_req, int req_type)
336 std::set<I> core_files;
337 for (CECPacket::const_iterator it = reply->begin(); it != reply->end(); ++it) {
338 const G *tag = static_cast<const G *>(&*it);
339 if ( tag->GetTagName() != req_type ) {
340 continue;
343 core_files.insert(tag->ID());
344 if ( m_items_hash.count(tag->ID()) ) {
345 // Item already known: update it
346 T *item = m_items_hash[tag->ID()];
347 ProcessItemUpdate(tag, item);
348 } else {
349 // New item
350 if (full_req) {
351 // Non-incremental mode: we have only partial info
352 // so we need to request full info before we can use the item
353 full_req->AddTag(CECTag(req_type, tag->ID()));
354 } else {
355 // Incremental mode: new items always carry full info,
356 // so we can add it right away
357 AddItem(CreateItem(tag));
361 for(iterator it = begin(); it != end();) {
362 iterator it2 = it++;
363 if ( core_files.count(GetItemID(*it2)) == 0 ) {
364 RemoveItem(it2);
369 virtual T *CreateItem(const G *)
371 return 0;
373 virtual void DeleteItem(T *)
376 virtual I GetItemID(T *)
378 return I();
380 virtual void ProcessItemUpdate(const G *, T *)
384 virtual bool Phase1Done(const CECPacket *)
386 return true;
390 class CServerConnectRem {
391 CRemoteConnect *m_Conn;
392 uint32 m_ID;
394 CServer *m_CurrServer;
396 public:
397 void HandlePacket(const CECPacket *packet);
399 CServerConnectRem(CRemoteConnect *);
401 bool IsConnected() { return (m_ID != 0) && (m_ID != 0xffffffff); }
402 bool IsConnecting() { return m_ID == 0xffffffff; }
403 bool IsLowID() { return m_ID < 16777216; }
404 uint32 GetClientID() { return m_ID; }
405 CServer *GetCurrentServer() { return m_CurrServer; }
408 // Actions
410 void ConnectToServer(CServer* server);
411 void ConnectToAnyServer();
412 void StopConnectionTry();
413 void Disconnect();
416 class CServerListRem : public CRemoteContainer<CServer, uint32, CEC_Server_Tag> {
417 uint32 m_TotalUser, m_TotalFile;
419 virtual void HandlePacket(const CECPacket *packet);
420 public:
421 CServerListRem(CRemoteConnect *);
422 void GetUserFileStatus(uint32 &total_user, uint32 &total_file)
424 total_user = m_TotalUser;
425 total_file = m_TotalFile;
428 void UpdateUserFileStatus(CServer *server);
430 CServer* GetServerByAddress(const wxString& address, uint16 port) const;
431 CServer* GetServerByIPTCP(uint32 nIP, uint16 nPort) const;
434 // Actions
436 void RemoveServer(CServer* server);
437 void UpdateServerMetFromURL(wxString url);
438 void SetStaticServer(CServer* server, bool isStatic);
439 void SetServerPrio(CServer* server, uint32 prio);
440 void SaveServerMet() {} // not needed here
441 void FilterServers() {} // not needed here
444 // template
446 CServer *CreateItem(const CEC_Server_Tag *);
447 void DeleteItem(CServer *);
448 uint32 GetItemID(CServer *);
449 void ProcessItemUpdate(const CEC_Server_Tag *, CServer *);
452 class CUpDownClientListRem : public CRemoteContainer<CClientRef, uint32, CEC_UpDownClient_Tag> {
453 public:
454 CUpDownClientListRem(CRemoteConnect *);
456 void FilterQueues() {} // not needed here
458 // template
460 CClientRef *CreateItem(const CEC_UpDownClient_Tag *);
461 void DeleteItem(CClientRef *);
462 uint32 GetItemID(CClientRef *);
463 void ProcessItemUpdate(const CEC_UpDownClient_Tag *, CClientRef *);
466 class CDownQueueRem : public std::map<uint32, CPartFile*> {
467 CRemoteConnect *m_conn;
468 public:
469 CDownQueueRem(CRemoteConnect * conn) { m_conn = conn; }
471 CPartFile* GetFileByID(uint32 id);
474 // User actions
476 void Prio(CPartFile *file, uint8 prio);
477 void AutoPrio(CPartFile *file, bool flag);
478 void Category(CPartFile *file, uint8 cat);
480 void SendFileCommand(CPartFile *file, ec_tagname_t cmd);
482 // Actions
484 void StopUDPRequests() {}
485 void AddFileLinkToDownload(CED2KFileLink*, uint8);
486 bool AddLink(const wxString &link, uint8 category = 0);
487 void UnsetCompletedFilesExist();
488 void ResetCatParts(int cat);
489 void AddSearchToDownload(CSearchFile* toadd, uint8 category);
490 void ClearCompleted(const ListOfUInts32 & ecids);
493 class CSharedFilesRem : public std::map<uint32, CKnownFile*> {
494 CRemoteConnect *m_conn;
495 public:
496 CSharedFilesRem(CRemoteConnect * conn);
498 CKnownFile *GetFileByID(uint32 id);
500 void SetFilePrio(CKnownFile *file, uint8 prio);
503 // Actions
505 void Reload(bool sendtoserver = true, bool firstload = false);
506 bool RenameFile(CKnownFile* file, const CPath& newName);
507 void SetFileCommentRating(CKnownFile* file, const wxString& newComment, int8 newRating);
508 void CopyFileList(std::vector<CKnownFile*>& out_list) const;
511 class CKnownFilesRem : public CRemoteContainer<CKnownFile, uint32, CEC_SharedFile_Tag> {
512 CKnownFile * CreateKnownFile(const CEC_SharedFile_Tag *tag, CKnownFile *file = NULL);
513 CPartFile * CreatePartFile(const CEC_PartFile_Tag *tag);
515 bool m_initialUpdate; // improved handling for first data transfer
516 public:
517 CKnownFilesRem(CRemoteConnect * conn);
519 CKnownFile *FindKnownFileByID(uint32 id) { return GetByID(id); }
521 uint16 requested;
522 uint32 transferred;
523 uint16 accepted;
526 // template
528 CKnownFile *CreateItem(const CEC_SharedFile_Tag *) { wxFAIL; return NULL; } // unused, required by template
529 void DeleteItem(CKnownFile *);
530 uint32 GetItemID(CKnownFile *);
531 void ProcessItemUpdate(const CEC_SharedFile_Tag *, CKnownFile *);
532 bool Phase1Done(const CECPacket *) { return true; }
533 void ProcessUpdate(const CECTag *reply, CECPacket *full_req, int req_type);
535 void ProcessItemUpdatePartfile(const CEC_PartFile_Tag *, CPartFile *);
538 class CIPFilterRem {
539 CRemoteConnect *m_conn;
540 public:
541 CIPFilterRem(CRemoteConnect *conn);
544 // Actions
546 void Reload();
547 void Update(wxString strURL = wxEmptyString);
548 bool IsReady() const { return true; }
551 class CSearchListRem : public CRemoteContainer<CSearchFile, uint32, CEC_SearchFile_Tag> {
552 virtual void HandlePacket(const CECPacket *);
553 public:
554 CSearchListRem(CRemoteConnect *);
556 int m_curr_search;
557 typedef std::map<long, CSearchResultList> ResultMap;
558 ResultMap m_results;
560 const CSearchResultList& GetSearchResults(long nSearchID);
561 void RemoveResults(long nSearchID);
562 const CSearchResultList& GetSearchResults(long nSearchID) const;
564 // Actions
567 wxString StartNewSearch(uint32* nSearchID, SearchType search_type,
568 const CSearchList::CSearchParams& params);
570 void StopSearch(bool globalOnly = false);
573 // template
575 CSearchFile *CreateItem(const CEC_SearchFile_Tag *);
576 void DeleteItem(CSearchFile *);
577 uint32 GetItemID(CSearchFile *);
578 void ProcessItemUpdate(const CEC_SearchFile_Tag *, CSearchFile *);
579 bool Phase1Done(const CECPacket *);
582 class CFriendListRem : public CRemoteContainer<CFriend, uint32, CEC_Friend_Tag> {
583 virtual void HandlePacket(const CECPacket *);
584 public:
585 CFriendListRem(CRemoteConnect *);
587 void AddFriend(const CClientRef& toadd);
588 void AddFriend(const CMD4Hash& userhash, uint32 lastUsedIP, uint32 lastUsedPort, const wxString& name);
589 void RemoveFriend(CFriend* toremove);
590 void RequestSharedFileList(CFriend* Friend);
591 void RequestSharedFileList(CClientRef& client);
592 void SetFriendSlot(CFriend* Friend, bool new_state);
595 // template
597 CFriend *CreateItem(const CEC_Friend_Tag *);
598 void DeleteItem(CFriend *);
599 uint32 GetItemID(CFriend *);
600 void ProcessItemUpdate(const CEC_Friend_Tag *, CFriend *);
603 class CStatsUpdaterRem : public CECPacketHandlerBase {
604 virtual void HandlePacket(const CECPacket *);
605 public:
606 CStatsUpdaterRem() {}
609 class CStatTreeRem : public CECPacketHandlerBase {
610 virtual void HandlePacket(const CECPacket *);
611 CRemoteConnect *m_conn;
612 public:
613 CStatTreeRem(CRemoteConnect * conn) { m_conn = conn; }
614 void DoRequery();
617 class CListenSocketRem {
618 uint32 m_peak_connections;
619 public:
620 uint32 GetPeakConnections() { return m_peak_connections; }
623 class CamuleRemoteGuiApp : public wxApp, public CamuleGuiBase, public CamuleAppCommon {
624 wxTimer* poll_timer;
626 virtual int InitGui(bool geometry_enable, wxString &geometry_string);
628 bool OnInit();
630 int OnExit();
632 void OnPollTimer(wxTimerEvent& evt);
634 void OnECConnection(wxEvent& event);
635 void OnECInitDone(wxEvent& event);
636 void OnNotifyEvent(CMuleGUIEvent& evt);
637 void OnFinishedHTTPDownload(CMuleInternalEvent& event);
639 CStatsUpdaterRem m_stats_updater;
640 public:
642 void Startup();
644 bool ShowConnectionDialog();
646 class CRemoteConnect *m_connect;
648 CEConnectDlg *dialog;
650 bool CopyTextToClipboard(wxString strText);
652 virtual int ShowAlert(wxString msg, wxString title, int flags);
654 void ShutDown(wxCloseEvent &evt);
656 CPreferencesRem *glob_prefs;
658 #ifdef ASIO_SOCKETS
659 CAsioService* m_AsioService;
660 #endif
663 // Provide access to core data thru EC
664 CServerConnectRem *serverconnect;
665 CServerListRem *serverlist;
666 CDownQueueRem *downloadqueue;
667 CSharedFilesRem *sharedfiles;
668 CKnownFilesRem *knownfiles;
669 CUpDownClientListRem *clientlist;
670 CIPFilterRem *ipfilter;
671 CSearchListRem *searchlist;
672 CFriendListRem *friendlist;
673 CListenSocketRem *listensocket;
674 CStatTreeRem * stattree;
676 CStatistics *m_statistics;
678 bool AddServer(CServer *srv, bool fromUser = false);
680 uint32 GetPublicIP();
682 wxString GetLog(bool reset = false);
683 wxString GetServerLog(bool reset = false);
685 void AddServerMessageLine(wxString &msg);
686 void AddRemoteLogLine(const wxString& line);
688 void SetOSFiles(wxString ) { /* onlinesig is created on remote side */ }
690 bool IsConnected() const { return IsConnectedED2K() || IsConnectedKad(); }
691 bool IsFirewalled() const;
692 bool IsConnectedED2K() const;
693 bool IsConnectedKad() const
695 return ((m_ConnState & CONNECTED_KAD_OK)
696 || (m_ConnState & CONNECTED_KAD_FIREWALLED));
698 bool IsFirewalledKad() const { return (m_ConnState & CONNECTED_KAD_FIREWALLED) != 0; }
700 bool IsKadRunning() const { return ((m_ConnState & CONNECTED_KAD_OK)
701 || (m_ConnState & CONNECTED_KAD_FIREWALLED)
702 || (m_ConnState & CONNECTED_KAD_NOT)); }
704 // Check Kad state (UDP)
705 bool IsFirewalledKadUDP() const { return theStats::IsFirewalledKadUDP(); }
706 bool IsKadRunningInLanMode() const { return theStats::IsKadRunningInLanMode(); }
707 // Kad stats
708 uint32 GetKadUsers() const { return theStats::GetKadUsers(); }
709 uint32 GetKadFiles() const { return theStats::GetKadFiles(); }
710 uint32 GetKadIndexedSources() const { return theStats::GetKadIndexedSources(); }
711 uint32 GetKadIndexedKeywords() const{ return theStats::GetKadIndexedKeywords(); }
712 uint32 GetKadIndexedNotes() const { return theStats::GetKadIndexedNotes(); }
713 uint32 GetKadIndexedLoad() const { return theStats::GetKadIndexedLoad(); }
714 const CUInt128& GetKadID() const { return m_kadID; }
715 // True IP of machine
716 uint32 GetKadIPAdress() const { return theStats::GetKadIPAdress(); }
717 // Buddy status
718 uint8 GetBuddyStatus() const { return theStats::GetBuddyStatus(); }
719 uint32 GetBuddyIP() const { return theStats::GetBuddyIP(); }
720 uint32 GetBuddyPort() const { return theStats::GetBuddyPort(); }
722 void StartKad();
723 void StopKad();
725 /** Bootstraps kad from the specified IP (must be in hostorder). */
726 void BootstrapKad(uint32 ip, uint16 port);
727 /** Updates the nodes.dat file from the specified url. */
728 void UpdateNotesDat(const wxString& str);
730 void DisconnectED2K();
732 bool CryptoAvailable() const;
734 uint32 GetED2KID() const;
735 uint32 GetID() const;
736 void ShowUserCount();
738 uint8 m_ConnState;
739 uint32 m_clientID;
741 wxLocale m_locale;
742 // This KnownFile collects all currently uploading clients for display in the upload list control
743 CKnownFile * m_allUploadingKnownFile;
745 CUInt128 m_kadID;
747 DECLARE_EVENT_TABLE()
750 DECLARE_APP(CamuleRemoteGuiApp)
752 extern CamuleRemoteGuiApp *theApp;
754 #endif /* AMULE_REMOTE_GUI_H */
756 // File_checked_for_headers