// // This file is part of the aMule Project. // // Copyright (c) 2003-2011 aMule Team ( admin@amule.org / http://www.amule.org ) // Copyright (c) 2002 Merkur ( devs@emule-project.net / http://www.emule-project.net ) // // Any parts of this program derived from the xMule, lMule or eMule project, // or contributed by third-party developers are copyrighted by their // respective authors. // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // #include "TransferWnd.h" // Interface declarations #include #include // This include must be before amuleDlg.h #ifdef __WXMSW__ #include // Needed for windows compilation #endif #include "amuleDlg.h" // Needed for CamuleDlg #include "PartFile.h" // Needed for PR_LOW #include "DownloadQueue.h" // Needed for CDownloadQueue #include "CatDialog.h" // Needed for CCatDialog #include "DownloadListCtrl.h" // Needed for CDownloadListCtrl #include "SourceListCtrl.h" // Needed for CSourceListCtrl #include "amule.h" // Needed for theApp #include "muuli_wdr.h" // Needed for ID_CATEGORIES #include "SearchDlg.h" // Needed for CSearchDlg->UpdateCatChoice() #include "MuleNotebook.h" #include "Preferences.h" #include "Statistics.h" // Needed for theStats #include "SharedFileList.h" // Needed for CSharedFileList #include "GuiEvents.h" // Needed for CoreNotify_* BEGIN_EVENT_TABLE(CTransferWnd, wxPanel) EVT_RIGHT_DOWN(CTransferWnd::OnNMRclickDLtab) EVT_NOTEBOOK_PAGE_CHANGED(ID_CATEGORIES, CTransferWnd::OnCategoryChanged) EVT_SPLITTER_SASH_POS_CHANGING(ID_DOWNLOADSSPLATTER, CTransferWnd::OnSashPositionChanging) EVT_BUTTON(ID_BTNCLRCOMPL, CTransferWnd::OnBtnClearDownloads) EVT_BUTTON(ID_CLIENTTOGGLE, CTransferWnd::OnToggleClientList) EVT_MENU_RANGE(MP_CAT_SET0, MP_CAT_SET0 + 15, CTransferWnd::OnSetDefaultCat) EVT_MENU(MP_CAT_ADD, CTransferWnd::OnAddCategory) EVT_MENU(MP_CAT_EDIT, CTransferWnd::OnEditCategory) EVT_MENU(MP_CAT_REMOVE, CTransferWnd::OnDelCategory) EVT_MENU(MP_PRIOLOW, CTransferWnd::OnSetCatPriority) EVT_MENU(MP_PRIONORMAL, CTransferWnd::OnSetCatPriority) EVT_MENU(MP_PRIOHIGH, CTransferWnd::OnSetCatPriority) EVT_MENU(MP_PRIOAUTO, CTransferWnd::OnSetCatPriority) EVT_MENU(MP_PAUSE, CTransferWnd::OnSetCatStatus) EVT_MENU(MP_STOP, CTransferWnd::OnSetCatStatus) EVT_MENU(MP_CANCEL, CTransferWnd::OnSetCatStatus) EVT_MENU(MP_RESUME, CTransferWnd::OnSetCatStatus) END_EVENT_TABLE() CTransferWnd::CTransferWnd( wxWindow* pParent ) : wxPanel( pParent, -1 ) { wxSizer* content = transferDlg(this, true); content->Show(this, true); downloadlistctrl = CastChild( wxT("downloadList"), CDownloadListCtrl ); clientlistctrl = CastChild( ID_CLIENTLIST, CSourceListCtrl ); m_dlTab = CastChild( ID_CATEGORIES, CMuleNotebook ); // Set disabled image for clear complete button CastChild(ID_BTNCLRCOMPL, wxBitmapButton)->SetBitmapDisabled(amuleDlgImages(34)); // We want to use our own popup m_dlTab->SetPopupHandler( this ); // Set default category theApp->glob_prefs->GetCategory(0)->title = GetCatTitle(thePrefs::GetAllcatFilter()); theApp->glob_prefs->GetCategory(0)->path = thePrefs::GetIncomingDir(); // Show default + userdefined categories for ( uint32 i = 0; i < theApp->glob_prefs->GetCatCount(); i++ ) { m_dlTab->AddPage( new wxPanel(m_dlTab), theApp->glob_prefs->GetCategory(i)->title ); } m_menu = NULL; m_splitter = 0; wxConfigBase *config = wxConfigBase::Get(); // Check if the clientlist is hidden bool show = true; config->Read( wxT("/GUI/TransferWnd/ShowClientList"), &show, true ); clientlistctrl->SetShowing(show); // Load the last used splitter position m_splitter = config->Read( wxT("/GUI/TransferWnd/Splitter"), 463l ); } CTransferWnd::~CTransferWnd() { wxConfigBase *config = wxConfigBase::Get(); if ( !clientlistctrl->GetShowing() ) { // Save the splitter position config->Write( wxT("/GUI/TransferWnd/Splitter"), m_splitter ); // Save the visible status of the list config->Write( wxT("/GUI/TransferWnd/ShowClientList"), false ); } else { wxSplitterWindow* splitter = CastChild( wxT("splitterWnd"), wxSplitterWindow ); // Save the splitter position config->Write( wxT("/GUI/TransferWnd/Splitter"), splitter->GetSashPosition() ); // Save the visible status of the list config->Write( wxT("/GUI/TransferWnd/ShowClientList"), true ); } } void CTransferWnd::AddCategory( Category_Struct* category ) { // Add the initial page m_dlTab->AddPage( new wxPanel(m_dlTab), category->title ); // Update the title UpdateCategory( m_dlTab->GetPageCount() - 1 ); theApp->amuledlg->m_searchwnd->UpdateCatChoice(); } void CTransferWnd::UpdateCategory(int index) { uint32 nrCats = theApp->glob_prefs->GetCatCount(); std::vector files, downloads; bool showCatTabInfos = thePrefs::ShowCatTabInfos(); if (showCatTabInfos) { files.insert(files.begin(), nrCats, 0); downloads.insert(downloads.begin(), nrCats, 0); #ifdef CLIENT_GUI for (CDownQueueRem::const_iterator it = theApp->downloadqueue->begin(); it != theApp->downloadqueue->end(); ++it) { CPartFile *cur_file = it->second; #else std::vector fileList; theApp->downloadqueue->CopyFileList(fileList, true); int size = fileList.size(); for (int i = 0; i < size; ++i ) { CPartFile *cur_file = fileList[i]; #endif bool downloading = cur_file->GetTransferingSrcCount() > 0; int fileCat = cur_file->GetCategory(); if ((index == -1 || fileCat == index) && cur_file->CheckShowItemInGivenCat(fileCat)) { files[fileCat]++; if (downloading) { downloads[fileCat]++; } } if (index == -1 && fileCat > 0 && cur_file->CheckShowItemInGivenCat(0)) { files[0]++; if (downloading) { downloads[0]++; } } } } int start, end; if (index == -1) { start = 0; end = nrCats - 1; } else { start = index; end = index; } for (int i = start; i <= end; i++) { wxString label = theApp->glob_prefs->GetCategory(i)->title; if (showCatTabInfos) { label += CFormat(wxT(" (%u/%u)")) % downloads[i] % files[i]; } m_dlTab->SetPageText(i, label); } } void CTransferWnd::OnSetCatStatus( wxCommandEvent& event ) { if ( event.GetId() == MP_CANCEL ) { 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) { return; } } CoreNotify_Download_Set_Cat_Status( m_dlTab->GetSelection(), event.GetId() ); } void CTransferWnd::OnSetCatPriority( wxCommandEvent& event ) { int priority = 0; switch ( event.GetId() ) { case MP_PRIOLOW: priority = PR_LOW; break; case MP_PRIONORMAL: priority = PR_NORMAL; break; case MP_PRIOHIGH: priority = PR_HIGH; break; case MP_PRIOAUTO: priority = PR_AUTO; break; default: return; } CoreNotify_Download_Set_Cat_Prio( m_dlTab->GetSelection(), priority ); } void CTransferWnd::OnAddCategory(wxCommandEvent& WXUNUSED(event)) { if (theApp->glob_prefs->GetCatCount() >= 99) { wxMessageBox(_("Only 99 categories are supported."), _("Too many categories!"), wxOK | wxICON_EXCLAMATION); return; } CCatDialog dialog( this, // Allow browse? #ifdef CLIENT_GUI false #else true #endif ); dialog.ShowModal(); } void CTransferWnd::OnDelCategory(wxCommandEvent& WXUNUSED(event)) { RemoveCategory(m_dlTab->GetSelection()); } void CTransferWnd::RemoveCategory(int index) { if ( index > 0 ) { theApp->downloadqueue->ResetCatParts(index); theApp->glob_prefs->RemoveCat(index); RemoveCategoryPage(index); if ( theApp->glob_prefs->GetCatCount() == 1 ) { thePrefs::SetAllcatFilter( acfAll ); } theApp->glob_prefs->SaveCats(); theApp->amuledlg->m_searchwnd->UpdateCatChoice(); } } void CTransferWnd::RemoveCategoryPage(int index) { m_dlTab->RemovePage(index); m_dlTab->SetSelection(0); downloadlistctrl->ChangeCategory(0); } void CTransferWnd::OnEditCategory( wxCommandEvent& WXUNUSED(event) ) { CCatDialog dialog( this, // Allow browse? #ifdef CLIENT_GUI false #else true #endif , m_dlTab->GetSelection()); dialog.ShowModal(); } void CTransferWnd::OnSetDefaultCat( wxCommandEvent& event ) { thePrefs::SetAllcatFilter( static_cast(event.GetId() - MP_CAT_SET0) ); theApp->glob_prefs->GetCategory(0)->title = GetCatTitle( thePrefs::GetAllcatFilter() ); UpdateCategory( 0 ); downloadlistctrl->ChangeCategory( 0 ); theApp->glob_prefs->SaveCats(); downloadlistctrl->SortList(); } void CTransferWnd::OnCategoryChanged(wxNotebookEvent& evt) { // First remove currently showing sources (switching cat will deselect all) CKnownFileVector filesVector; clientlistctrl->ShowSources(filesVector); // Then change cat downloadlistctrl->ChangeCategory(evt.GetSelection()); downloadlistctrl->SortList(); } void CTransferWnd::OnNMRclickDLtab(wxMouseEvent& evt) { // Only handle events from the category-notebook if ( evt.GetEventObject() != (wxObject*)m_dlTab ) return; if ( m_dlTab->GetSelection() == -1 ) { return; } // Avoid opening another menu when it's already open if ( m_menu == NULL ) { m_menu = new wxMenu( _("Category") ); if ( m_dlTab->GetSelection() == 0 ) { wxMenu* catmenu = new wxMenu(); catmenu->Append( MP_CAT_SET0, _("All") ); catmenu->Append( MP_CAT_SET0 + 1, _("All others") ); catmenu->AppendSeparator(); catmenu->Append( MP_CAT_SET0 + 2, _("Incomplete") ); catmenu->Append( MP_CAT_SET0 + 3, _("Completed") ); catmenu->Append( MP_CAT_SET0 + 4, _("Waiting") ); catmenu->Append( MP_CAT_SET0 + 5, _("Downloading") ); catmenu->Append( MP_CAT_SET0 + 6, _("Erroneous") ); catmenu->Append( MP_CAT_SET0 + 7, _("Paused") ); catmenu->Append( MP_CAT_SET0 + 8, _("Stopped") ); catmenu->Append( MP_CAT_SET0 + 15, _("Active") ); catmenu->AppendSeparator(); catmenu->Append( MP_CAT_SET0 + 9, _("Video") ); catmenu->Append( MP_CAT_SET0 + 10, _("Audio") ); catmenu->Append( MP_CAT_SET0 + 11, _("Archive") ); catmenu->Append( MP_CAT_SET0 + 12, _("CD-Images") ); catmenu->Append( MP_CAT_SET0 + 13, _("Pictures") ); catmenu->Append( MP_CAT_SET0 + 14, _("Text") ); m_menu->Append(0, _("Select view filter"), catmenu); } m_menu->Append( MP_CAT_ADD, _("Add category") ); if ( m_dlTab->GetSelection() ) { m_menu->Append(MP_CAT_EDIT,_("Edit category")); m_menu->Append(MP_CAT_REMOVE, _("Remove category")); } m_menu->AppendSeparator(); m_menu->Append( MP_CANCEL, _("Cancel")); m_menu->Append( MP_STOP, _("&Stop")); m_menu->Append( MP_PAUSE, _("&Pause")); m_menu->Append( MP_RESUME, _("&Resume")); PopupMenu(m_menu, evt.GetPosition()); delete m_menu; m_menu = NULL; } } void CTransferWnd::OnBtnClearDownloads( wxCommandEvent& WXUNUSED(evt) ) { downloadlistctrl->Freeze(); downloadlistctrl->ClearCompleted(); downloadlistctrl->Thaw(); } void CTransferWnd::Prepare() { wxSplitterWindow* splitter = CastChild( wxT("splitterWnd"), wxSplitterWindow ); int height = splitter->GetSize().GetHeight(); int header_height = s_clientlistHeader->GetSize().GetHeight(); if ( m_splitter ) { // Some sanity checking if ( m_splitter < s_splitterMin ) { m_splitter = s_splitterMin; } else if ( m_splitter > height - header_height * 2 ) { m_splitter = height - header_height * 2; } splitter->SetSashPosition( m_splitter ); m_splitter = 0; } if ( !clientlistctrl->GetShowing() ) { // use a toggle event to close it (calculate size, change button) clientlistctrl->SetShowing( true ); // so it will be toggled to false wxCommandEvent evt1; OnToggleClientList( evt1 ); } } void CTransferWnd::OnToggleClientList(wxCommandEvent& WXUNUSED(evt)) { wxSplitterWindow* splitter = CastChild( wxT("splitterWnd"), wxSplitterWindow ); wxBitmapButton* button = CastChild( ID_CLIENTTOGGLE, wxBitmapButton ); if ( !clientlistctrl->GetShowing() ) { splitter->SetSashPosition( m_splitter ); m_splitter = 0; clientlistctrl->SetShowing( true ); button->SetBitmapLabel( amuleDlgImages( 10 ) ); button->SetBitmapFocus( amuleDlgImages( 10 ) ); button->SetBitmapSelected( amuleDlgImages( 10 ) ); button->SetBitmapHover( amuleDlgImages( 10 ) ); } else { clientlistctrl->SetShowing( false ); m_splitter = splitter->GetSashPosition(); // Add the height of the listctrl to the top-window int height = clientlistctrl->GetSize().GetHeight() + splitter->GetWindow1()->GetSize().GetHeight(); splitter->SetSashPosition( height ); button->SetBitmapLabel( amuleDlgImages( 11 ) ); button->SetBitmapFocus( amuleDlgImages( 11 ) ); button->SetBitmapSelected( amuleDlgImages( 11 ) ); button->SetBitmapHover( amuleDlgImages( 11 ) ); } } void CTransferWnd::OnSashPositionChanging(wxSplitterEvent& evt) { if ( evt.GetSashPosition() < s_splitterMin ) { evt.SetSashPosition( s_splitterMin ); } else { wxSplitterWindow* splitter = wxStaticCast( evt.GetEventObject(), wxSplitterWindow); wxCHECK_RET(splitter, wxT("ERROR: NULL splitter in CTransferWnd::OnSashPositionChanging")); int height = splitter->GetSize().GetHeight(); int header_height = s_clientlistHeader->GetSize().GetHeight(); int mousey = wxGetMousePosition().y - splitter->GetScreenRect().GetTop(); if ( !clientlistctrl->GetShowing() ) { // lower window hidden if ( height - mousey < header_height * 2 ) { // no moving down if already hidden evt.Veto(); } else { // show it m_splitter = mousey; // prevent jumping if it was minimized and is then shown by dragging the sash wxCommandEvent event; OnToggleClientList( event ); } } else { // lower window showing if ( height - mousey < header_height * 2 ) { // hide it wxCommandEvent event; OnToggleClientList( event ); } else { // normal resize // If several events queue up, setting the sash to the current mouse position // will speed up things and make sash moving more smoothly. evt.SetSashPosition( mousey ); } } } } // File_checked_for_headers