Switch to side-by-side view

--- a/src/internfile/internfile.cpp
+++ b/src/internfile/internfile.cpp
@@ -1,5 +1,5 @@
 #ifndef lint
-static char rcsid[] = "@(#$Id: internfile.cpp,v 1.44 2008-10-04 14:26:59 dockes Exp $ (C) 2004 J.F.Dockes";
+static char rcsid[] = "@(#$Id: internfile.cpp,v 1.45 2008-10-08 16:15:22 dockes Exp $ (C) 2004 J.F.Dockes";
 #endif
 /*
  *   This program is free software; you can redistribute it and/or modify
@@ -49,6 +49,9 @@
 static const string isep(":");
 static const string stxtplain("text/plain");
 
+set<string> FileInterner::o_missingExternal;
+map<string, set<string> >  FileInterner::o_typesForMissing;
+
 // This is used when the user wants to retrieve a search result doc's parent
 // (ie message having a given attachment)
 bool FileInterner::getEnclosing(const string &url, const string &ipath,
@@ -245,35 +248,52 @@
 
 // See if the error string is formatted as a missing helper message,
 // accumulate helper name if it is
-void FileInterner::checkExternalMissing(const string& msg)
+void FileInterner::checkExternalMissing(const string& msg, const string& mt)
 {
     if (msg.find("RECFILTERROR") == 0) {
 	list<string> lerr;
 	stringToStrings(msg, lerr);
 	if (lerr.size() > 2) {
 	    list<string>::iterator it = lerr.begin();
-	    it++;
+	    lerr.erase(it++);
 	    if (*it == "HELPERNOTFOUND") {
-		it++;
-		m_missingExternal.push_back(it->c_str());
+		lerr.erase(it++);
+		string s;
+		stringsToString(lerr, s);
+		o_missingExternal.insert(s);
+		o_typesForMissing[s].insert(mt);
 	    }
 	}		    
     }
 }
 
-// Return the list of missing external helper apps that we saw while
-// working
-const list<string>& FileInterner::getMissingExternal() 
-{
-    m_missingExternal.sort();
-    m_missingExternal.unique();
-    return m_missingExternal;
-}
 void FileInterner::getMissingExternal(string& out) 
 {
-    m_missingExternal.sort();
-    m_missingExternal.unique();
-    stringsToString(m_missingExternal, out);
+    stringsToString(o_missingExternal, out);
+}
+
+void FileInterner::getMissingDescription(string& out)
+{
+    out.erase();
+
+    for (set<string>::const_iterator it = o_missingExternal.begin();
+	     it != o_missingExternal.end(); it++) {
+	out += *it;
+	map<string, set<string> >::const_iterator it2;
+	it2 = o_typesForMissing.find(*it);
+	if (it2 != o_typesForMissing.end()) {
+	    out += " (";
+	    set<string>::const_iterator it3;
+	    for (it3 = it2->second.begin(); 
+		 it3 != it2->second.end(); it3++) {
+		out += *it3;
+		out += string(" ");
+	    }
+	    trimstring(out);
+	    out += ")";
+	}	
+	out += "\n";
+    }
 }
 
 // Helper for extracting a value from a map.
@@ -475,10 +495,10 @@
 {
     collectIpathAndMT(doc, ipath);
     m_reason = m_handlers.back()->get_error();
-    checkExternalMissing(m_reason);
+    checkExternalMissing(m_reason, doc.mimetype);
     LOGERR(("FileInterner::internfile: next_document error "
-	    "[%s%s%s] %s\n", m_fn.c_str(), ipath.empty() ? "" : "|", 
-	    ipath.c_str(), m_reason.c_str()));
+	    "[%s%s%s] %s %s\n", m_fn.c_str(), ipath.empty() ? "" : "|", 
+	    ipath.c_str(), doc.mimetype.c_str(), m_reason.c_str()));
 }
 
 FileInterner::Status FileInterner::internfile(Rcl::Doc& doc, string& ipath)