debian: fix build-deps for focal
[amule.git] / src / FileDetailDialog.cpp
blob62af93283bbad968c8edee6f72a4da960bd03c04
1 //
2 // This file is part of the aMule Project.
3 //
4 // Copyright (c) 2003-2011 aMule Team ( admin@amule.org / http://www.amule.org )
5 // Copyright (c) 2002-2011 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 // Any parts of this program derived from the xMule, lMule or eMule project,
12 // or contributed by third-party developers are copyrighted by their
13 // respective authors.
15 // This program is free software; you can redistribute it and/or modify
16 // it under the terms of the GNU General Public License as published by
17 // the Free Software Foundation; either version 2 of the License, or
18 // (at your option) any later version.
20 // This program is distributed in the hope that it will be useful,
21 // but WITHOUT ANY WARRANTY; without even the implied warranty of
22 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 // GNU General Public License for more details.
25 // You should have received a copy of the GNU General Public License
26 // along with this program; if not, write to the Free Software
27 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
31 #include "muuli_wdr.h" // Needed for ID_CLOSEWNDFD,...,IDC_APPLY
32 #include "FileDetailDialog.h" // Interface declarations
33 #include "FileDetailListCtrl.h" // Needed for CFileDetailListCtrl
34 #include "CommentDialogLst.h" // Needed for CCommentDialogLst
35 #include "PartFile.h" // Needed for CPartFile
36 #include "amule.h" // Needed for theApp
37 #include "SharedFileList.h" // Needed for CSharedFileList
38 #include "OtherFunctions.h"
39 #include "MuleColour.h"
41 #define ID_MY_TIMER 1652
43 //IMPLEMENT_DYNAMIC(CFileDetailDialog, CDialog)
44 BEGIN_EVENT_TABLE(CFileDetailDialog,wxDialog)
45 EVT_BUTTON(ID_CLOSEWNDFD, CFileDetailDialog::OnClosewnd)
46 EVT_BUTTON(IDC_BUTTONSTRIP, CFileDetailDialog::OnBnClickedButtonStrip)
47 EVT_BUTTON(IDC_TAKEOVER, CFileDetailDialog::OnBnClickedTakeOver)
48 EVT_LIST_ITEM_ACTIVATED(IDC_LISTCTRLFILENAMES, CFileDetailDialog::OnListClickedTakeOver)
49 EVT_BUTTON(IDC_CMTBT, CFileDetailDialog::OnBnClickedShowComment)
50 EVT_TEXT(IDC_FILENAME, CFileDetailDialog::OnTextFileNameChange)
51 EVT_BUTTON(IDC_APPLY_AND_CLOSE, CFileDetailDialog::OnBnClickedOk)
52 EVT_BUTTON(IDC_APPLY, CFileDetailDialog::OnBnClickedApply)
53 EVT_BUTTON(IDC_PREVFILE, CFileDetailDialog::OnBnClickedPrevFile)
54 EVT_BUTTON(IDC_NEXTFILE, CFileDetailDialog::OnBnClickedNextFile)
55 EVT_TIMER(ID_MY_TIMER,CFileDetailDialog::OnTimer)
56 END_EVENT_TABLE()
58 CFileDetailDialog::CFileDetailDialog(wxWindow *parent, std::vector<CPartFile *> & files, int index)
60 wxDialog(parent, -1, _("File Details"), wxDefaultPosition, wxDefaultSize,
61 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMAXIMIZE_BOX | wxMINIMIZE_BOX),
62 m_files(files),
63 m_index(index),
64 m_filenameChanged(false)
66 m_timer.SetOwner(this, ID_MY_TIMER);
67 m_timer.Start(5000);
68 wxSizer *content = fileDetails(this, true);
69 m_file = m_files[m_index];
70 UpdateData(true);
71 content->SetSizeHints(this);
72 content->Show(this, true);
75 CFileDetailDialog::~CFileDetailDialog()
77 m_timer.Stop();
80 void CFileDetailDialog::OnTimer(wxTimerEvent& WXUNUSED(evt))
82 UpdateData(false);
85 void CFileDetailDialog::OnClosewnd(wxCommandEvent& WXUNUSED(evt))
87 EndModal(0);
90 void CFileDetailDialog::UpdateData(bool resetFilename)
92 wxString bufferS;
93 CastChild(IDC_FNAME, wxStaticText)->SetLabel(MakeStringEscaped(m_file->GetFileName().TruncatePath(60)));
94 CastChild(IDC_METFILE, wxStaticText)->SetLabel(MakeStringEscaped(m_file->GetFullName().TruncatePath(60, true)));
96 if (resetFilename) {
97 resetValueForFilenameTextEdit();
100 CastChild(IDC_FHASH,wxStaticText)->SetLabel(m_file->GetFileHash().Encode());
101 bufferS = CFormat(wxT("%u bytes (%s)")) % m_file->GetFileSize() % CastItoXBytes(m_file->GetFileSize());
102 CastChild(IDC_FSIZE,wxControl)->SetLabel(bufferS);
103 CastChild(IDC_PFSTATUS,wxControl)->SetLabel(m_file->getPartfileStatus());
104 bufferS = CFormat(wxT("%i (%i)")) % m_file->GetPartCount() % m_file->GetHashCount();
105 CastChild(IDC_PARTCOUNT,wxControl)->SetLabel(bufferS);
106 CastChild(IDC_TRANSFERRED,wxControl)->SetLabel(CastItoXBytes(m_file->GetTransferred()));
107 CastChild(IDC_FD_STATS1,wxControl)->SetLabel(CastItoXBytes(m_file->GetLostDueToCorruption()));
108 CastChild(IDC_FD_STATS2,wxControl)->SetLabel(CastItoXBytes(m_file->GetGainDueToCompression()));
109 CastChild(IDC_FD_STATS3,wxControl)->SetLabel(CastItoIShort(m_file->TotalPacketsSavedDueToICH()));
110 CastChild(IDC_COMPLSIZE,wxControl)->SetLabel(CastItoXBytes(m_file->GetCompletedSize()));
111 bufferS = CFormat(_("%.1f%% done")) % m_file->GetPercentCompleted();
112 CastChild(IDC_PROCCOMPL,wxControl)->SetLabel(bufferS);
113 bufferS = CFormat(_("%.2f kB/s")) % m_file->GetKBpsDown();
114 CastChild(IDC_DATARATE,wxControl)->SetLabel(bufferS);
115 bufferS = CFormat(wxT("%i")) % m_file->GetSourceCount();
116 CastChild(IDC_SOURCECOUNT,wxControl)->SetLabel(bufferS);
117 bufferS = CFormat(wxT("%i")) % m_file->GetTransferingSrcCount();
118 CastChild(IDC_SOURCECOUNT2,wxControl)->SetLabel(bufferS);
119 bufferS = CFormat(wxT("%i (%.1f%%)"))
120 % m_file->GetAvailablePartCount()
121 % ((m_file->GetAvailablePartCount() * 100.0)/ m_file->GetPartCount());
122 CastChild(IDC_PARTAVAILABLE,wxControl)->SetLabel(bufferS);
123 bufferS = CastSecondsToHM(m_file->GetDlActiveTime());
124 CastChild(IDC_DLACTIVETIME, wxControl)->SetLabel(bufferS);
126 if (m_file->lastseencomplete==0) {
127 bufferS = wxString(_("Unknown")).MakeLower();
128 } else {
129 wxDateTime last_seen(m_file->lastseencomplete);
130 bufferS = last_seen.FormatISODate() + wxT(" ") + last_seen.FormatISOTime();
133 CastChild(IDC_LASTSEENCOMPL,wxControl)->SetLabel(bufferS);
134 setEnableForApplyButton();
135 // disable "Show all comments" button if there are no comments
136 FileRatingList list;
137 m_file->GetRatingAndComments(list);
138 CastChild(IDC_CMTBT, wxControl)->Enable(!list.empty());
139 FillSourcenameList();
140 Layout();
143 // CFileDetailDialog message handlers
145 void CFileDetailDialog::FillSourcenameList()
147 CFileDetailListCtrl* pmyListCtrl;
148 int itempos;
149 int inserted = 0;
150 pmyListCtrl = CastChild(IDC_LISTCTRLFILENAMES, CFileDetailListCtrl );
152 // reset
153 for (int i=0;i<pmyListCtrl->GetItemCount();i++){
154 SourcenameItem *item = reinterpret_cast<SourcenameItem *>(pmyListCtrl->GetItemData(i));
155 item->count = 0;
158 // update
159 #ifdef CLIENT_GUI
160 const SourcenameItemMap &sources = m_file->GetSourcenameItemMap();
161 for (SourcenameItemMap::const_iterator it = sources.begin(); it != sources.end(); ++it) {
162 const SourcenameItem &cur_src = it->second;
163 itempos = pmyListCtrl->FindItem(-1,cur_src.name);
164 if (itempos == -1) {
165 int itemid = pmyListCtrl->InsertItem(0, cur_src.name);
166 SourcenameItem *item = new SourcenameItem(cur_src.name, cur_src.count);
167 pmyListCtrl->SetItemPtrData(0, reinterpret_cast<wxUIntPtr>(item));
168 // background.. argh -- PA: was in old version - do we still need this?
169 wxListItem tmpitem;
170 tmpitem.m_itemId = itemid;
171 tmpitem.SetBackgroundColour(CMuleColour(wxSYS_COLOUR_LISTBOX));
172 pmyListCtrl->SetItem(tmpitem);
173 inserted++;
174 } else {
175 SourcenameItem *item = reinterpret_cast<SourcenameItem *>(pmyListCtrl->GetItemData(itempos));
176 item->count = cur_src.count;
179 #else // CLIENT_GUI
180 const CKnownFile::SourceSet& sources = m_file->GetSourceList();
181 CKnownFile::SourceSet::const_iterator it = sources.begin();
182 for ( ; it != sources.end(); ++it ) {
183 const CClientRef &cur_src = *it;
184 if (cur_src.GetRequestFile() != m_file ||
185 cur_src.GetClientFilename().Length() == 0) {
186 continue;
189 itempos = pmyListCtrl->FindItem(-1,cur_src.GetClientFilename());
190 if (itempos == -1) {
191 int itemid = pmyListCtrl->InsertItem(0, cur_src.GetClientFilename());
192 SourcenameItem *item = new SourcenameItem(cur_src.GetClientFilename(), 1);
193 pmyListCtrl->SetItemPtrData(0, reinterpret_cast<wxUIntPtr>(item));
194 // background.. argh -- PA: was in old version - do we still need this?
195 wxListItem tmpitem;
196 tmpitem.m_itemId=itemid;
197 tmpitem.SetBackgroundColour(CMuleColour(wxSYS_COLOUR_LISTBOX));
198 pmyListCtrl->SetItem(tmpitem);
199 inserted++;
200 } else {
201 SourcenameItem *item = reinterpret_cast<SourcenameItem *>(pmyListCtrl->GetItemData(itempos));
202 item->count++;
205 #endif // CLIENT_GUI
207 // remove 0'er and update counts
208 for (int i = 0; i < pmyListCtrl->GetItemCount(); ++i) {
209 SourcenameItem *item = reinterpret_cast<SourcenameItem *>(pmyListCtrl->GetItemData(i));
210 if (item->count == 0) {
211 delete item;
212 pmyListCtrl->DeleteItem(i);
213 i--; // PA: one step back is enough, no need to go back to 0
214 } else {
215 pmyListCtrl->SetItem(i, 1, CFormat(wxT("%i")) % item->count);
219 if (inserted) {
220 pmyListCtrl->SortList();
222 // no need to call Layout() here, it's called in UpdateData()
226 void CFileDetailDialog::OnBnClickedShowComment(wxCommandEvent& WXUNUSED(evt))
228 CCommentDialogLst(this,m_file).ShowModal();
232 void CFileDetailDialog::resetValueForFilenameTextEdit()
234 CastChild(IDC_FILENAME, wxTextCtrl)->SetValue(m_file->GetFileName().GetPrintable());
235 m_filenameChanged = false;
236 setEnableForApplyButton();
240 void CFileDetailDialog::setValueForFilenameTextEdit(const wxString &s)
242 CastChild(IDC_FILENAME, wxTextCtrl)->SetValue(s);
243 m_filenameChanged = true;
244 setEnableForApplyButton();
248 void CFileDetailDialog::setEnableForApplyButton()
250 bool enabled =
251 m_file->GetStatus() != PS_COMPLETE &&
252 m_file->GetStatus() != PS_COMPLETING &&
253 m_filenameChanged;
254 CastChild(IDC_APPLY, wxControl)->Enable(enabled);
255 // Make OK button default so Text can be applied by hitting return
256 CastChild(enabled ? IDC_APPLY_AND_CLOSE : ID_CLOSEWNDFD, wxButton)->SetDefault();
260 void CFileDetailDialog::OnTextFileNameChange(wxCommandEvent& WXUNUSED(evt))
262 m_filenameChanged = true;
263 setEnableForApplyButton();
267 void CFileDetailDialog::OnBnClickedOk(wxCommandEvent& evt)
269 OnBnClickedApply(evt);
270 OnClosewnd(evt);
274 void CFileDetailDialog::OnBnClickedApply(wxCommandEvent& WXUNUSED(evt))
276 CPath fileName = CPath(CastChild(IDC_FILENAME, wxTextCtrl)->GetValue());
278 if (fileName.IsOk() && (fileName != m_file->GetFileName())) {
279 if (theApp->sharedfiles->RenameFile(m_file, fileName)) {
280 FindWindow(IDC_FNAME)->SetLabel(MakeStringEscaped(m_file->GetFileName().GetPrintable()));
281 FindWindow(IDC_METFILE)->SetLabel(m_file->GetFullName().GetPrintable());
283 resetValueForFilenameTextEdit();
285 Layout();
291 void CFileDetailDialog::OnBnClickedPrevFile(wxCommandEvent&)
293 if (--m_index < 0) {
294 m_index = m_files.size() - 1;
296 m_file = m_files[m_index];
297 UpdateData(true);
301 void CFileDetailDialog::OnBnClickedNextFile(wxCommandEvent&)
303 if (++m_index == (int) m_files.size()) {
304 m_index = 0;
306 m_file = m_files[m_index];
307 UpdateData(true);
311 static bool IsDigit(const wxChar ch)
313 switch (ch) {
314 case '0':
315 case '1':
316 case '2':
317 case '3':
318 case '4':
319 case '5':
320 case '6':
321 case '7':
322 case '8':
323 case '9': return true;
325 return false;
328 static bool IsWordSeparator(const wxChar ch)
330 switch (ch) {
331 case '.':
332 case ',':
333 case '(':
334 case ')':
335 case '[':
336 case ']':
337 case '{':
338 case '}':
339 case '-':
340 case '"':
341 case ' ': return true;
343 return false;
346 static void ReplaceWord(wxString& str, const wxString& replaceFrom, const wxString& replaceTo, bool numbers = false)
348 unsigned int i = 0;
349 unsigned int l = replaceFrom.Length();
350 while (i < str.Length()) {
351 if (str.Mid(i, l) == replaceFrom) {
352 if ((i == 0 || IsWordSeparator(str.GetChar(i-1))) &&
353 ((i == str.Length() - l || IsWordSeparator(str.GetChar(i+l))) ||
354 (numbers && IsDigit(str.GetChar(i+l))))) {
355 str.replace(i, l, replaceTo);
357 i += replaceTo.Length() - 1;
359 i++;
363 void CFileDetailDialog::OnBnClickedButtonStrip(wxCommandEvent& WXUNUSED(evt))
365 wxString filename;
366 filename = CastChild(IDC_FILENAME, wxTextCtrl)->GetValue();
368 int extpos = filename.Find('.', true);
369 wxString ext;
370 if (extpos > 0) {
371 // get the extension - we do not modify it except make it lowercase
372 ext = filename.Mid(extpos);
373 ext.MakeLower();
374 // get rid of extension and replace . with space
375 filename.Truncate(extpos);
376 filename.Replace(wxT("."),wxT(" "));
379 // Replace Space-holders with Spaces
380 filename.Replace(wxT("_"),wxT(" "));
381 filename.Replace(wxT("%20"),wxT(" "));
383 // Some additional formatting
384 filename.Replace(wxT("hYPNOTiC"), wxEmptyString);
385 filename.MakeLower();
386 filename.Replace(wxT("xxx"), wxT("XXX"));
387 // filename.Replace(wxT("xdmnx"), wxEmptyString);
388 // filename.Replace(wxT("pmp"), wxEmptyString);
389 // filename.Replace(wxT("dws"), wxEmptyString);
390 filename.Replace(wxT("www pornreactor com"), wxEmptyString);
391 filename.Replace(wxT("sharereactor"), wxEmptyString);
392 filename.Replace(wxT("found via www filedonkey com"), wxEmptyString);
393 filename.Replace(wxT("deviance"), wxEmptyString);
394 filename.Replace(wxT("adunanza"), wxEmptyString);
395 filename.Replace(wxT("-ftv"), wxEmptyString);
396 filename.Replace(wxT("flt"), wxEmptyString);
397 filename.Replace(wxT("[]"), wxEmptyString);
398 filename.Replace(wxT("()"), wxEmptyString);
400 // Change CD, CD#, VCD{,#}, DVD{,#}, ISO, PC to uppercase
401 ReplaceWord(filename, wxT("cd"), wxT("CD"), true);
402 ReplaceWord(filename, wxT("vcd"), wxT("VCD"), true);
403 ReplaceWord(filename, wxT("dvd"), wxT("DVD"), true);
404 ReplaceWord(filename, wxT("iso"), wxT("ISO"), false);
405 ReplaceWord(filename, wxT("pc"), wxT("PC"), false);
407 // Make leading Caps
408 // and delete 1+ spaces
409 if (filename.Length()>1)
411 bool last_char_space = true;
412 bool last_char_wordseparator = true;
413 unsigned int i = 0;
415 do {
416 wxChar c = filename.GetChar(i);
417 if (c == ' ') {
418 if (last_char_space) {
419 filename.Remove(i, 1);
420 i--;
421 } else {
422 last_char_space = true;
424 } else if (c == '.') {
425 if (last_char_space && i > 0) {
426 i--;
427 filename.Remove(i, 1);
429 last_char_space = false;
430 } else {
431 if (last_char_wordseparator) {
432 wxString tempStr(c);
433 tempStr.MakeUpper();
434 filename.SetChar(i, tempStr.GetChar(0));
435 last_char_space = false;
438 last_char_wordseparator = IsWordSeparator(c);
439 i++;
440 } while (i < filename.Length());
442 if (last_char_space && i > 0) {
443 filename.Remove(i-1, 1);
447 // should stay lowercase
448 ReplaceWord(filename, wxT("By"), wxT("by"));
450 // re-add extension
451 filename += ext;
453 setValueForFilenameTextEdit(filename);
456 void CFileDetailDialog::OnBnClickedTakeOver(wxCommandEvent& WXUNUSED(evt))
458 CFileDetailListCtrl* pmyListCtrl;
459 pmyListCtrl = CastChild( IDC_LISTCTRLFILENAMES, CFileDetailListCtrl );
460 if (pmyListCtrl->GetSelectedItemCount() > 0) {
461 // get first selected item (there is only one)
462 long pos = pmyListCtrl->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
463 if (pos != -1) { // shouldn't happen, we checked if something is selected
464 setValueForFilenameTextEdit(pmyListCtrl->GetItemText(pos));
469 void CFileDetailDialog::OnListClickedTakeOver(wxListEvent& WXUNUSED(evt))
471 wxCommandEvent ev;
472 OnBnClickedTakeOver(ev);
474 // File_checked_for_headers