Don't allow creation of more than 99 categories
[amule.git] / src / TransferWnd.cpp
blob80cb8504e07697167ff5c9f67c91afb381642995
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 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
26 #include "TransferWnd.h" // Interface declarations
28 #include <common/MenuIDs.h>
30 #include <wx/config.h>
33 // This include must be before amuleDlg.h
34 #ifdef __WXMSW__
35 #include <wx/msw/winundef.h> // Needed for windows compilation
36 #endif
39 #include "amuleDlg.h" // Needed for CamuleDlg
40 #include "PartFile.h" // Needed for PR_LOW
41 #include "DownloadQueue.h" // Needed for CDownloadQueue
42 #include "CatDialog.h" // Needed for CCatDialog
43 #include "DownloadListCtrl.h" // Needed for CDownloadListCtrl
44 #include "SourceListCtrl.h" // Needed for CSourceListCtrl
45 #include "amule.h" // Needed for theApp
46 #include "muuli_wdr.h" // Needed for ID_CATEGORIES
47 #include "SearchDlg.h" // Needed for CSearchDlg->UpdateCatChoice()
48 #include "MuleNotebook.h"
49 #include "Preferences.h"
50 #include "Statistics.h" // Needed for theStats
51 #include "SharedFileList.h" // Needed for CSharedFileList
52 #include "GuiEvents.h" // Needed for CoreNotify_*
55 BEGIN_EVENT_TABLE(CTransferWnd, wxPanel)
56 EVT_RIGHT_DOWN(CTransferWnd::OnNMRclickDLtab)
57 EVT_NOTEBOOK_PAGE_CHANGED(ID_CATEGORIES, CTransferWnd::OnCategoryChanged)
59 EVT_SPLITTER_SASH_POS_CHANGING(ID_DOWNLOADSSPLATTER, CTransferWnd::OnSashPositionChanging)
61 EVT_BUTTON(ID_BTNCLRCOMPL, CTransferWnd::OnBtnClearDownloads)
62 EVT_BUTTON(ID_CLIENTTOGGLE, CTransferWnd::OnToggleClientList)
64 EVT_MENU_RANGE(MP_CAT_SET0, MP_CAT_SET0 + 15, CTransferWnd::OnSetDefaultCat)
65 EVT_MENU(MP_CAT_ADD, CTransferWnd::OnAddCategory)
66 EVT_MENU(MP_CAT_EDIT, CTransferWnd::OnEditCategory)
67 EVT_MENU(MP_CAT_REMOVE, CTransferWnd::OnDelCategory)
68 EVT_MENU(MP_PRIOLOW, CTransferWnd::OnSetCatPriority)
69 EVT_MENU(MP_PRIONORMAL, CTransferWnd::OnSetCatPriority)
70 EVT_MENU(MP_PRIOHIGH, CTransferWnd::OnSetCatPriority)
71 EVT_MENU(MP_PRIOAUTO, CTransferWnd::OnSetCatPriority)
72 EVT_MENU(MP_PAUSE, CTransferWnd::OnSetCatStatus)
73 EVT_MENU(MP_STOP, CTransferWnd::OnSetCatStatus)
74 EVT_MENU(MP_CANCEL, CTransferWnd::OnSetCatStatus)
75 EVT_MENU(MP_RESUME, CTransferWnd::OnSetCatStatus)
76 END_EVENT_TABLE()
80 CTransferWnd::CTransferWnd( wxWindow* pParent )
81 : wxPanel( pParent, -1 )
83 wxSizer* content = transferDlg(this, true);
84 content->Show(this, true);
86 downloadlistctrl = CastChild( wxT("downloadList"), CDownloadListCtrl );
87 clientlistctrl = CastChild( ID_CLIENTLIST, CSourceListCtrl );
88 m_dlTab = CastChild( ID_CATEGORIES, CMuleNotebook );
90 // Set disabled image for clear complete button
91 CastChild(ID_BTNCLRCOMPL, wxBitmapButton)->SetBitmapDisabled(amuleDlgImages(34));
93 // We want to use our own popup
94 m_dlTab->SetPopupHandler( this );
96 // Set default category
97 theApp->glob_prefs->GetCategory(0)->title = GetCatTitle(thePrefs::GetAllcatFilter());
98 theApp->glob_prefs->GetCategory(0)->path = thePrefs::GetIncomingDir();
100 // Show default + userdefined categories
101 for ( uint32 i = 0; i < theApp->glob_prefs->GetCatCount(); i++ ) {
102 m_dlTab->AddPage( new wxPanel(m_dlTab), theApp->glob_prefs->GetCategory(i)->title );
105 m_menu = NULL;
106 m_splitter = 0;
108 wxConfigBase *config = wxConfigBase::Get();
110 // Check if the clientlist is hidden
111 bool show = true;
112 config->Read( wxT("/GUI/TransferWnd/ShowClientList"), &show, true );
113 clientlistctrl->SetShowing(show);
114 // Load the last used splitter position
115 m_splitter = config->Read( wxT("/GUI/TransferWnd/Splitter"), 463l );
119 CTransferWnd::~CTransferWnd()
121 wxConfigBase *config = wxConfigBase::Get();
123 if ( !clientlistctrl->GetShowing() ) {
124 // Save the splitter position
125 config->Write( wxT("/GUI/TransferWnd/Splitter"), m_splitter );
127 // Save the visible status of the list
128 config->Write( wxT("/GUI/TransferWnd/ShowClientList"), false );
129 } else {
130 wxSplitterWindow* splitter = CastChild( wxT("splitterWnd"), wxSplitterWindow );
132 // Save the splitter position
133 config->Write( wxT("/GUI/TransferWnd/Splitter"), splitter->GetSashPosition() );
135 // Save the visible status of the list
136 config->Write( wxT("/GUI/TransferWnd/ShowClientList"), true );
141 void CTransferWnd::AddCategory( Category_Struct* category )
143 // Add the initial page
144 m_dlTab->AddPage( new wxPanel(m_dlTab), category->title );
146 // Update the title
147 UpdateCategory( m_dlTab->GetPageCount() - 1 );
149 theApp->amuledlg->m_searchwnd->UpdateCatChoice();
152 void CTransferWnd::UpdateCategory(int index)
154 uint32 nrCats = theApp->glob_prefs->GetCatCount();
155 std::vector<uint16> files, downloads;
156 bool showCatTabInfos = thePrefs::ShowCatTabInfos();
157 if (showCatTabInfos) {
158 files.insert(files.begin(), nrCats, 0);
159 downloads.insert(downloads.begin(), nrCats, 0);
161 #ifdef CLIENT_GUI
162 for (CDownQueueRem::const_iterator it = theApp->downloadqueue->begin(); it != theApp->downloadqueue->end(); ++it) {
163 CPartFile *cur_file = it->second;
164 #else
165 std::vector<CPartFile*> fileList;
166 theApp->downloadqueue->CopyFileList(fileList, true);
167 int size = fileList.size();
168 for (int i = 0; i < size; ++i ) {
169 CPartFile *cur_file = fileList[i];
170 #endif
171 bool downloading = cur_file->GetTransferingSrcCount() > 0;
172 int fileCat = cur_file->GetCategory();
173 if ((index == -1 || fileCat == index) && cur_file->CheckShowItemInGivenCat(fileCat)) {
174 files[fileCat]++;
175 if (downloading) {
176 downloads[fileCat]++;
179 if (index == -1 && fileCat > 0 && cur_file->CheckShowItemInGivenCat(0)) {
180 files[0]++;
181 if (downloading) {
182 downloads[0]++;
188 int start, end;
189 if (index == -1) {
190 start = 0;
191 end = nrCats - 1;
192 } else {
193 start = index;
194 end = index;
196 for (int i = start; i <= end; i++) {
197 wxString label = theApp->glob_prefs->GetCategory(i)->title;
198 if (showCatTabInfos) {
199 label += CFormat(wxT(" (%u/%u)")) % downloads[i] % files[i];
201 m_dlTab->SetPageText(i, label);
206 void CTransferWnd::OnSetCatStatus( wxCommandEvent& event )
208 if ( event.GetId() == MP_CANCEL ) {
209 if ( wxMessageBox(_("Are you sure you wish to cancel and delete all files in this category?"),_("Confirmation Required"), wxYES_NO|wxCENTRE|wxICON_EXCLAMATION, this) == wxNO) {
210 return;
214 CoreNotify_Download_Set_Cat_Status( m_dlTab->GetSelection(), event.GetId() );
218 void CTransferWnd::OnSetCatPriority( wxCommandEvent& event )
220 int priority = 0;
222 switch ( event.GetId() ) {
223 case MP_PRIOLOW: priority = PR_LOW; break;
224 case MP_PRIONORMAL: priority = PR_NORMAL; break;
225 case MP_PRIOHIGH: priority = PR_HIGH; break;
226 case MP_PRIOAUTO: priority = PR_AUTO; break;
227 default:
228 return;
231 CoreNotify_Download_Set_Cat_Prio( m_dlTab->GetSelection(), priority );
235 void CTransferWnd::OnAddCategory(wxCommandEvent& WXUNUSED(event))
237 if (theApp->glob_prefs->GetCatCount() >= 99) {
238 wxMessageBox(_("Only 99 categories are supported."), _("Too many categories!"), wxOK | wxICON_EXCLAMATION);
239 return;
241 CCatDialog dialog( this,
242 // Allow browse?
243 #ifdef CLIENT_GUI
244 false
245 #else
246 true
247 #endif
249 if (dialog.ShowModal() == wxOK) {
250 // Add the files on this folder.
251 Category_Struct* newcat =
252 theApp->glob_prefs->GetCategory(
253 theApp->glob_prefs->GetCatCount()-1);
254 theApp->sharedfiles->AddFilesFromDirectory(newcat->path);
255 theApp->sharedfiles->Reload();
260 void CTransferWnd::OnDelCategory(wxCommandEvent& WXUNUSED(event))
262 RemoveCategory(m_dlTab->GetSelection());
266 void CTransferWnd::RemoveCategory(int index)
268 if ( index > 0 ) {
269 theApp->downloadqueue->ResetCatParts(index);
270 theApp->glob_prefs->RemoveCat(index);
271 RemoveCategoryPage(index);
272 if ( theApp->glob_prefs->GetCatCount() == 1 ) {
273 thePrefs::SetAllcatFilter( acfAll );
275 theApp->glob_prefs->SaveCats();
276 theApp->amuledlg->m_searchwnd->UpdateCatChoice();
281 void CTransferWnd::RemoveCategoryPage(int index)
283 m_dlTab->RemovePage(index);
284 m_dlTab->SetSelection(0);
285 downloadlistctrl->ChangeCategory(0);
289 void CTransferWnd::OnEditCategory( wxCommandEvent& WXUNUSED(event) )
291 Category_Struct* cat = theApp->glob_prefs->GetCategory(m_dlTab->GetSelection());
292 CPath oldpath = cat->path;
293 CCatDialog dialog( this,
294 // Allow browse?
295 #ifdef CLIENT_GUI
296 false
297 #else
298 true
299 #endif
300 , m_dlTab->GetSelection());
302 if (dialog.ShowModal() == wxOK) {
303 if (!oldpath.IsSameDir(cat->path)) {
304 theApp->sharedfiles->AddFilesFromDirectory(cat->path);
305 theApp->sharedfiles->Reload();
311 void CTransferWnd::OnSetDefaultCat( wxCommandEvent& event )
313 thePrefs::SetAllcatFilter( static_cast<AllCategoryFilter>(event.GetId() - MP_CAT_SET0) );
314 theApp->glob_prefs->GetCategory(0)->title = GetCatTitle( thePrefs::GetAllcatFilter() );
316 UpdateCategory( 0 );
318 downloadlistctrl->ChangeCategory( 0 );
320 theApp->glob_prefs->SaveCats();
322 downloadlistctrl->SortList();
326 void CTransferWnd::ShowQueueCount(uint32 /*number*/)
328 #if 0
329 wxString str = CFormat(wxT("%u (%u %s)")) % number % theStats::GetBannedCount() % _("Banned");
330 wxStaticText* label = CastChild( ID_CLIENTCOUNT, wxStaticText );
332 label->SetLabel( str );
333 label->GetParent()->Layout();
334 #endif
338 void CTransferWnd::OnCategoryChanged(wxNotebookEvent& evt)
340 // First remove currently showing sources (switching cat will deselect all)
341 CKnownFileVector filesVector;
342 clientlistctrl->ShowSources(filesVector);
343 // Then change cat
344 downloadlistctrl->ChangeCategory(evt.GetSelection());
345 downloadlistctrl->SortList();
349 void CTransferWnd::OnNMRclickDLtab(wxMouseEvent& evt)
351 // Only handle events from the category-notebook
352 if ( evt.GetEventObject() != (wxObject*)m_dlTab )
353 return;
355 if ( m_dlTab->GetSelection() == -1 ) {
356 return;
359 // Avoid opening another menu when it's already open
360 if ( m_menu == NULL ) {
361 m_menu = new wxMenu( _("Category") );
363 if ( m_dlTab->GetSelection() == 0 ) {
364 wxMenu* catmenu = new wxMenu();
366 catmenu->Append( MP_CAT_SET0, _("All") );
367 catmenu->Append( MP_CAT_SET0 + 1, _("All others") );
369 catmenu->AppendSeparator();
371 catmenu->Append( MP_CAT_SET0 + 2, _("Incomplete") );
372 catmenu->Append( MP_CAT_SET0 + 3, _("Completed") );
373 catmenu->Append( MP_CAT_SET0 + 4, _("Waiting") );
374 catmenu->Append( MP_CAT_SET0 + 5, _("Downloading") );
375 catmenu->Append( MP_CAT_SET0 + 6, _("Erroneous") );
376 catmenu->Append( MP_CAT_SET0 + 7, _("Paused") );
377 catmenu->Append( MP_CAT_SET0 + 8, _("Stopped") );
378 catmenu->Append( MP_CAT_SET0 + 15, _("Active") );
380 catmenu->AppendSeparator();
382 catmenu->Append( MP_CAT_SET0 + 9, _("Video") );
383 catmenu->Append( MP_CAT_SET0 + 10, _("Audio") );
384 catmenu->Append( MP_CAT_SET0 + 11, _("Archive") );
385 catmenu->Append( MP_CAT_SET0 + 12, _("CD-Images") );
386 catmenu->Append( MP_CAT_SET0 + 13, _("Pictures") );
387 catmenu->Append( MP_CAT_SET0 + 14, _("Text") );
389 m_menu->Append(0, _("Select view filter"), catmenu);
392 m_menu->Append( MP_CAT_ADD, _("Add category") );
394 if ( m_dlTab->GetSelection() ) {
395 m_menu->Append(MP_CAT_EDIT,_("Edit category"));
396 m_menu->Append(MP_CAT_REMOVE, _("Remove category"));
399 m_menu->AppendSeparator();
401 m_menu->Append( MP_CANCEL, _("Cancel"));
402 m_menu->Append( MP_STOP, _("&Stop"));
403 m_menu->Append( MP_PAUSE, _("&Pause"));
404 m_menu->Append( MP_RESUME, _("&Resume"));
406 PopupMenu(m_menu, evt.GetPosition());
408 delete m_menu;
409 m_menu = NULL;
414 void CTransferWnd::OnBtnClearDownloads( wxCommandEvent& WXUNUSED(evt) )
416 downloadlistctrl->Freeze();
417 downloadlistctrl->ClearCompleted();
418 downloadlistctrl->Thaw();
422 void CTransferWnd::Prepare()
424 wxSplitterWindow* splitter = CastChild( wxT("splitterWnd"), wxSplitterWindow );
425 int height = splitter->GetSize().GetHeight();
426 int header_height = s_clientlistHeader->GetSize().GetHeight();
428 if ( m_splitter ) {
429 // Some sanity checking
430 if ( m_splitter < s_splitterMin ) {
431 m_splitter = s_splitterMin;
432 } else if ( m_splitter > height - header_height * 2 ) {
433 m_splitter = height - header_height * 2;
435 splitter->SetSashPosition( m_splitter );
436 m_splitter = 0;
439 if ( !clientlistctrl->GetShowing() ) {
440 // use a toggle event to close it (calculate size, change button)
441 clientlistctrl->SetShowing( true ); // so it will be toggled to false
442 wxCommandEvent evt1;
443 OnToggleClientList( evt1 );
447 void CTransferWnd::OnToggleClientList(wxCommandEvent& WXUNUSED(evt))
449 wxSplitterWindow* splitter = CastChild( wxT("splitterWnd"), wxSplitterWindow );
450 wxBitmapButton* button = CastChild( ID_CLIENTTOGGLE, wxBitmapButton );
452 if ( !clientlistctrl->GetShowing() ) {
453 splitter->SetSashPosition( m_splitter );
454 m_splitter = 0;
456 clientlistctrl->SetShowing( true );
458 button->SetBitmapLabel( amuleDlgImages( 10 ) );
459 button->SetBitmapFocus( amuleDlgImages( 10 ) );
460 button->SetBitmapSelected( amuleDlgImages( 10 ) );
461 button->SetBitmapHover( amuleDlgImages( 10 ) );
462 } else {
463 clientlistctrl->SetShowing( false );
465 m_splitter = splitter->GetSashPosition();
467 // Add the height of the listctrl to the top-window
468 int height = clientlistctrl->GetSize().GetHeight()
469 + splitter->GetWindow1()->GetSize().GetHeight();
471 splitter->SetSashPosition( height );
473 button->SetBitmapLabel( amuleDlgImages( 11 ) );
474 button->SetBitmapFocus( amuleDlgImages( 11 ) );
475 button->SetBitmapSelected( amuleDlgImages( 11 ) );
476 button->SetBitmapHover( amuleDlgImages( 11 ) );
481 void CTransferWnd::OnSashPositionChanging(wxSplitterEvent& evt)
483 if ( evt.GetSashPosition() < s_splitterMin ) {
484 evt.SetSashPosition( s_splitterMin );
485 } else {
486 wxSplitterWindow* splitter = wxStaticCast( evt.GetEventObject(), wxSplitterWindow);
487 wxCHECK_RET(splitter, wxT("ERROR: NULL splitter in CTransferWnd::OnSashPositionChanging"));
489 int height = splitter->GetSize().GetHeight();
490 int header_height = s_clientlistHeader->GetSize().GetHeight();
491 int mousey = wxGetMousePosition().y - splitter->GetScreenRect().GetTop();
493 if ( !clientlistctrl->GetShowing() ) {
494 // lower window hidden
495 if ( height - mousey < header_height * 2 ) {
496 // no moving down if already hidden
497 evt.Veto();
498 } else {
499 // show it
500 m_splitter = mousey; // prevent jumping if it was minimized and is then shown by dragging the sash
501 wxCommandEvent event;
502 OnToggleClientList( event );
504 } else {
505 // lower window showing
506 if ( height - mousey < header_height * 2 ) {
507 // hide it
508 wxCommandEvent event;
509 OnToggleClientList( event );
510 } else {
511 // normal resize
512 // If several events queue up, setting the sash to the current mouse position
513 // will speed up things and make sash moving more smoothly.
514 evt.SetSashPosition( mousey );
519 // File_checked_for_headers