// Copyright (c) 2005, Rodrigo Braz Monteiro // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // * Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // * Neither the name of the Aegisub Group nor the names of its contributors // may be used to endorse or promote products derived from this software // without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. // // ----------------------------------------------------------------------------- // // AEGISUB // // Website: http://aegisub.cellosoft.com // Contact: mailto:zeratul@cellosoft.com // //////////// // Includes #include #include #ifdef __WIN32__ #include #endif #include "ass_override.h" #include "ass_file.h" #include "ass_dialogue.h" #include "ass_style.h" #include "fonts_collector.h" #include "utils.h" #include "options.h" /////////////// // Constructor DialogFontsCollector::DialogFontsCollector(wxWindow *parent) : wxDialog(parent,-1,_("Fonts Collector"),wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE) { // Destination box DestBox = new wxTextCtrl(this,-1,Options.AsText(_T("Fonts Collector Destination")),wxDefaultPosition,wxSize(250,20),0); BrowseButton = new wxButton(this,BROWSE_BUTTON,_("&Browse...")); wxSizer *DestBottomSizer = new wxBoxSizer(wxHORIZONTAL); wxStaticText *DestLabel = new wxStaticText(this,-1,_("Choose the folder where the fonts will be collected to.\nIt will be created if it doesn't exist.")); DestBottomSizer->Add(DestBox,1,wxEXPAND | wxRIGHT,5); DestBottomSizer->Add(BrowseButton,0,0,0); wxSizer *DestSizer = new wxStaticBoxSizer(wxVERTICAL,this,_("Destination")); DestSizer->Add(DestLabel,0,wxEXPAND | wxBOTTOM,5); DestSizer->Add(DestBottomSizer,0,wxEXPAND,0); // Log box LogBox = new wxTextCtrl(this,-1,_T(""),wxDefaultPosition,wxSize(300,210),wxTE_MULTILINE | wxTE_READONLY | wxTE_RICH); wxSizer *LogSizer = new wxStaticBoxSizer(wxVERTICAL,this,_("Log")); LogSizer->Add(LogBox,1,wxEXPAND,0); // Buttons sizer StartButton = new wxButton(this,START_BUTTON,_("&Start!")); StartButton->SetDefault(); CloseButton = new wxButton(this,wxID_CLOSE); wxSizer *ButtonSizer = new wxBoxSizer(wxHORIZONTAL); ButtonSizer->AddStretchSpacer(1); ButtonSizer->Add(StartButton,0,wxRIGHT,5); ButtonSizer->Add(CloseButton); // Main sizer wxSizer *MainSizer = new wxBoxSizer(wxVERTICAL); MainSizer->Add(DestSizer,0,wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM,5); MainSizer->Add(LogSizer,0,wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM,5); MainSizer->Add(ButtonSizer,0,wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM,5); // Set sizer SetSizer(MainSizer); MainSizer->SetSizeHints(this); } ////////////// // Destructor DialogFontsCollector::~DialogFontsCollector() { } //////////////////////////////// // Get fonts from ass overrides void FontsCollectorThread::GetFonts (wxString tagName,int par_n,AssOverrideParameter *param,void *usr) { if (tagName == _T("\\fn")) { instance->AddFont(param->AsText(),false); } } /////////////// // Adds a font void FontsCollectorThread::AddFont(wxString fontname,bool isStyle) { if (fonts.Index(fontname) == wxNOT_FOUND) { fonts.Add(fontname); // Dialogue if (!isStyle) { collector->LogBox->AppendText(wxString(_T("\"")) + fontname + _("\" found on dialogue line ") + wxString::Format(_T("%i"),curLine) + _T(".\n")); } } } /////////////////// // Static instance FontsCollectorThread *FontsCollectorThread::instance; /////////////// // Event table BEGIN_EVENT_TABLE(DialogFontsCollector, wxDialog) EVT_BUTTON(START_BUTTON,DialogFontsCollector::OnStart) EVT_BUTTON(BROWSE_BUTTON,DialogFontsCollector::OnBrowse) EVT_BUTTON(wxID_CLOSE,DialogFontsCollector::OnClose) END_EVENT_TABLE() //////////////////// // Start processing void DialogFontsCollector::OnStart(wxCommandEvent &event) { // Check if it's OK to do it wxString foldername = DestBox->GetValue(); wxFileName folder(foldername); // Make folder if it doesn't exist if (!folder.DirExists()) folder.Mkdir(0777,wxPATH_MKDIR_FULL); // Start if (folder.DirExists()) { // Start thread wxThread *worker = new FontsCollectorThread(AssFile::top,foldername,this); worker->Create(); worker->Run(); // Set options Options.SetText(_T("Fonts Collector Destination"),foldername); Options.Save(); // Set buttons StartButton->Enable(false); BrowseButton->Enable(false); DestBox->Enable(false); CloseButton->Enable(false); if (!worker->IsDetached()) worker->Wait(); } // Folder not available else { wxMessageBox(_("Invalid folder"),_("Error"),wxICON_EXCLAMATION | wxOK); } } //////////////// // Close dialog void DialogFontsCollector::OnClose(wxCommandEvent &event) { EndModal(0); } /////////////////// // Browse location void DialogFontsCollector::OnBrowse(wxCommandEvent &event) { wxString dest = wxDirSelector(_("Select folder to save fonts on"),DestBox->GetValue(),0); if (!dest.empty()) { DestBox->SetValue(dest); } } ////////////////////// // Get font filenames wxArrayString FontsCollectorThread::GetFontFiles (wxString face) { wxArrayString files; int n = 0; for (FontMap::iterator entry = regFonts.begin();entry != regFonts.end();entry++) { wxString curData = (*entry).first; if (face == curData.Left(face.Length())) { files.Add((*entry).second); n++; } } if (n==0) throw _T("Font not found"); return files; } /////////////////////// // Collect font files void FontsCollectorThread::CollectFontData () { #ifdef __WIN32__ // Prepare key wxRegKey *reg = new wxRegKey(_T("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts")); // Try win9x if (!reg->Exists()) { delete reg; reg = new wxRegKey(_T("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Fonts")); if (!reg->Exists()) { delete reg; throw _("Could not locate fonts directory"); } } wxString curName; wxString curVal; long index; int n = 0; // Iterate through bool ok = reg->GetFirstValue(curName,index); while (ok) { reg->QueryValue(curName,curVal); //AddFontData(curName,curVal); regFonts[curName] = curVal; ok = reg->GetNextValue(curName,index); n++; } // Clean up delete reg; #endif } //////////////////// // Collector thread FontsCollectorThread::FontsCollectorThread(AssFile *_subs,wxString _destination,DialogFontsCollector *_collector) : wxThread(wxTHREAD_DETACHED) { subs = _subs; destination = _destination; collector = _collector; instance = this; } //////////////// // Thread entry wxThread::ExitCode FontsCollectorThread::Entry() { // Collect Collect(); collector->CloseButton->Enable(true); // Return if (IsDetached()) Delete(); return 0; } /////////// // Collect void FontsCollectorThread::Collect() { // Make sure there is a separator at the end destination += _T("\\"); // Reset log box wxTextCtrl *LogBox = collector->LogBox; wxMutexGuiEnter(); LogBox->SetValue(_T("")); LogBox->SetDefaultStyle(wxTextAttr(wxColour(0,0,180))); LogBox->AppendText(_("Searching for fonts in file...\n")); LogBox->SetDefaultStyle(wxTextAttr(wxColour(0,0,0))); wxSafeYield(); wxMutexGuiLeave(); // Scans file AssStyle *curStyle; AssDialogue *curDiag; curLine = 0; for (std::list::iterator cur=subs->Line.begin();cur!=subs->Line.end();cur++) { // Collect from style curStyle = AssEntry::GetAsStyle(*cur); if (curStyle) { AddFont(curStyle->font,true); wxMutexGuiEnter(); LogBox->AppendText(wxString(_T("\"")) + curStyle->font + _("\" found on style \"") + curStyle->name + _T("\".\n")); wxSafeYield(); wxMutexGuiLeave(); } // Collect from dialogue else { curDiag = AssEntry::GetAsDialogue(*cur); if (curDiag) { curLine++; curDiag->ProcessParameters(GetFonts); } } } #ifdef __WIN32__ // Collect font data wxMutexGuiEnter(); LogBox->SetDefaultStyle(wxTextAttr(wxColour(0,0,180))); LogBox->AppendText(_("\nReading fonts from registry...\n")); LogBox->SetDefaultStyle(wxTextAttr(wxColour(0,0,0))); wxSafeYield(); wxMutexGuiLeave(); CollectFontData(); // Get fonts folder wxString source; TCHAR szPath[MAX_PATH]; if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_FONTS,NULL,0,szPath))) { source = wxString(szPath); } else source = wxGetOSDirectory() + _T("\\fonts"); source += _T("\\"); // Get font file names wxArrayString work; wxArrayString copied; for (size_t i=0;iSetDefaultStyle(wxTextAttr(wxColour(255,128,0))); LogBox->AppendText(wxString(_T("\"")) + work[j] + _("\" already exists on destination.\n")); wxSafeYield(); wxMutexGuiLeave(); } // Copy else { wxString srcFile = source + work[j]; bool success = Copy(srcFile,dstFile); wxMutexGuiEnter(); if (success) { LogBox->SetDefaultStyle(wxTextAttr(wxColour(0,180,0))); LogBox->AppendText(wxString(_T("\"")) + work[j] + _("\" copied.\n")); } else { LogBox->SetDefaultStyle(wxTextAttr(wxColour(220,0,0))); LogBox->AppendText(wxString(_("Failed copying \"")) + work[j] + _T("\".\n")); } wxSafeYield(); wxMutexGuiLeave(); } } } } catch (...) { wxMutexGuiEnter(); LogBox->SetDefaultStyle(wxTextAttr(wxColour(220,0,0))); LogBox->AppendText(wxString(_("Could not find font ")) + fonts[i] + _T("\n")); wxMutexGuiLeave(); } } #endif }