Upstream tarball 20080304
[amule.git] / src / FileDetailDialog.cpp
blobbe33f87da0f27fafd44c6e11004ac1f3a3142213
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 // 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.
24 //
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 "updownclient.h" // Needed for CUpDownClient
36 #include "PartFile.h" // Needed for CPartFile
37 #include "Color.h" // Needed for SYSCOLOR
38 #include "amule.h" // Needed for theApp
39 #include "SharedFileList.h" // Needed for CSharedFileList
40 #include "OtherFunctions.h"
42 #define ID_MY_TIMER 1652
44 //IMPLEMENT_DYNAMIC(CFileDetailDialog, CDialog)
45 BEGIN_EVENT_TABLE(CFileDetailDialog,wxDialog)
46 EVT_BUTTON(ID_CLOSEWNDFD, CFileDetailDialog::OnClosewnd)
47 EVT_BUTTON(IDC_BUTTONSTRIP, CFileDetailDialog::OnBnClickedButtonStrip)
48 EVT_BUTTON(IDC_TAKEOVER, CFileDetailDialog::OnBnClickedTakeOver)
49 EVT_LIST_ITEM_ACTIVATED(IDC_LISTCTRLFILENAMES, CFileDetailDialog::OnListClickedTakeOver)
50 EVT_BUTTON(IDC_CMTBT, CFileDetailDialog::OnBnClickedShowComment)
51 EVT_TEXT(IDC_FILENAME, CFileDetailDialog::OnTextFileNameChange)
52 EVT_BUTTON(IDC_APPLY_AND_CLOSE, CFileDetailDialog::OnBnClickedOk)
53 EVT_BUTTON(IDC_APPLY, CFileDetailDialog::OnBnClickedApply)
54 EVT_TIMER(ID_MY_TIMER,CFileDetailDialog::OnTimer)
55 END_EVENT_TABLE()
57 CFileDetailDialog::CFileDetailDialog(wxWindow *parent, CPartFile *file)
59 wxDialog(parent, -1, _("File Details"), wxDefaultPosition, wxDefaultSize,
60 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMAXIMIZE_BOX | wxMINIMIZE_BOX),
61 m_file(file),
62 m_filenameChanged(false)
64 theApp->m_FileDetailDialogActive++;
65 m_timer.SetOwner(this, ID_MY_TIMER);
66 m_timer.Start(5000);
67 wxSizer *content = fileDetails(this, true);
68 UpdateData();
69 content->SetSizeHints(this);
70 content->Show(this, true);
73 CFileDetailDialog::~CFileDetailDialog()
75 theApp->m_FileDetailDialogActive = 0;
76 m_timer.Stop();
79 void CFileDetailDialog::OnTimer(wxTimerEvent& WXUNUSED(evt)) {
80 UpdateData();
83 void CFileDetailDialog::OnClosewnd(wxCommandEvent& WXUNUSED(evt))
85 EndModal(0);
88 void CFileDetailDialog::UpdateData()
90 wxString bufferS;
91 CastChild(IDC_FNAME,wxStaticText)->SetLabel(MakeStringEscaped(
92 TruncateFilename(m_file->GetFileName(),60)));
93 CastChild(IDC_METFILE,wxStaticText)->SetLabel(MakeStringEscaped(
94 TruncateFilename(m_file->GetFullName(),60,true)));
96 wxString tmp = CastChild(IDC_FILENAME, wxTextCtrl)->GetValue();
97 if (tmp.Length() < 3) {
98 resetValueForFilenameTextEdit();
101 CastChild(IDC_FHASH,wxStaticText)->SetLabel(m_file->GetFileHash().Encode());
102 bufferS = wxString::Format(wxT("%llu bytes ("), m_file->GetFileSize())
103 + CastItoXBytes(m_file->GetFileSize())
104 + wxT(")");
105 CastChild(IDC_FSIZE,wxControl)->SetLabel(bufferS);
106 CastChild(IDC_PFSTATUS,wxControl)->SetLabel(m_file->getPartfileStatus());
107 bufferS = wxString::Format(wxT("%i (%i)"),m_file->GetPartCount(),m_file->GetHashCount());
108 CastChild(IDC_PARTCOUNT,wxControl)->SetLabel(bufferS);
109 CastChild(IDC_TRANSFERRED,wxControl)->SetLabel(CastItoXBytes(m_file->GetTransferred()));
110 CastChild(IDC_FD_STATS1,wxControl)->SetLabel(CastItoXBytes(m_file->GetLostDueToCorruption()));
111 CastChild(IDC_FD_STATS2,wxControl)->SetLabel(CastItoXBytes(m_file->GetGainDueToCompression()));
112 CastChild(IDC_FD_STATS3,wxControl)->SetLabel(CastItoIShort(m_file->TotalPacketsSavedDueToICH()));
113 CastChild(IDC_COMPLSIZE,wxControl)->SetLabel(CastItoXBytes(m_file->GetCompletedSize()));
114 bufferS = wxString::Format(_("%.2f%% done"),m_file->GetPercentCompleted());
115 CastChild(IDC_PROCCOMPL,wxControl)->SetLabel(bufferS);
116 bufferS = wxString::Format(_("%.2f kB/s"),(float)m_file->GetKBpsDown());
117 CastChild(IDC_DATARATE,wxControl)->SetLabel(bufferS);
118 bufferS = wxString::Format(wxT("%i"),m_file->GetSourceCount());
119 CastChild(IDC_SOURCECOUNT,wxControl)->SetLabel(bufferS);
120 bufferS = wxString::Format(wxT("%i"),m_file->GetTransferingSrcCount());
121 CastChild(IDC_SOURCECOUNT2,wxControl)->SetLabel(bufferS);
122 bufferS = wxString::Format(wxT("%i (%.1f%%)"),
123 m_file->GetAvailablePartCount(),
124 ((m_file->GetAvailablePartCount() * 100.0f)/ m_file->GetPartCount()));
125 CastChild(IDC_PARTAVAILABLE,wxControl)->SetLabel(bufferS);
126 bufferS = CastSecondsToHM(m_file->GetDlActiveTime());
127 CastChild(IDC_DLACTIVETIME, wxControl)->SetLabel(bufferS);
129 if (m_file->lastseencomplete==0) {
130 bufferS = wxString(_("Unknown")).MakeLower();
131 } else {
132 wxDateTime last_seen(m_file->lastseencomplete);
133 bufferS = last_seen.FormatISODate() + wxT(" ") + last_seen.FormatISOTime();
136 CastChild(IDC_LASTSEENCOMPL,wxControl)->SetLabel(bufferS);
137 setEnableForApplyButton();
138 // disable "Show all comments" button if there are no comments
139 CastChild(IDC_CMTBT, wxControl)->Enable(!m_file->GetRatingAndComments().empty());
140 FillSourcenameList();
141 Layout();
144 // CFileDetailDialog message handlers
146 #define LVCFMT_LEFT wxLIST_FORMAT_LEFT
149 void CFileDetailDialog::FillSourcenameList()
151 CFileDetailListCtrl* pmyListCtrl;
152 int itempos;
153 pmyListCtrl = CastChild(IDC_LISTCTRLFILENAMES, CFileDetailListCtrl );
155 // reset
156 for (int i=0;i<pmyListCtrl->GetItemCount();i++){
157 pmyListCtrl->SetItem(i, 1, wxT("0"));
158 SourcenameItem *item = reinterpret_cast<SourcenameItem *>(pmyListCtrl->GetItemData(i));
159 item->count = 0;
162 // update
163 #ifdef CLIENT_GUI
164 const SourcenameItemList &sources = m_file->GetSourcenameItemList();
165 for (SourcenameItemList::const_iterator it = sources.begin(); it != sources.end(); ++it) {
166 const SourcenameItem &cur_src = *it;
167 itempos = pmyListCtrl->FindItem(-1,cur_src.name);
168 if (itempos == -1) {
169 int itemid = pmyListCtrl->InsertItem(0, cur_src.name);
170 pmyListCtrl->SetItem(0, 1, wxString::Format(wxT("%li"), cur_src.count));
171 SourcenameItem *item = new SourcenameItem(cur_src.name, cur_src.count);
172 pmyListCtrl->SetItemPtrData(0, reinterpret_cast<wxUIntPtr>(item));
173 // background.. argh -- PA: was in old version - do we still need this?
174 wxListItem tmpitem;
175 tmpitem.m_itemId = itemid;
176 tmpitem.SetBackgroundColour(SYSCOLOR(wxSYS_COLOUR_LISTBOX));
177 pmyListCtrl->SetItem(tmpitem);
178 } else {
179 SourcenameItem *item = reinterpret_cast<SourcenameItem *>(pmyListCtrl->GetItemData(itempos));
180 item->count = cur_src.count;
181 pmyListCtrl->SetItem(itempos, 1, wxString::Format(wxT("%li"), cur_src.count));
184 #else // CLIENT_GUI
185 const CPartFile::SourceSet& sources = m_file->GetSourceList();
186 CPartFile::SourceSet::const_iterator it = sources.begin();
187 for ( ; it != sources.end(); ++it ) {
188 const CUpDownClient &cur_src = **it;
189 if (cur_src.GetRequestFile() != m_file ||
190 cur_src.GetClientFilename().Length() == 0) {
191 continue;
194 itempos = pmyListCtrl->FindItem(-1,cur_src.GetClientFilename());
195 if (itempos == -1) {
196 int itemid = pmyListCtrl->InsertItem(0, cur_src.GetClientFilename());
197 pmyListCtrl->SetItem(0, 1, wxT("1"));
198 SourcenameItem *item = new SourcenameItem(cur_src.GetClientFilename(), 1);
199 pmyListCtrl->SetItemPtrData(0, reinterpret_cast<wxUIntPtr>(item));
200 // background.. argh -- PA: was in old version - do we still need this?
201 wxListItem tmpitem;
202 tmpitem.m_itemId=itemid;
203 tmpitem.SetBackgroundColour(SYSCOLOR(wxSYS_COLOUR_LISTBOX));
204 pmyListCtrl->SetItem(tmpitem);
205 } else {
206 SourcenameItem *item = reinterpret_cast<SourcenameItem *>(pmyListCtrl->GetItemData(itempos));
207 item->count++;
208 pmyListCtrl->SetItem(itempos, 1, wxString::Format(wxT("%li"), item->count));
211 #endif // CLIENT_GUI
213 pmyListCtrl->SortList();
215 // remove 0'er
216 for (int i = 0; i < pmyListCtrl->GetItemCount(); ++i) {
217 SourcenameItem *item = reinterpret_cast<SourcenameItem *>(pmyListCtrl->GetItemData(i));
218 if (item->count == 0) {
219 delete item;
220 pmyListCtrl->DeleteItem(i);
221 i--; // PA: one step back is enough, no need to go back to 0
225 Layout();
229 void CFileDetailDialog::OnBnClickedShowComment(wxCommandEvent& WXUNUSED(evt))
231 CCommentDialogLst(this,m_file).ShowModal();
235 void CFileDetailDialog::resetValueForFilenameTextEdit()
237 CastChild(IDC_FILENAME, wxTextCtrl)->SetValue(m_file->GetFileName().GetPrintable());
238 m_filenameChanged = false;
239 setEnableForApplyButton();
243 void CFileDetailDialog::setValueForFilenameTextEdit(const wxString &s)
245 CastChild(IDC_FILENAME, wxTextCtrl)->SetValue(s);
246 m_filenameChanged = true;
247 setEnableForApplyButton();
251 void CFileDetailDialog::setEnableForApplyButton()
253 CastChild(IDC_APPLY, wxControl)->Enable(
254 m_file->IsPartFile() && // Currently renaming of completed files causes problem with kad
255 m_file->GetStatus() != PS_COMPLETE &&
256 m_file->GetStatus() != PS_COMPLETING &&
257 m_filenameChanged);
261 void CFileDetailDialog::OnTextFileNameChange(wxCommandEvent& WXUNUSED(evt))
263 m_filenameChanged = true;
264 setEnableForApplyButton();
268 void CFileDetailDialog::OnBnClickedOk(wxCommandEvent& evt)
270 OnBnClickedApply(evt);
271 OnClosewnd(evt);
275 void CFileDetailDialog::OnBnClickedApply(wxCommandEvent& WXUNUSED(evt))
277 CPath fileName = CPath(CastChild(IDC_FILENAME, wxTextCtrl)->GetValue());
279 if (fileName.IsOk() && (fileName != m_file->GetFileName())) {
280 if (theApp->sharedfiles->RenameFile(m_file, fileName)) {
281 FindWindow(IDC_FNAME)->SetLabel(MakeStringEscaped(m_file->GetFileName().GetPrintable()));
282 FindWindow(IDC_METFILE)->SetLabel(m_file->GetFullName().GetPrintable());
284 resetValueForFilenameTextEdit();
286 Layout();
292 bool IsDigit(const wxChar ch)
294 switch (ch) {
295 case '0':
296 case '1':
297 case '2':
298 case '3':
299 case '4':
300 case '5':
301 case '6':
302 case '7':
303 case '8':
304 case '9': return true;
306 return false;
309 bool IsWordSeparator(const wxChar ch)
311 switch (ch) {
312 case '.':
313 case ',':
314 case '(':
315 case ')':
316 case '[':
317 case ']':
318 case '{':
319 case '}':
320 case '-':
321 case '"':
322 case ' ': return true;
324 return false;
327 void ReplaceWord(wxString& str, const wxString& replaceFrom, const wxString& replaceTo, bool numbers = false)
329 unsigned int i = 0;
330 unsigned int l = replaceFrom.Length();
331 while (i < str.Length()) {
332 if (str.Mid(i, l) == replaceFrom) {
333 if ((i == 0 || IsWordSeparator(str.GetChar(i-1))) &&
334 ((i == str.Length() - l || IsWordSeparator(str.GetChar(i+l))) ||
335 (numbers && IsDigit(str.GetChar(i+l))))) {
336 str.replace(i, l, replaceTo);
338 i += replaceTo.Length() - 1;
340 i++;
344 void CFileDetailDialog::OnBnClickedButtonStrip(wxCommandEvent& WXUNUSED(evt))
346 wxString filename;
347 filename = CastChild(IDC_FILENAME, wxTextCtrl)->GetValue();
349 int extpos = filename.Find('.', true);
350 wxString ext;
351 if (extpos > 0) {
352 // get the extension - we do not modify it except make it lowercase
353 ext = filename.Mid(extpos);
354 ext.MakeLower();
355 // get rid of extension and replace . with space
356 filename.Truncate(extpos);
357 filename.Replace(wxT("."),wxT(" "));
360 // Replace Space-holders with Spaces
361 filename.Replace(wxT("_"),wxT(" "));
362 filename.Replace(wxT("%20"),wxT(" "));
364 // Some additional formatting
365 filename.Replace(wxT("hYPNOTiC"), wxEmptyString);
366 filename.MakeLower();
367 filename.Replace(wxT("xxx"), wxT("XXX"));
368 // filename.Replace(wxT("xdmnx"), wxEmptyString);
369 // filename.Replace(wxT("pmp"), wxEmptyString);
370 // filename.Replace(wxT("dws"), wxEmptyString);
371 filename.Replace(wxT("www pornreactor com"), wxEmptyString);
372 filename.Replace(wxT("sharereactor"), wxEmptyString);
373 filename.Replace(wxT("found via www filedonkey com"), wxEmptyString);
374 filename.Replace(wxT("deviance"), wxEmptyString);
375 filename.Replace(wxT("adunanza"), wxEmptyString);
376 filename.Replace(wxT("-ftv"), wxEmptyString);
377 filename.Replace(wxT("flt"), wxEmptyString);
378 filename.Replace(wxT("[]"), wxEmptyString);
379 filename.Replace(wxT("()"), wxEmptyString);
381 // Change CD, CD#, VCD{,#}, DVD{,#}, ISO, PC to uppercase
382 ReplaceWord(filename, wxT("cd"), wxT("CD"), true);
383 ReplaceWord(filename, wxT("vcd"), wxT("VCD"), true);
384 ReplaceWord(filename, wxT("dvd"), wxT("DVD"), true);
385 ReplaceWord(filename, wxT("iso"), wxT("ISO"), false);
386 ReplaceWord(filename, wxT("pc"), wxT("PC"), false);
388 // Make leading Caps
389 // and delete 1+ spaces
390 if (filename.Length()>1)
392 bool last_char_space = true;
393 bool last_char_wordseparator = true;
394 unsigned int i = 0;
396 do {
397 wxChar c = filename.GetChar(i);
398 if (c == ' ') {
399 if (last_char_space) {
400 filename.Remove(i, 1);
401 i--;
402 } else {
403 last_char_space = true;
405 } else if (c == '.') {
406 if (last_char_space && i > 0) {
407 i--;
408 filename.Remove(i, 1);
410 last_char_space = false;
411 } else {
412 if (last_char_wordseparator) {
413 wxString tempStr(c);
414 tempStr.MakeUpper();
415 filename.SetChar(i, tempStr.GetChar(0));
416 last_char_space = false;
419 last_char_wordseparator = IsWordSeparator(c);
420 i++;
421 } while (i < filename.Length());
423 if (last_char_space && i > 0) {
424 filename.Remove(i-1, 1);
428 // should stay lowercase
429 ReplaceWord(filename, wxT("By"), wxT("by"));
431 // re-add extension
432 filename += ext;
434 setValueForFilenameTextEdit(filename);
437 void CFileDetailDialog::OnBnClickedTakeOver(wxCommandEvent& WXUNUSED(evt))
439 CFileDetailListCtrl* pmyListCtrl;
440 pmyListCtrl = CastChild( IDC_LISTCTRLFILENAMES, CFileDetailListCtrl );
441 if (pmyListCtrl->GetSelectedItemCount() > 0) {
442 long pos=-1;
443 for(;;) {
444 pos=pmyListCtrl->GetNextItem(pos,wxLIST_NEXT_ALL,wxLIST_STATE_SELECTED);
445 if(pos==-1) {
446 break;
448 setValueForFilenameTextEdit(pmyListCtrl->GetItemText(pos));
453 void CFileDetailDialog::OnListClickedTakeOver(wxListEvent& WXUNUSED(evt))
455 CFileDetailListCtrl* pmyListCtrl;
456 pmyListCtrl = CastChild( IDC_LISTCTRLFILENAMES, CFileDetailListCtrl );
457 if (pmyListCtrl->GetSelectedItemCount() > 0) {
458 long pos=-1;
459 for(;;) {
460 pos=pmyListCtrl->GetNextItem(pos,wxLIST_NEXT_ALL,wxLIST_STATE_SELECTED);
461 if(pos==-1) {
462 break;
464 setValueForFilenameTextEdit(pmyListCtrl->GetItemText(pos));
468 // File_checked_for_headers