#include "SubtitleSystem.h" #include #include #include #include "SubtitleSubRip.h" #include "SubtitleMicroDVD.h" #include "SubtitleTTXT.h" #include "SubtitleMPL2.h" #include "SubtitleASS.h" #include "SubtitleSSA.h" #include "SubtitleSubViewer2.h" #include "SubtitleMPsub.h" #include "SubtitleEncorePAL.h" #include "SubtitleEncoreNTSC.h" #include "utility.h" /* * */ class IFactory { public: virtual ~IFactory() { } virtual SubtitleFormat* create(Document *doc) = 0; virtual Glib::ustring get_name() = 0; virtual Glib::ustring get_extension() = 0; virtual bool check(const std::string &line) = 0; }; /* * */ template class Factory : public IFactory { public: Factory() { } virtual SubtitleFormat* create(Document *doc) { return new Sub(doc); } virtual Glib::ustring get_name() { return Sub::get_name(); } virtual bool check(const std::string &line) { return Sub::check(line); } virtual Glib::ustring get_extension() { return Sub::get_extension(); } }; /* * */ #define REGISTER_SUBTITLE(class) \ { \ se_debug_message((SE_DEBUG_APP | SE_DEBUG_LOADER | SE_DEBUG_SAVER), "Register subtitle class <%s>", #class); \ static Factory factory; m_static_subtitle_formats.push_back(&factory); } /* * */ static std::list m_static_subtitle_formats; /* * */ SubtitleSystem& SubtitleSystem::getInstance() { if(m_static_subtitle_formats.empty()) { se_debug_message( (SE_DEBUG_APP|SE_DEBUG_LOADER|SE_DEBUG_SAVER), "Init Register Subtitles"); REGISTER_SUBTITLE(SubtitleASS); REGISTER_SUBTITLE(SubtitleSSA); REGISTER_SUBTITLE(SubtitleSubRip); REGISTER_SUBTITLE(SubtitleMicroDVD); REGISTER_SUBTITLE(SubtitleMPL2); REGISTER_SUBTITLE(SubtitleSubViewer2); REGISTER_SUBTITLE(SubtitleMPsub); REGISTER_SUBTITLE(SubtitleEncorePAL); REGISTER_SUBTITLE(SubtitleEncoreNTSC); #ifdef ENABLE_TTXT REGISTER_SUBTITLE(SubtitleTTXT); #endif } static SubtitleSystem system; return system; } /* * retourne la list des formats supporter */ std::list SubtitleSystem::get_formats() { static std::list list; if(list.empty()) { for(std::list::const_iterator it=m_static_subtitle_formats.begin(); it!=m_static_subtitle_formats.end(); ++it) { list.push_back((*it)->get_name()); } } return list; } /* * determine quel est le format du sous-titre */ Glib::ustring SubtitleSystem::find_subtitle_format(const Glib::ustring &filename) { se_debug_message( (SE_DEBUG_APP|SE_DEBUG_LOADER|SE_DEBUG_SAVER), "Open file <%s>", filename.c_str()); std::ifstream file(filename.c_str()); if(!file) { se_debug_message( (SE_DEBUG_APP|SE_DEBUG_LOADER|SE_DEBUG_SAVER), "Open file failed <%s>.", filename.c_str()); return ""; } std::string line; unsigned int count = 0; while(!file.eof() && std::getline(file, line)) { Glib::ustring fmt = find_format(line.c_str()); if(!fmt.empty()) { file.close(); se_debug_message( (SE_DEBUG_APP|SE_DEBUG_LOADER|SE_DEBUG_SAVER), "Format detected <%s>", fmt.c_str()); return fmt; } if(++count > 100) break; } file.close(); se_debug_message((SE_DEBUG_APP|SE_DEBUG_LOADER|SE_DEBUG_SAVER), "Can't determinate this format!"); throw SubtitleException("SubtitleSystem", _("I can't find what is this format or it's not supported.")); } /* * crée la class du format */ SubtitleFormat* SubtitleSystem::create_subtitle_format(const Glib::ustring &name, Document *doc) { g_return_val_if_fail(doc, NULL); for(std::list::const_iterator it=m_static_subtitle_formats.begin(); it!=m_static_subtitle_formats.end(); ++it) { if((*it)->get_name() == name) { se_debug_message( (SE_DEBUG_APP|SE_DEBUG_LOADER|SE_DEBUG_SAVER), "create subtitle format <%s>", name.c_str()); return (*it)->create(doc); } } se_debug_message( (SE_DEBUG_APP|SE_DEBUG_LOADER|SE_DEBUG_SAVER), "create subtitle format failed <%s>", name.c_str()); return NULL; } /* * cherche le format de la line str */ Glib::ustring SubtitleSystem::find_format(const char *str) { for(std::list::const_iterator it=m_static_subtitle_formats.begin(); it!=m_static_subtitle_formats.end(); ++it) { if((*it)->check(str)) { se_debug_message((SE_DEBUG_APP|SE_DEBUG_LOADER|SE_DEBUG_SAVER), "find format <%s> = %s", str, (*it)->get_name().c_str()); return (*it)->get_name(); } } se_debug_message((SE_DEBUG_APP|SE_DEBUG_LOADER|SE_DEBUG_SAVER), "find format <%s> failed.", str); return ""; } /* * retourne l'extension utiliser par le format * ex: "ass", "ssa", "srt", ... */ Glib::ustring SubtitleSystem::get_extension(const Glib::ustring &format) { for(std::list::const_iterator it=m_static_subtitle_formats.begin(); it!=m_static_subtitle_formats.end(); ++it) { if((*it)->get_name() == format) return (*it)->get_extension(); } return ""; }