2 // This file is part of the aMule Project.
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 )
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
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 "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
)
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
),
62 m_filenameChanged(false)
64 theApp
->m_FileDetailDialogActive
++;
65 m_timer
.SetOwner(this, ID_MY_TIMER
);
67 wxSizer
*content
= fileDetails(this, true);
69 content
->SetSizeHints(this);
70 content
->Show(this, true);
73 CFileDetailDialog::~CFileDetailDialog()
75 theApp
->m_FileDetailDialogActive
= 0;
79 void CFileDetailDialog::OnTimer(wxTimerEvent
& WXUNUSED(evt
)) {
83 void CFileDetailDialog::OnClosewnd(wxCommandEvent
& WXUNUSED(evt
))
88 void CFileDetailDialog::UpdateData()
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())
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();
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();
144 // CFileDetailDialog message handlers
146 #define LVCFMT_LEFT wxLIST_FORMAT_LEFT
149 void CFileDetailDialog::FillSourcenameList()
151 CFileDetailListCtrl
* pmyListCtrl
;
153 pmyListCtrl
= CastChild(IDC_LISTCTRLFILENAMES
, CFileDetailListCtrl
);
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
));
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
);
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?
175 tmpitem
.m_itemId
= itemid
;
176 tmpitem
.SetBackgroundColour(SYSCOLOR(wxSYS_COLOUR_LISTBOX
));
177 pmyListCtrl
->SetItem(tmpitem
);
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
));
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) {
194 itempos
= pmyListCtrl
->FindItem(-1,cur_src
.GetClientFilename());
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?
202 tmpitem
.m_itemId
=itemid
;
203 tmpitem
.SetBackgroundColour(SYSCOLOR(wxSYS_COLOUR_LISTBOX
));
204 pmyListCtrl
->SetItem(tmpitem
);
206 SourcenameItem
*item
= reinterpret_cast<SourcenameItem
*>(pmyListCtrl
->GetItemData(itempos
));
208 pmyListCtrl
->SetItem(itempos
, 1, wxString::Format(wxT("%li"), item
->count
));
213 pmyListCtrl
->SortList();
216 for (int i
= 0; i
< pmyListCtrl
->GetItemCount(); ++i
) {
217 SourcenameItem
*item
= reinterpret_cast<SourcenameItem
*>(pmyListCtrl
->GetItemData(i
));
218 if (item
->count
== 0) {
220 pmyListCtrl
->DeleteItem(i
);
221 i
--; // PA: one step back is enough, no need to go back to 0
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
&&
261 void CFileDetailDialog::OnTextFileNameChange(wxCommandEvent
& WXUNUSED(evt
))
263 m_filenameChanged
= true;
264 setEnableForApplyButton();
268 void CFileDetailDialog::OnBnClickedOk(wxCommandEvent
& evt
)
270 OnBnClickedApply(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();
292 bool IsDigit(const wxChar ch
)
304 case '9': return true;
309 bool IsWordSeparator(const wxChar ch
)
322 case ' ': return true;
327 void ReplaceWord(wxString
& str
, const wxString
& replaceFrom
, const wxString
& replaceTo
, bool numbers
= false)
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;
344 void CFileDetailDialog::OnBnClickedButtonStrip(wxCommandEvent
& WXUNUSED(evt
))
347 filename
= CastChild(IDC_FILENAME
, wxTextCtrl
)->GetValue();
349 int extpos
= filename
.Find('.', true);
352 // get the extension - we do not modify it except make it lowercase
353 ext
= filename
.Mid(extpos
);
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);
389 // and delete 1+ spaces
390 if (filename
.Length()>1)
392 bool last_char_space
= true;
393 bool last_char_wordseparator
= true;
397 wxChar c
= filename
.GetChar(i
);
399 if (last_char_space
) {
400 filename
.Remove(i
, 1);
403 last_char_space
= true;
405 } else if (c
== '.') {
406 if (last_char_space
&& i
> 0) {
408 filename
.Remove(i
, 1);
410 last_char_space
= false;
412 if (last_char_wordseparator
) {
415 filename
.SetChar(i
, tempStr
.GetChar(0));
416 last_char_space
= false;
419 last_char_wordseparator
= IsWordSeparator(c
);
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"));
434 setValueForFilenameTextEdit(filename
);
437 void CFileDetailDialog::OnBnClickedTakeOver(wxCommandEvent
& WXUNUSED(evt
))
439 CFileDetailListCtrl
* pmyListCtrl
;
440 pmyListCtrl
= CastChild( IDC_LISTCTRLFILENAMES
, CFileDetailListCtrl
);
441 if (pmyListCtrl
->GetSelectedItemCount() > 0) {
444 pos
=pmyListCtrl
->GetNextItem(pos
,wxLIST_NEXT_ALL
,wxLIST_STATE_SELECTED
);
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) {
460 pos
=pmyListCtrl
->GetNextItem(pos
,wxLIST_NEXT_ALL
,wxLIST_STATE_SELECTED
);
464 setValueForFilenameTextEdit(pmyListCtrl
->GetItemText(pos
));
468 // File_checked_for_headers