1 ////////////////////////////////////////////////////////////////////////////////
2 /// Name: AlcFrame Class
4 /// Purpose: aMule ed2k link creator
6 /// Author: ThePolish <thepolish@vipmail.ru>
8 /// Copyright (c) 2004-2011 ThePolish ( thepolish@vipmail.ru )
10 /// Copyright (c) 2004-2011 Marcelo Roberto Jimenez ( phoenix@amule.org )
13 /// http://jimmac.musichall.cz/ikony.php3
14 /// http://www.everaldo.com
15 /// http://www.icomania.com
17 /// This program is free software; you can redistribute it and/or modify
18 /// it under the terms of the GNU General Public License as published by
19 /// (at your option) any later version.
21 /// This program is distributed in the hope that it will be useful,
22 /// but WITHOUT ANY WARRANTY; without even the implied warranty of
23 /// the Free Software Foundation; either version 2 of the License, or
24 /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 /// GNU General Public License for more details.
27 /// You should have received a copy of the GNU General Public License
28 /// along with this program; if not, write to the
29 /// Free Software Foundation, Inc.,
30 /// 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
31 ////////////////////////////////////////////////////////////////////////////////
34 #include <wx/clipbrd.h>
35 #include <wx/dataobj.h>
37 #include <wx/filedlg.h>
38 #include <wx/filename.h>
39 #include <wx/button.h>
42 #include <wx/msgdlg.h>
43 #include <wx/statbox.h>
44 #include <wx/stattext.h>
45 #include <wx/textfile.h>
47 #include <wx/toolbar.h>
54 #elif defined(__WXMAC__)
55 #include <CoreServices/CoreServices.h>
56 #if wxCHECK_VERSION(2, 9, 0)
57 #include <wx/osx/core/cfstring.h> // Do_not_auto_remove
59 #include <wx/mac/corefoundation/cfstring.h>
71 AlcFrame::AlcFrame (const wxString
& title
):
72 wxFrame ((wxFrame
*) NULL
, -1, title
)
76 wxIcon
icon(wxT("alc"));
79 icon
.CopyFromBitmap(AlcPix::getPixmap(wxT("alc")));
85 SetStatusText (_("Welcome!"));
87 // Unused dialog for now
90 // Frame Vertical sizer
91 m_frameVBox
= new wxBoxSizer (wxVERTICAL
);
93 // Add Main panel to frame (needed by win32 for padding sub panels)
94 m_mainPanel
= new wxPanel (this, -1);
96 // Main Panel Vertical Sizer
97 m_mainPanelVBox
= new wxBoxSizer (wxVERTICAL
);
99 // Main Panel static line
100 m_staticLine
= new wxStaticLine (m_mainPanel
, -1);
101 m_mainPanelVBox
->Add (m_staticLine
, 0, wxALL
| wxGROW
);
105 new wxStaticBox (m_mainPanel
, -1, _("Input parameters"));
106 m_inputSBoxSizer
= new wxStaticBoxSizer (m_inputSBox
, wxHORIZONTAL
);
109 m_inputFlexSizer
= new wxFlexGridSizer (6, 2, 5, 10);
111 // Left col is growable
112 m_inputFlexSizer
->AddGrowableCol (0);
115 m_inputFileStaticText
=new wxStaticText(m_mainPanel
, -1,
117 wxDefaultPosition
,wxDefaultSize
,wxALIGN_CENTRE
);
119 m_inputAddStaticText
=new wxStaticText(m_mainPanel
, -1,
120 _("Add Optional URLs for this file"),
121 wxDefaultPosition
,wxDefaultSize
,wxALIGN_CENTRE
);
124 m_inputFileTextCtrl
= new wxTextCtrl (m_mainPanel
,-1,wxEmptyString
,
125 wxDefaultPosition
, wxSize(300,-1));
126 m_inputFileTextCtrl
->
128 ("Enter here the file you want to compute the eD2k link"));
130 m_inputAddTextCtrl
= new wxTextCtrl (m_mainPanel
,-1,wxEmptyString
,
131 wxDefaultPosition
, wxSize(300,-1));
134 ("Enter here the URL you want to add to the eD2k link: Add / at the end to let aLinkCreator append the current file name"));
137 m_inputUrlListBox
= new wxListBox(m_mainPanel
, -1, wxDefaultPosition
,
138 wxDefaultSize
, 0, NULL
, wxLB_SINGLE
| wxLB_NEEDED_SB
| wxLB_HSCROLL
);
141 m_inputFileBrowseButton
=
142 new wxButton (m_mainPanel
, ID_BROWSE_BUTTON
, wxString (_("Browse")));
145 new wxButton (m_mainPanel
, ID_ADD_BUTTON
, wxString (_("Add")));
148 m_buttonUrlVBox
= new wxBoxSizer (wxVERTICAL
);
150 new wxButton (m_mainPanel
, ID_REMOVE_BUTTON
, wxString (_("Remove")));
152 new wxButton (m_mainPanel
, ID_CLEAR_BUTTON
, wxString (_("Clear")));
154 m_buttonUrlVBox
->Add (m_removeButton
, 0, wxALIGN_CENTER
| wxTOP
| wxBOTTOM
, 5);
155 m_buttonUrlVBox
->Add (m_clearButton
, 0, wxALIGN_CENTER
| wxTOP
| wxBOTTOM
, 5);
159 new wxCheckBox (m_mainPanel
, ID_PARTHASHES_CHECK
,
161 ("Create link with part-hashes"));
163 m_parthashesCheck
->SetValue(false);
167 ("Help to spread new and rare files faster, at the cost of an increased link size"));
170 m_inputFlexSizer
->Add (m_inputFileStaticText
, 1, wxGROW
| wxALIGN_BOTTOM
| wxTOP
, 10);
171 m_inputFlexSizer
->Add (1,1);
173 m_inputFlexSizer
->Add (m_inputFileTextCtrl
, 1, wxGROW
| wxALIGN_TOP
, 0);
174 m_inputFlexSizer
->Add (m_inputFileBrowseButton
, 0, wxGROW
| wxALIGN_TOP
, 0);
176 m_inputFlexSizer
->Add (m_inputAddStaticText
, 1, wxGROW
| wxALIGN_BOTTOM
| wxTOP
, 10);
177 m_inputFlexSizer
->Add (1,1);
179 m_inputFlexSizer
->Add (m_inputAddTextCtrl
, 1, wxGROW
| wxALIGN_TOP
, 0);
180 m_inputFlexSizer
->Add (m_inputAddButton
, 0, wxGROW
| wxALIGN_TOP
, 0);
182 m_inputFlexSizer
->Add (m_inputUrlListBox
, 0, wxGROW
| wxALIGN_CENTER
, 0);
183 m_inputFlexSizer
->Add (m_buttonUrlVBox
, 0, wxGROW
| wxALIGN_CENTER
, 0);
185 m_inputFlexSizer
->Add (m_parthashesCheck
, 0, wxGROW
| wxALIGN_CENTER
| wxTOP
, 10);
186 m_inputFlexSizer
->Add (1,1);
188 m_inputSBoxSizer
->Add (m_inputFlexSizer
, 1, wxGROW
| wxALIGN_CENTER
| wxALL
, 10);
189 m_mainPanelVBox
->Add (m_inputSBoxSizer
, 0, wxGROW
| wxALIGN_CENTER
| wxALL
, 10);
192 // MD4 Hash Vertical Box Sizer
193 m_md4HashSBox
= new wxStaticBox (m_mainPanel
, -1, _("MD4 File Hash"));
194 m_md4HashSBoxSizer
= new wxStaticBoxSizer (m_md4HashSBox
, wxHORIZONTAL
);
197 m_md4HashTextCtrl
= new wxTextCtrl( m_mainPanel
, -1, wxEmptyString
, wxDefaultPosition
,
198 wxDefaultSize
, wxTE_READONLY
);
200 m_md4HashSBoxSizer
->Add (m_md4HashTextCtrl
, 1, wxALL
| wxALIGN_CENTER
, 5);
201 m_mainPanelVBox
->Add( m_md4HashSBoxSizer
, 0, wxALL
| wxGROW
, 10 );
204 // Hash Vertical Box Sizer
205 m_e2kHashSBox
= new wxStaticBox (m_mainPanel
, -1, _("eD2k File Hash"));
206 m_e2kHashSBoxSizer
= new wxStaticBoxSizer (m_e2kHashSBox
, wxHORIZONTAL
);
209 m_e2kHashTextCtrl
= new wxTextCtrl( m_mainPanel
, -1, wxEmptyString
, wxDefaultPosition
,
210 wxDefaultSize
, wxTE_READONLY
);
212 m_e2kHashSBoxSizer
->Add (m_e2kHashTextCtrl
, 1, wxALL
| wxALIGN_CENTER
, 5);
213 m_mainPanelVBox
->Add( m_e2kHashSBoxSizer
, 0, wxALL
| wxGROW
, 10 );
215 // Ed2k Vertical Box Sizer
216 m_ed2kSBox
= new wxStaticBox (m_mainPanel
, -1, _("eD2k link"));
217 m_ed2kSBoxSizer
= new wxStaticBoxSizer (m_ed2kSBox
, wxVERTICAL
);
220 m_ed2kTextCtrl
= new wxTextCtrl( m_mainPanel
, -1, wxEmptyString
, wxDefaultPosition
,
221 wxSize(-1,60), wxTE_MULTILINE
|wxTE_READONLY
|wxVSCROLL
);
223 m_ed2kSBoxSizer
->Add (m_ed2kTextCtrl
, 1, wxALL
| wxGROW
, 5);
224 m_mainPanelVBox
->Add( m_ed2kSBoxSizer
, 1, wxALL
| wxGROW
, 10 );
227 m_buttonHBox
= new wxBoxSizer (wxHORIZONTAL
);
229 new wxButton (m_mainPanel
, ID_START_BUTTON
, wxString (_("Start")));
231 new wxButton (m_mainPanel
, ID_SAVEAS_BUTTON
, wxString (_("Save")));
233 new wxButton (m_mainPanel
, ID_COPY_BUTTON
, wxString (_("Copy to clipboard")));
235 new wxButton (m_mainPanel
, ID_EXIT_BUTTON
, wxString (_("Exit")));
237 m_buttonHBox
->Add (m_copyButton
, 0, wxALIGN_LEFT
| wxALL
, 5);
238 m_buttonHBox
->Add(1,1,1);
239 m_buttonHBox
->Add (m_startButton
, 0, wxALIGN_RIGHT
| wxALL
, 5);
240 m_buttonHBox
->Add (m_saveButton
, 0, wxALIGN_RIGHT
| wxALL
, 5);
241 m_buttonHBox
->Add (m_closeButton
, 0, wxALIGN_RIGHT
| wxALL
, 5);
244 m_mainPanelVBox
->Add (m_buttonHBox
, 0, wxALL
| wxGROW
, 5);
247 m_toolBarBitmaps
[0] = AlcPix::getPixmap(wxT("open"));
248 m_toolBarBitmaps
[1] = AlcPix::getPixmap(wxT("copy"));
249 m_toolBarBitmaps
[2] = AlcPix::getPixmap(wxT("saveas"));
250 m_toolBarBitmaps
[3] = AlcPix::getPixmap(wxT("about"));
252 // Constructing toolbar
254 new wxToolBar (this, -1, wxDefaultPosition
, wxDefaultSize
,
255 wxTB_HORIZONTAL
| wxTB_FLAT
);
257 m_toolbar
->SetToolBitmapSize (wxSize (32, 32));
258 m_toolbar
->SetMargins (2, 2);
260 m_toolbar
->AddTool (ID_BAR_OPEN
, _("Open"), m_toolBarBitmaps
[0],
261 _("Open a file to compute its eD2k link"));
263 m_toolbar
->AddTool (ID_BAR_COPY
, _("Copy"), m_toolBarBitmaps
[1],
264 _("Copy computed eD2k link to clipboard"));
266 m_toolbar
->AddTool (ID_BAR_SAVEAS
, _("Save as"), m_toolBarBitmaps
[2],
267 _("Save computed eD2k link to file"));
269 m_toolbar
->AddSeparator ();
271 m_toolbar
->AddTool (ID_BAR_ABOUT
, _("About"), m_toolBarBitmaps
[3],
272 _("About aLinkCreator"));
274 m_toolbar
->Realize ();
276 SetToolBar (m_toolbar
);
279 m_mainPanel
->SetAutoLayout(true);
280 m_mainPanel
->SetSizerAndFit (m_mainPanelVBox
);
283 m_frameVBox
->Add (m_mainPanel
, 1, wxALL
| wxGROW
, 0);
284 SetAutoLayout (true);
285 SetSizerAndFit (m_frameVBox
);
287 m_startButton
->SetFocus();
291 AlcFrame::~AlcFrame ()
295 BEGIN_EVENT_TABLE (AlcFrame
, wxFrame
)
296 EVT_TOOL (ID_BAR_OPEN
, AlcFrame::OnBarOpen
)
297 EVT_TOOL (ID_BAR_SAVEAS
, AlcFrame::OnBarSaveAs
)
298 EVT_TOOL (ID_BAR_COPY
, AlcFrame::OnBarCopy
)
299 EVT_TOOL (ID_BAR_ABOUT
, AlcFrame::OnBarAbout
)
300 EVT_BUTTON (ID_START_BUTTON
, AlcFrame::OnStartButton
)
301 EVT_BUTTON (ID_EXIT_BUTTON
, AlcFrame::OnCloseButton
)
302 EVT_BUTTON (ID_SAVEAS_BUTTON
, AlcFrame::OnSaveAsButton
)
303 EVT_BUTTON (ID_COPY_BUTTON
, AlcFrame::OnCopyButton
)
304 EVT_BUTTON (ID_BROWSE_BUTTON
, AlcFrame::OnBrowseButton
)
305 EVT_BUTTON (ID_ADD_BUTTON
, AlcFrame::OnAddUrlButton
)
306 EVT_BUTTON (ID_REMOVE_BUTTON
, AlcFrame::OnRemoveUrlButton
)
307 EVT_BUTTON (ID_CLEAR_BUTTON
, AlcFrame::OnClearUrlButton
)
310 /// Toolbar Open button
312 AlcFrame::OnBarOpen (wxCommandEvent
& WXUNUSED(event
))
317 /// Browse button to select file to hash
319 AlcFrame::OnBrowseButton (wxCommandEvent
& WXUNUSED(event
))
324 /// Set File to hash in wxTextCtrl
326 AlcFrame::SetFileToHash()
331 HRESULT hr
= SHGetSpecialFolderLocation(NULL
, CSIDL_PERSONAL
, &pidl
);
333 if (!SHGetPathFromIDList(pidl
, wxStringBuffer(browseroot
, MAX_PATH
))) {
334 browseroot
= wxFileName::GetHomeDir();
337 browseroot
= wxFileName::GetHomeDir();
341 SHGetMalloc(&pMalloc
);
347 #elif defined(__WXMAC__)
351 if (FSFindFolder(kUserDomain
, kDocumentsFolderType
, kCreateFolder
, &fsRef
) == noErr
)
353 CFURLRef urlRef
= CFURLCreateFromFSRef(NULL
, &fsRef
);
354 CFStringRef cfString
= CFURLCopyFileSystemPath(urlRef
, kCFURLPOSIXPathStyle
);
356 #if wxCHECK_VERSION(2, 9, 0)
357 browseroot
= wxCFStringRef(cfString
).AsString(wxLocale::GetSystemEncoding());
359 browseroot
= wxMacCFStringHolder(cfString
).AsString(wxLocale::GetSystemEncoding());
362 browseroot
= wxFileName::GetHomeDir();
366 wxString browseroot
= wxFileName::GetHomeDir();
368 const wxString
& filename
=
369 wxFileSelector (_("Select the file you want to compute the eD2k link"),
370 browseroot
, wxEmptyString
, wxEmptyString
, wxT("*.*"),
371 wxFD_OPEN
| wxFD_FILE_MUST_EXIST
, this);
373 if (!filename
.empty ())
375 m_inputFileTextCtrl
->SetValue(filename
);
379 /// Toolbar Save As button
381 AlcFrame::OnBarSaveAs (wxCommandEvent
& WXUNUSED(event
))
383 SaveEd2kLinkToFile();
388 AlcFrame::OnSaveAsButton(wxCommandEvent
& WXUNUSED(event
))
390 SaveEd2kLinkToFile();
393 /// Copy Ed2k link to clip board
395 AlcFrame::CopyEd2kLinkToClipBoard()
397 wxString link
= m_ed2kTextCtrl
->GetValue();
400 wxClipboardLocker clipLocker
;
403 wxLogError(_("Can't open the clipboard"));
408 wxTheClipboard
->AddData(new wxTextDataObject(link
));
412 SetStatusText (_("Nothing to copy for now !"));
418 AlcFrame::OnCopyButton(wxCommandEvent
& WXUNUSED(event
))
420 CopyEd2kLinkToClipBoard();
423 /// Toolbar Copy button
425 AlcFrame::OnBarCopy(wxCommandEvent
& WXUNUSED(event
))
427 CopyEd2kLinkToClipBoard();
430 /// Save computed Ed2k link to file
432 AlcFrame::SaveEd2kLinkToFile()
434 wxString
link(m_ed2kTextCtrl
->GetValue());
438 const wxString
& filename
=
439 wxFileSelector (_("Select the file to your computed eD2k link"),
440 wxFileName::GetHomeDir(),wxT("my_ed2k_link"),
441 wxT("txt"), wxT("*.txt"), wxFD_SAVE
, this);
443 if (!filename
.empty ())
445 // Open file and let wxFile destructor close the file
446 // Closing it explicitly may crash on Win32 ...
447 wxFile
file(filename
,wxFile::write_append
);
448 if (! file
.IsOpened())
450 SetStatusText (_("Unable to open ") + filename
);
453 file
.Write(link
+ wxTextFile::GetEOL());
457 SetStatusText (_("Please, enter a non empty file name"));
462 SetStatusText (_("Nothing to save for now !"));
466 /// Toolbar About button
468 AlcFrame::OnBarAbout (wxCommandEvent
& WXUNUSED(event
))
471 ("aLinkCreator, the aMule eD2k link creator\n\n(c) 2004 ThePolish <thepolish@vipmail.ru>\n\nPixmaps from http://www.everaldo.com and http://www.icomania.com\nand http://jimmac.musichall.cz/ikony.php3\n\nDistributed under GPL"),
472 _("About aLinkCreator"), wxOK
| wxCENTRE
| wxICON_INFORMATION
);
476 void AlcFrame::OnCloseButton (wxCommandEvent
& WXUNUSED(event
))
481 /// Hook into MD4/ED2K routine
482 bool AlcFrame::Hook(int percent
)
484 // Update progress bar
485 bool goAhead
= ::wxGetApp().GetMainFrame()->m_progressBar
->Update(percent
);
488 // Destroying progressbar: no merci for croissants !
489 ::wxGetApp().GetMainFrame()->m_progressBar
->Destroy();
491 delete ::wxGetApp().GetMainFrame()->m_progressBar
;
492 ::wxGetApp().GetMainFrame()->m_progressBar
= NULL
;
498 /// Compute Hashes on Start Button
499 void AlcFrame::OnStartButton (wxCommandEvent
& WXUNUSED(event
))
501 wxString filename
= m_inputFileTextCtrl
->GetValue();
503 if (!filename
.empty ())
508 // wxFileName needed for base name
509 wxFileName
fileToHash(filename
);
512 m_e2kHashTextCtrl
->SetValue(_("Hashing..."));
513 m_ed2kTextCtrl
->SetValue(_("Hashing..."));
516 // Create MD4 progress bar dialog
517 m_progressBar
=new wxProgressDialog (_("aLinkCreator is working for you"), _("Computing MD4 Hash..."),
518 100, this, wxPD_AUTO_HIDE
| wxPD_CAN_ABORT
| wxPD_REMAINING_TIME
);
519 m_md4HashTextCtrl
->SetValue(_("Hashing..."));
523 m_md4HashTextCtrl
->SetValue(md4
.calcMd4FromFile(filename
,Hook
));
525 // Deleting MD4 progress bar dialog
526 delete m_progressBar
;
531 // Create ED2K progress bar dialog
532 m_progressBar
=new wxProgressDialog (_("aLinkCreator is working for you"), _("Computing eD2k Hashes..."),
533 100, this, wxPD_AUTO_HIDE
| wxPD_CAN_ABORT
| wxPD_REMAINING_TIME
);
538 // Test the return value to see if was aborted.
539 if (hash
.SetED2KHashFromFile(filename
, Hook
))
542 wxArrayString
ed2kHash (hash
.GetED2KHash());
545 wxArrayString arrayOfUrls
;
547 for (size_t i
= 0; i
< m_inputUrlListBox
->GetCount(); ++i
)
549 url
=m_inputUrlListBox
->GetString(i
);
550 if (url
.Right(1) == wxT("/"))
552 url
+= fileToHash
.GetFullName();
554 arrayOfUrls
.Add(wxURI(url
).BuildURI());
556 arrayOfUrls
.Shrink(); // Reduce memory usage
559 m_e2kHashTextCtrl
->SetValue(ed2kHash
.Last());
562 m_ed2kTextCtrl
->SetValue(hash
.GetED2KLink(m_parthashesCheck
->IsChecked(), &arrayOfUrls
));
567 m_e2kHashTextCtrl
->SetValue(_("Cancelled !"));
568 m_ed2kTextCtrl
->SetValue(_("Cancelled !"));
571 // Deleting progress bar dialog
572 delete m_progressBar
;
576 SetStatusText (wxString::Format(_("Done in %.2f s"),
577 chrono
.Time()*.001));
582 SetStatusText (_("Please, enter a non empty file name"));
587 /// Add an URL to the URL list box
589 AlcFrame::OnAddUrlButton (wxCommandEvent
& WXUNUSED(event
))
591 wxString
url(m_inputAddTextCtrl
->GetValue());
595 // Check if the URL already exist in list
596 bool UrlNotExists
= true;
597 for (size_t i
= 0; i
< m_inputUrlListBox
->GetCount(); ++i
)
599 if (url
== m_inputUrlListBox
->GetString(i
))
606 // Add only a not already existant URL
609 m_inputUrlListBox
->Append(wxURI(url
).BuildURI());
610 m_inputAddTextCtrl
->SetValue(wxEmptyString
);
614 wxLogError(_("You have already added this URL !"));
619 SetStatusText (_("Please, enter a non empty URL"));
623 /// Remove the selected URL from the URL list box
625 AlcFrame::OnRemoveUrlButton (wxCommandEvent
& WXUNUSED(event
))
627 m_inputUrlListBox
->Delete(m_inputUrlListBox
->GetSelection());
630 /// Clear the URL list box
632 AlcFrame::OnClearUrlButton (wxCommandEvent
& WXUNUSED(event
))
634 m_inputUrlListBox
->Clear();
636 // File_checked_for_headers