/*************************************************************************** sq_libraryhandler.cpp - description ------------------- begin : Mar 5 2004 copyright : (C) 2004 by Baryshev Dmitry email : ksquirrel.iv@gmail.com ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include "sq_libraryhandler.h" #include "sq_config.h" #include #include #include #if !defined(QT_STRINGIFY) # define QT_STRINGIFY2(x) #x # define QT_STRINGIFY(x) QT_STRINGIFY2(x) #endif static const int buffer_size = 10; SQ_LibraryHandler * SQ_LibraryHandler::m_instance = 0; // SQ_LibraryHandler SQ_LibraryHandler::SQ_LibraryHandler(TQObject *parent) : TQObject(parent), TQValueVector() { m_instance = this; kdDebug() << "+SQ_LibraryHandler" << endl; tdeconf = new TDEConfig("ksquirrel-codec-settings"); load(); } SQ_LibraryHandler::~SQ_LibraryHandler() { clear(); delete tdeconf; kdDebug() << "-SQ_LibraryHandler" << endl; } /* * Find appropriate SQ_LIBRARY by filename. If * not found, return NULL. */ SQ_LIBRARY* SQ_LibraryHandler::libraryForFile(const KURL &url) { KMimeType::Ptr mime = KMimeType::findByURL(url); iterator itEnd = end(); SQ_LIBRARY *l = 0; // go through array and compare names for(iterator it = begin();it != itEnd;++it) { if((*it).mime_multi) { if((*it).mimetype.find(mime->name()) != -1) { l = &(*it); break; } } else if((*it).mimetype == mime->name()) { l = &(*it); break; } } #if 0 if(l) kdDebug() << KStringHandler::lsqueeze(url.prettyURL()) << "\" => " << l->quickinfo << endl; #endif return l; } SQ_LIBRARY* SQ_LibraryHandler::libraryForFile(const TQString &path) { KURL u; u.setPath(path); return libraryForFile(u); } /* * Get all filters as one string. */ TQString SQ_LibraryHandler::allFiltersString() const { TQString ret; const_iterator itEnd = end(); // construct string for(const_iterator it = begin();it != itEnd;++it) { if(!(*it).filter.isEmpty()) ret = ret + (*it).filter + ' '; } return ret; } TQString SQ_LibraryHandler::allFiltersFileDialogString(bool r, bool allfiles) const { TQString ret; const_iterator itEnd = end(); // construct string for(const_iterator it = begin();it != itEnd;++it) { if(!r) if((*it).writestatic) ret = ret + (*it).filter + '|' + (*it).quickinfo + '\n'; else; else if((*it).readable) ret = ret + (*it).filter + '|' + (*it).quickinfo + '\n'; } return allfiles ? (ret + "*.*|" + i18n("All files")) : ret.left(ret.length() - 1); } /* * Fill 'filters' with all found filters, and * 'quick' with appropriate information. */ void SQ_LibraryHandler::allFilters(TQStringList &filters, TQStringList &quick) const { // clear rubbish filters.clear(); quick.clear(); // no found libraries ? if(empty()) return; const_iterator itEnd = end(); // go through array and fill TQStringLists for(const_iterator it = begin();it != itEnd;++it) if(!(*it).filter.isEmpty()) { filters.append((*it).filter); quick.append((*it).quickinfo); } } void SQ_LibraryHandler::allWritableFilters(TQStringList &filters, TQStringList &quick) const { // clear rubbish filters.clear(); quick.clear(); // no libraries ? if(empty()) return; const_iterator itEnd = end(); // go through array and fill TQStringLists for(const_iterator it = begin();it != itEnd;++it) if((*it).writestatic && !(*it).filter.isEmpty()) { filters.append((*it).filter); quick.append((*it).quickinfo); } } /* * Remove and unload all libraries. */ void SQ_LibraryHandler::clear() { kdDebug() << "SQ_LibraryHandler::clear()" << endl; iterator itEnd = end(); // unload libraries on clear() for(iterator it = begin();it != itEnd;++it) { writeSettings(&(*it)); // delete temp file if((*it).needtempfile) { delete (*it).tmp_il; delete (*it).tmp; } (*it).codec_destroy((*it).codec_il); (*it).codec_destroy((*it).codec); delete (*it).lib; (*it).lib = 0; } TQValueVector::clear(); } /* * Add new libraries. */ void SQ_LibraryHandler::add(TQStringList &foundLibraries) { codec_options o; TQStringList::iterator itEnd = foundLibraries.end(); for(TQStringList::iterator it = foundLibraries.begin();it != itEnd;++it) { TQFileInfo ff(*it); SQ_LIBRARY libtmp; // create TQLibrary object libtmp.lib = new TQLibrary(*it); libtmp.libpath = *it; libtmp.lib->load(); // resolve create() and destroy() functions libtmp.codec_create = (fmt_codec_base*(*)())(libtmp.lib)->resolve(TQString::fromLatin1("codec_create")); libtmp.codec_destroy = (void (*)(fmt_codec_base*))(libtmp.lib)->resolve(TQString::fromLatin1("codec_destroy")); // couldn't resolve - corrupted library ? if(!libtmp.codec_create || !libtmp.codec_destroy) { libtmp.lib->unload(); delete libtmp.lib; } else { // create codec ! fmt_codec_base *codeK = libtmp.codec_create(); // read options codeK->options(&o); TQString q = o.name; // Yet unknown library ? if(!alreadyInMap(q)) { libtmp.mime = TQPixmap(reinterpret_cast(o.pixmap)); libtmp.mimetype = o.mimetype; libtmp.mime_multi = libtmp.mimetype.find(';') != -1; libtmp.quickinfo = q; libtmp.filter = o.filter; libtmp.version = o.version; libtmp.regexp_str = o.mime; libtmp.config = o.config; libtmp.regexp.setPattern(libtmp.regexp_str); libtmp.regexp.setCaseSensitive(true); libtmp.writestatic = o.writestatic; libtmp.writeanimated = o.writeanimated; libtmp.readable = o.readable; libtmp.canbemultiple = o.canbemultiple; libtmp.needtempfile = o.needtempfile; libtmp.tmp = 0; libtmp.codec_il = libtmp.codec_create(); if(libtmp.needtempfile) { libtmp.tmp = new KTempFile; libtmp.tmp->setAutoDelete(true); libtmp.tmp->close(); codeK->settempfile(libtmp.tmp->name().ascii()); libtmp.tmp_il = new KTempFile; libtmp.tmp_il->setAutoDelete(true); libtmp.tmp_il->close(); libtmp.codec_il->settempfile(libtmp.tmp_il->name().ascii()); } if(libtmp.writestatic) codeK->getwriteoptions(&libtmp.opt); libtmp.codec = codeK; readSettings(&libtmp); append(libtmp); } else // already known library { // destroy codec libtmp.codec_destroy(codeK); // unload library libtmp.lib->unload(); delete libtmp.lib; } } } // print some information dump(); } /* * Is library named 'quick' already been handled ? */ bool SQ_LibraryHandler::alreadyInMap(const TQString &quick) const { const_iterator itEnd = end(); // go through array and find 'quick' for(const_iterator it = begin();it != itEnd;++it) if((*it).quickinfo == quick) return true; return false; } /* * Print some information on found libraries. */ void SQ_LibraryHandler::dump() const { std::cerr << "SQ_LibraryHandler: memory dump (total " << count() << ")" << endl; const_iterator itEnd = end(); std::cerr.setf(ios::left); for(const_iterator it = begin();it != itEnd;++it) { std::cerr << std::setw(30) << KStringHandler::csqueeze(TQFileInfo((*it).libpath).fileName(), 30) << std::setw(0) << " [" << KStringHandler::rsqueeze((*it).quickinfo, 45) << "]" << endl; } } /* * Does any of found libraries handle given extension ? */ bool SQ_LibraryHandler::knownExtension(const TQString &ext) { iterator itEnd = end(); // go through array and compare extensions for(iterator it = begin();it != itEnd;++it) { if((*it).filter.contains(ext, false)) return true; } return false; } /* * Find appropriate SQ_LIBRARY by its name. If * not found, return NULL. * * Name is a string, returned by fmt_quickinfo() */ SQ_LIBRARY* SQ_LibraryHandler::libraryByName(const TQString &name) { SQ_LIBRARY *l; iterator itEnd = end(); // go through array and compare names for(iterator it = begin();it != itEnd;++it) { l = &(*it); if(l->quickinfo == name) return l; } return 0; } void SQ_LibraryHandler::writeSettings(SQ_LIBRARY *lib) { // no config - no settings if(lib->config.isEmpty()) return; tdeconf->setGroup(lib->quickinfo); fmt_settings::iterator itEnd = lib->settings.end(); TQString k; for(fmt_settings::iterator it = lib->settings.begin();it != itEnd;++it) { k = (*it).first; if((*it).second.type == settings_value::v_bool) // boolean { k.prepend("b"); tdeconf->writeEntry(k, (*it).second.bVal); } else if((*it).second.type == settings_value::v_int) // integer { k.prepend("i"); tdeconf->writeEntry(k, (*it).second.iVal); } else if((*it).second.type == settings_value::v_double) // double { k.prepend("d"); tdeconf->writeEntry(k, (*it).second.dVal); } else // string { k.prepend("s"); tdeconf->writeEntry(k, (*it).second.sVal); } } } void SQ_LibraryHandler::readSettings(SQ_LIBRARY *lib) { // no config - no settings if(lib->config.isEmpty()) return; TQMap map = tdeconf->entryMap(lib->quickinfo); if(!map.size()) { lib->codec->fill_default_settings(); lib->settings = lib->codec->settings(); return; } TQMap::iterator mapEnd = map.end(); fmt_settings &sett = lib->settings; TQString d, k; settings_value val; for(TQMap::iterator mapIt = map.begin();mapIt != mapEnd;++mapIt) { k = mapIt.key(); d = mapIt.data(); if(k.startsWith(TQChar('i'))) { val.type = settings_value::v_int; val.iVal = d.toInt(); } else if(k.startsWith(TQChar('d'))) { val.type = settings_value::v_double; val.dVal = d.toDouble(); } else if(k.startsWith(TQChar('b'))) { val.type = settings_value::v_bool; val.bVal = (d == "true"); } else // all other values are treated as strings { val.type = settings_value::v_string; val.sVal = d.ascii(); } k = k.right(k.length() - 1); sett[k.ascii()] = val; } lib->codec->set_settings(sett); } void SQ_LibraryHandler::reload() { clear(); load(); } void SQ_LibraryHandler::load() { TQStringList libs; TQDir dir(QT_STRINGIFY(SQ_KLIBS), TQString(), TQDir::Unsorted, TQDir::Files); const TQFileInfoList *list = dir.entryInfoList(); if(list) { TQFileInfoListIterator it(*list); TQFileInfo *fi; while((fi = it.current()) != 0) { libs.append(fi->absFilePath()); ++it; } } // just show dump, if no libs were found add(libs); } SQ_LibraryHandler::Support SQ_LibraryHandler::maybeSupported(const KURL &u, const TQString &mime) const { const_iterator itEnd = constEnd(); SQ_Config::instance()->setGroup("Main"); bool treat = SQ_Config::instance()->readBoolEntry("treat", true); // we can determine mimetype by hand or use "mime" TQString mimeDet = mime.isEmpty() ? KMimeType::findByURL(u)->name() : mime; // mimetype by magic is not determined automatically // for non-local urls - we may support this file type or may not // (we don't know exactly at this moment) if(!u.isLocalFile() && mimeDet == KMimeType::defaultMimeType()) return (treat ? SQ_LibraryHandler::No : SQ_LibraryHandler::Maybe); // go through array and compare mimetype names for(const_iterator it = constBegin();it != itEnd;++it) { if((*it).mime_multi) { if((*it).mimetype.find(mimeDet, 0, false) != -1) return SQ_LibraryHandler::Yes; } else if((*it).mimetype == mimeDet) // don't waste CPU time with find() return SQ_LibraryHandler::Yes; } // we don't know about given mimetype return SQ_LibraryHandler::No; } void SQ_LibraryHandler::sync() { iterator itEnd = end(); // unload libraries on clear() for(iterator it = begin();it != itEnd;++it) writeSettings(&(*it)); tdeconf->sync(); }