allow setting attrs on mimeview defs, factorize some code with mhExecFactory

This commit is contained in:
dockes 2009-11-21 13:36:56 +00:00
parent 360b2271da
commit e57408bf7c
2 changed files with 47 additions and 55 deletions

View File

@ -65,7 +65,7 @@ static Dijon::Filter *mhFactory(const string &mime)
/** /**
* Create a filter that executes an external program or script * Create a filter that executes an external program or script
* A filter def can look like: * A filter def can look like:
* exec someprog -v -t " h i j";charset= xx; mimetype=yy * someprog -v -t " h i j";charset= xx; mimetype=yy
* A semi-colon list of attr=value pairs may come after the exec spec. * A semi-colon list of attr=value pairs may come after the exec spec.
* This list is treated by replacing semi-colons with newlines and building * This list is treated by replacing semi-colons with newlines and building
* a confsimple. This is done quite brutally and we don't support having * a confsimple. This is done quite brutally and we don't support having
@ -74,20 +74,18 @@ static Dijon::Filter *mhFactory(const string &mime)
MimeHandlerExec *mhExecFactory(RclConfig *cfg, const string& mtype, string& hs, MimeHandlerExec *mhExecFactory(RclConfig *cfg, const string& mtype, string& hs,
bool multiple) bool multiple)
{ {
string::size_type semicol0 = hs.find_first_of(";"); ConfSimple attrs;
string cmdstr, attrstr; string cmdstr;
if (semicol0 != string::npos) { if (!cfg->valueSplitAttributes(hs, cmdstr, attrs)) {
cmdstr = hs.substr(0, semicol0); LOGERR(("mhExecFactory: bad config line for [%s]: [%s]\n",
if (semicol0 < hs.size() - 1) mtype.c_str(), hs.c_str()));
attrstr = hs.substr(semicol0+1); return 0;
} else {
cmdstr = hs;
} }
// Split command name and args, and build exec object // Split command name and args, and build exec object
list<string> cmdtoks; list<string> cmdtoks;
stringToStrings(cmdstr, cmdtoks); stringToStrings(cmdstr, cmdtoks);
if (cmdtoks.size() < 2) { if (cmdtoks.empty()) {
LOGERR(("mhExecFactory: bad config line for [%s]: [%s]\n", LOGERR(("mhExecFactory: bad config line for [%s]: [%s]\n",
mtype.c_str(), hs.c_str())); mtype.c_str(), hs.c_str()));
return 0; return 0;
@ -95,35 +93,26 @@ MimeHandlerExec *mhExecFactory(RclConfig *cfg, const string& mtype, string& hs,
MimeHandlerExec *h = multiple ? MimeHandlerExec *h = multiple ?
new MimeHandlerExecMultiple(mtype.c_str()) : new MimeHandlerExecMultiple(mtype.c_str()) :
new MimeHandlerExec(mtype.c_str()); new MimeHandlerExec(mtype.c_str());
// cmdtoks size is at least 2, this has been checked just before
list<string>::iterator it = cmdtoks.begin(); list<string>::iterator it = cmdtoks.begin();
it++;
h->params.push_back(cfg->findFilter(*it++)); h->params.push_back(cfg->findFilter(*it++));
h->params.insert(h->params.end(), it, cmdtoks.end()); h->params.insert(h->params.end(), it, cmdtoks.end());
// Handle additional attributes. We substitute the semi-colons // Handle additional attributes. We substitute the semi-colons
// with newlines and use a ConfSimple // with newlines and use a ConfSimple
if (!attrstr.empty()) { string value;
for (string::size_type i = 0; i < attrstr.size(); i++) if (attrs.get("charset", value))
if (attrstr[i] == ';') h->cfgCharset = stringtolower((const string&)value);
attrstr[i] = '\n'; if (attrs.get("mimetype", value))
ConfSimple attrs(attrstr); h->cfgMtype = stringtolower((const string&)value);
string value;
if (attrs.get("charset", value))
h->cfgCharset = stringtolower((const string&)value);
if (attrs.get("mimetype", value))
h->cfgMtype = stringtolower((const string&)value);
}
#if 0 #if 1
string sparams; string scmd;
for (it = h->params.begin(); it != h->params.end(); it++) { for (it = h->params.begin(); it != h->params.end(); it++) {
sparams += string("[") + *it + "] "; scmd += string("[") + *it + "] ";
} }
LOGDEB(("mhExecFactory:mt [%s] cfgmt [%s] cfgcs [%s] params: [%s]\n", LOGDEB(("mhExecFactory:mt [%s] cfgmt [%s] cfgcs [%s] cmd: [%s]\n",
mtype.c_str(), h->cfgMtype.c_str(), h->cfgCharset.c_str(), mtype.c_str(), h->cfgMtype.c_str(), h->cfgCharset.c_str(),
sparams.c_str())); scmd.c_str()));
#endif #endif
return h; return h;
@ -160,34 +149,29 @@ Dijon::Filter *getMimeHandler(const string &mtype, RclConfig *cfg,
hs = cfg->getMimeHandlerDef(mtype, filtertypes); hs = cfg->getMimeHandlerDef(mtype, filtertypes);
if (!hs.empty()) { if (!hs.empty()) {
// Break definition into type and name // Break definition into type and name/command string
list<string> toks; string::size_type b1 = hs.find_first_of(" \t");
stringToStrings(hs, toks); string handlertype = hs.substr(0, b1);
if (toks.empty()) { if (!stringlowercmp("internal", handlertype)) {
LOGERR(("getMimeHandler: bad mimeconf line for %s\n",
mtype.c_str()));
return 0;
}
// Retrieve handler function according to type
list<string>::iterator it = toks.begin();
if (!stringlowercmp("internal", *it)) {
return mhFactory(mtype); return mhFactory(mtype);
} else if (!stringlowercmp("dll", *it)) { } else if (!stringlowercmp("dll", handlertype)) {
} else if (!stringlowercmp("exec", *it)) { } else {
if (toks.size() < 2) { string cmdstr = hs.substr(b1);
trimstring(cmdstr);
if (cmdstr.empty()) {
LOGERR(("getMimeHandler: bad line for %s: %s\n", LOGERR(("getMimeHandler: bad line for %s: %s\n",
mtype.c_str(), hs.c_str())); mtype.c_str(), hs.c_str()));
return 0; return 0;
} }
return mhExecFactory(cfg, mtype, hs, false); if (!stringlowercmp("exec", handlertype)) {
} else if (!stringlowercmp("execm", *it)) { return mhExecFactory(cfg, mtype, cmdstr, false);
if (toks.size() < 2) { } else if (!stringlowercmp("execm", handlertype)) {
return mhExecFactory(cfg, mtype, cmdstr, true);
} else {
LOGERR(("getMimeHandler: bad line for %s: %s\n", LOGERR(("getMimeHandler: bad line for %s: %s\n",
mtype.c_str(), hs.c_str())); mtype.c_str(), hs.c_str()));
return 0; return 0;
} }
return mhExecFactory(cfg, mtype, hs, true);
} }
} }

View File

@ -892,24 +892,32 @@ static string fileurltolocalpath(string url)
void RclMain::startNativeViewer(Rcl::Doc doc) void RclMain::startNativeViewer(Rcl::Doc doc)
{ {
// Look for appropriate viewer // Look for appropriate viewer
string cmd; string cmdplusattr;
if (prefs.useDesktopOpen) { if (prefs.useDesktopOpen) {
cmd = rclconfig->getMimeViewerDef("application/x-all", ""); cmdplusattr = rclconfig->getMimeViewerDef("application/x-all", "");
} else { } else {
string apptag; string apptag;
map<string,string>::const_iterator it; map<string,string>::const_iterator it;
if ((it = doc.meta.find(Rcl::Doc::keyapptg)) != doc.meta.end()) if ((it = doc.meta.find(Rcl::Doc::keyapptg)) != doc.meta.end())
apptag = it->second; apptag = it->second;
cmd = rclconfig->getMimeViewerDef(doc.mimetype, apptag); cmdplusattr = rclconfig->getMimeViewerDef(doc.mimetype, apptag);
} }
if (cmd.length() == 0) { if (cmdplusattr.length() == 0) {
QMessageBox::warning(0, "Recoll", QMessageBox::warning(0, "Recoll",
tr("No external viewer configured for mime type [") tr("No external viewer configured for mime type [")
+ doc.mimetype.c_str() + "]"); + doc.mimetype.c_str() + "]");
return; return;
} }
// Extract possible attributes
ConfSimple attrs;
string cmd;
rclconfig->valueSplitAttributes(cmdplusattr, cmd, attrs);
bool ignoreipath = false;
if (attrs.get("ignoreipath", cmdplusattr))
ignoreipath = stringToBool(cmdplusattr);
// Split the command line // Split the command line
list<string> lcmd; list<string> lcmd;
if (!stringToStrings(cmd, lcmd)) { if (!stringToStrings(cmd, lcmd)) {
@ -949,7 +957,7 @@ void RclMain::startNativeViewer(Rcl::Doc doc)
// Command not found: start the user dialog to help find another one: // Command not found: start the user dialog to help find another one:
if (cmdpath.empty()) { if (cmdpath.empty()) {
QString mt = QString::fromAscii(doc.mimetype.c_str()); QString mt = QString::fromAscii(doc.mimetype.c_str());
QString message = tr("The viewer specified in mimeconf for %1: %2" QString message = tr("The viewer specified in mimeview for %1: %2"
" is not found.\nDo you want to start the " " is not found.\nDo you want to start the "
" preferences dialog ?") " preferences dialog ?")
.arg(mt).arg(QString::fromLocal8Bit(lcmd.front().c_str())); .arg(mt).arg(QString::fromLocal8Bit(lcmd.front().c_str()));
@ -971,7 +979,7 @@ void RclMain::startNativeViewer(Rcl::Doc doc)
// We may need a temp file, or not depending on the command arguments // We may need a temp file, or not depending on the command arguments
// and the fact that this is a subdoc or not. // and the fact that this is a subdoc or not.
bool wantsipath = cmd.find("%i") != string::npos; bool wantsipath = (cmd.find("%i") != string::npos) || ignoreipath;
bool wantsfile = cmd.find("%f") != string::npos; bool wantsfile = cmd.find("%f") != string::npos;
bool istempfile = false; bool istempfile = false;
string fn = fileurltolocalpath(doc.url); string fn = fileurltolocalpath(doc.url);