added menu to display missing helpers

This commit is contained in:
dockes 2008-10-08 16:15:22 +00:00
parent 990e534022
commit 2462b079fa
12 changed files with 118 additions and 42 deletions

View File

@ -1,5 +1,5 @@
#ifndef lint #ifndef lint
static char rcsid[] = "@(#$Id: rclconfig.cpp,v 1.61 2008-10-07 06:44:23 dockes Exp $ (C) 2004 J.F.Dockes"; static char rcsid[] = "@(#$Id: rclconfig.cpp,v 1.62 2008-10-08 16:15:22 dockes Exp $ (C) 2004 J.F.Dockes";
#endif #endif
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -42,6 +42,7 @@ static char rcsid[] = "@(#$Id: rclconfig.cpp,v 1.61 2008-10-07 06:44:23 dockes E
#include "debuglog.h" #include "debuglog.h"
#include "smallut.h" #include "smallut.h"
#include "textsplit.h" #include "textsplit.h"
#include "readfile.h"
#ifndef NO_NAMESPACES #ifndef NO_NAMESPACES
using namespace std; using namespace std;
@ -454,6 +455,22 @@ string RclConfig::getMimeHandlerDef(const std::string &mtype, bool filtertypes)
} }
return hs; return hs;
} }
string RclConfig::getMissingHelperDesc()
{
string fmiss = path_cat(getConfDir(), "missing");
string out;
file_to_string(fmiss, out);
return out;
}
void RclConfig::storeMissingHelperDesc(const string &s)
{
string fmiss = path_cat(getConfDir(), "missing");
FILE *fp = fopen(fmiss.c_str(), "w");
if (fp) {
fwrite(s.c_str(), s.size(), 1, fp);
fclose(fp);
}
}
// Read definitions for field prefixes, aliases, and hierarchy and arrange // Read definitions for field prefixes, aliases, and hierarchy and arrange
// things for speed (theses are used a lot during indexing) // things for speed (theses are used a lot during indexing)

View File

@ -16,7 +16,7 @@
*/ */
#ifndef _RCLCONFIG_H_INCLUDED_ #ifndef _RCLCONFIG_H_INCLUDED_
#define _RCLCONFIG_H_INCLUDED_ #define _RCLCONFIG_H_INCLUDED_
/* @(#$Id: rclconfig.h,v 1.41 2008-09-16 08:18:30 dockes Exp $ (C) 2004 J.F.Dockes */ /* @(#$Id: rclconfig.h,v 1.42 2008-10-08 16:15:22 dockes Exp $ (C) 2004 J.F.Dockes */
#include <list> #include <list>
#include <string> #include <string>
@ -161,6 +161,9 @@ class RclConfig {
bool getMimeViewerDefs(vector<pair<string, string> >&); bool getMimeViewerDefs(vector<pair<string, string> >&);
bool setMimeViewerDef(const string& mimetype, const string& cmd); bool setMimeViewerDef(const string& mimetype, const string& cmd);
/** Store/retrieve missing helpers description string */
string getMissingHelperDesc();
void storeMissingHelperDesc(const string &s);
/** Find exec file for external filter. cmd is the command name from the /** Find exec file for external filter. cmd is the command name from the
* command string returned by getMimeHandlerDef */ * command string returned by getMimeHandlerDef */

View File

@ -1,5 +1,5 @@
#!/bin/sh #!/bin/sh
# @(#$Id: rcldvi,v 1.6 2007-06-08 13:51:08 dockes Exp $ (C) 2006 J.F.Dockes # @(#$Id: rcldvi,v 1.7 2008-10-08 16:15:22 dockes Exp $ (C) 2006 J.F.Dockes
# This program is free software; you can redistribute it and/or modify # 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 # it under the terms of the GNU General Public License as published by
@ -110,7 +110,7 @@ elif iscmd catdvi ; then
fi fi
if test X$decoder = X ; then if test X$decoder = X ; then
senderror NOTFOUND dvips catdvi senderror HELPERNOTFOUND dvips or catdvi
fi fi
if test X$decoder = Xdvips ; then if test X$decoder = Xdvips ; then

View File

@ -1,5 +1,5 @@
#ifndef lint #ifndef lint
static char rcsid[] = "@(#$Id: indexer.cpp,v 1.69 2008-10-04 14:26:59 dockes Exp $ (C) 2004 J.F.Dockes"; static char rcsid[] = "@(#$Id: indexer.cpp,v 1.70 2008-10-08 16:15:22 dockes Exp $ (C) 2004 J.F.Dockes";
#endif #endif
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -146,12 +146,13 @@ bool DbIndexer::indexDb(bool resetbefore, list<string> *topdirs)
m_dbdir.c_str())); m_dbdir.c_str()));
return false; return false;
} }
if (!m_missingExternal.empty()) { string missing;
string missing; FileInterner::getMissingDescription(missing);
stringsToString(m_missingExternal, missing); if (!missing.empty()) {
LOGINFO(("DbIndexer::index missing helper program(s): %s\n", LOGINFO(("DbIndexer::index missing helper program(s):\n%s\n",
missing.c_str())); missing.c_str()));
} }
m_config->storeMissingHelperDesc(missing);
return true; return true;
} }
@ -443,9 +444,6 @@ DbIndexer::processone(const std::string &fn, const struct stat *stp,
string ipath; string ipath;
fis = interner.internfile(doc, ipath); fis = interner.internfile(doc, ipath);
if (fis == FileInterner::FIError) { if (fis == FileInterner::FIError) {
list<string> ext = interner.getMissingExternal();
m_missingExternal.merge(ext);
m_missingExternal.unique();
// We used to return at this point. // We used to return at this point.
// //
// The nice side was that if a filter failed because of a // The nice side was that if a filter failed because of a

View File

@ -16,7 +16,7 @@
*/ */
#ifndef _INDEXER_H_INCLUDED_ #ifndef _INDEXER_H_INCLUDED_
#define _INDEXER_H_INCLUDED_ #define _INDEXER_H_INCLUDED_
/* @(#$Id: indexer.h,v 1.25 2007-08-30 09:01:52 dockes Exp $ (C) 2004 J.F.Dockes */ /* @(#$Id: indexer.h,v 1.26 2008-10-08 16:15:22 dockes Exp $ (C) 2004 J.F.Dockes */
#include <string> #include <string>
#include <list> #include <list>
@ -146,7 +146,6 @@ class DbIndexer : public FsTreeWalkerCB {
Rcl::Db m_db; Rcl::Db m_db;
string m_tmpdir; string m_tmpdir;
DbIxStatusUpdater *m_updater; DbIxStatusUpdater *m_updater;
list<string> m_missingExternal; // Names of missing helper programs
bool init(bool rst = false, bool rdonly = false); bool init(bool rst = false, bool rdonly = false);
}; };

View File

@ -1,5 +1,5 @@
#ifndef lint #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 #endif
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -49,6 +49,9 @@ using namespace std;
static const string isep(":"); static const string isep(":");
static const string stxtplain("text/plain"); 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 // This is used when the user wants to retrieve a search result doc's parent
// (ie message having a given attachment) // (ie message having a given attachment)
bool FileInterner::getEnclosing(const string &url, const string &ipath, bool FileInterner::getEnclosing(const string &url, const string &ipath,
@ -245,35 +248,52 @@ bool FileInterner::dataToTempFile(const string& dt, const string& mt,
// See if the error string is formatted as a missing helper message, // See if the error string is formatted as a missing helper message,
// accumulate helper name if it is // 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) { if (msg.find("RECFILTERROR") == 0) {
list<string> lerr; list<string> lerr;
stringToStrings(msg, lerr); stringToStrings(msg, lerr);
if (lerr.size() > 2) { if (lerr.size() > 2) {
list<string>::iterator it = lerr.begin(); list<string>::iterator it = lerr.begin();
it++; lerr.erase(it++);
if (*it == "HELPERNOTFOUND") { if (*it == "HELPERNOTFOUND") {
it++; lerr.erase(it++);
m_missingExternal.push_back(it->c_str()); 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) void FileInterner::getMissingExternal(string& out)
{ {
m_missingExternal.sort(); stringsToString(o_missingExternal, out);
m_missingExternal.unique(); }
stringsToString(m_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. // Helper for extracting a value from a map.
@ -475,10 +495,10 @@ void FileInterner::processNextDocError(Rcl::Doc &doc, string& ipath)
{ {
collectIpathAndMT(doc, ipath); collectIpathAndMT(doc, ipath);
m_reason = m_handlers.back()->get_error(); m_reason = m_handlers.back()->get_error();
checkExternalMissing(m_reason); checkExternalMissing(m_reason, doc.mimetype);
LOGERR(("FileInterner::internfile: next_document error " LOGERR(("FileInterner::internfile: next_document error "
"[%s%s%s] %s\n", m_fn.c_str(), ipath.empty() ? "" : "|", "[%s%s%s] %s %s\n", m_fn.c_str(), ipath.empty() ? "" : "|",
ipath.c_str(), m_reason.c_str())); ipath.c_str(), doc.mimetype.c_str(), m_reason.c_str()));
} }
FileInterner::Status FileInterner::internfile(Rcl::Doc& doc, string& ipath) FileInterner::Status FileInterner::internfile(Rcl::Doc& doc, string& ipath)

View File

@ -16,12 +16,16 @@
*/ */
#ifndef _INTERNFILE_H_INCLUDED_ #ifndef _INTERNFILE_H_INCLUDED_
#define _INTERNFILE_H_INCLUDED_ #define _INTERNFILE_H_INCLUDED_
/* @(#$Id: internfile.h,v 1.20 2008-10-04 14:26:59 dockes Exp $ (C) 2004 J.F.Dockes */ /* @(#$Id: internfile.h,v 1.21 2008-10-08 16:15:22 dockes Exp $ (C) 2004 J.F.Dockes */
#include <string> #include <string>
#include <vector> #include <vector>
#include <map>
#include <set>
using std::string; using std::string;
using std::vector; using std::vector;
using std::map;
using std::set;
#include "pathut.h" #include "pathut.h"
#include "Filter.h" #include "Filter.h"
@ -95,6 +99,9 @@ class FileInterner {
*/ */
void setTargetMType(const string& tp) {m_targetMType = tp;} void setTargetMType(const string& tp) {m_targetMType = tp;}
/* In case we see an html version, it's set aside and can be recovered */
const string& get_html() {return m_html;}
/** Utility function: extract internal document into temporary file. /** Utility function: extract internal document into temporary file.
* This is used mainly for starting an external viewer for a * This is used mainly for starting an external viewer for a
* subdocument (ie: mail attachment). * subdocument (ie: mail attachment).
@ -110,9 +117,8 @@ class FileInterner {
const string& ipath, const string& mtype); const string& ipath, const string& mtype);
const string& getReason() const {return m_reason;} const string& getReason() const {return m_reason;}
const list<string>& getMissingExternal(); static void getMissingExternal(string& missing);
void getMissingExternal(string& missing); static void getMissingDescription(string& desc);
const string& get_html() {return m_html;}
private: private:
static const unsigned int MAXHANDLERS = 20; static const unsigned int MAXHANDLERS = 20;
@ -135,7 +141,8 @@ class FileInterner {
// Error data if any // Error data if any
string m_reason; string m_reason;
// Missing external programs // Missing external programs
list<string> m_missingExternal; static set<string> o_missingExternal;
static map<string, set<string> > o_typesForMissing;
void tmpcleanup(); void tmpcleanup();
bool dijontorcl(Rcl::Doc&); bool dijontorcl(Rcl::Doc&);
@ -143,7 +150,7 @@ class FileInterner {
bool dataToTempFile(const string& data, const string& mt, string& fn); bool dataToTempFile(const string& data, const string& mt, string& fn);
void popHandler(); void popHandler();
int addHandler(); int addHandler();
void checkExternalMissing(const string& msg); void checkExternalMissing(const string& msg, const string& mt);
void processNextDocError(Rcl::Doc &doc, string& ipath); void processNextDocError(Rcl::Doc &doc, string& ipath);
}; };

View File

@ -118,6 +118,7 @@
<action name="fileToggleIndexingAction"/> <action name="fileToggleIndexingAction"/>
<separator/> <separator/>
<action name="fileEraseDocHistoryAction"/> <action name="fileEraseDocHistoryAction"/>
<action name="showMissingHelpers_Action"/>
<separator/> <separator/>
<action name="fileExitAction"/> <action name="fileExitAction"/>
</item> </item>
@ -137,6 +138,7 @@
<separator/> <separator/>
<item text="&amp;Help" name="helpMenu"> <item text="&amp;Help" name="helpMenu">
<action name="userManualAction"/> <action name="userManualAction"/>
<action name="showMissingHelpers_Action"/>
<separator/> <separator/>
<action name="helpAbout_RecollAction"/> <action name="helpAbout_RecollAction"/>
</item> </item>
@ -227,6 +229,14 @@
<string>&amp;Erase document history</string> <string>&amp;Erase document history</string>
</property> </property>
</action> </action>
<action>
<property name="name">
<cstring>showMissingHelpers_Action</cstring>
</property>
<property name="menuText">
<string>&amp;Show missing helpers</string>
</property>
</action>
<action> <action>
<property name="name"> <property name="name">
<cstring>helpAbout_RecollAction</cstring> <cstring>helpAbout_RecollAction</cstring>

View File

@ -1,5 +1,5 @@
#ifndef lint #ifndef lint
static char rcsid[] = "@(#$Id: rclmain_w.cpp,v 1.55 2008-09-30 12:38:29 dockes Exp $ (C) 2005 J.F.Dockes"; static char rcsid[] = "@(#$Id: rclmain_w.cpp,v 1.56 2008-10-08 16:15:22 dockes Exp $ (C) 2005 J.F.Dockes";
#endif #endif
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -209,6 +209,8 @@ void RclMain::init()
this, SLOT(eraseDocHistory())); this, SLOT(eraseDocHistory()));
connect(helpAbout_RecollAction, SIGNAL(activated()), connect(helpAbout_RecollAction, SIGNAL(activated()),
this, SLOT(showAboutDialog())); this, SLOT(showAboutDialog()));
connect(showMissingHelpers_Action, SIGNAL(activated()),
this, SLOT(showMissingHelpers()));
connect(userManualAction, SIGNAL(activated()), this, SLOT(startManual())); connect(userManualAction, SIGNAL(activated()), this, SLOT(startManual()));
connect(toolsDoc_HistoryAction, SIGNAL(activated()), connect(toolsDoc_HistoryAction, SIGNAL(activated()),
this, SLOT(showDocHistory())); this, SLOT(showDocHistory()));
@ -579,6 +581,18 @@ void RclMain::showAboutDialog()
"<br>" + "http://www.recoll.org"; "<br>" + "http://www.recoll.org";
QMessageBox::information(this, tr("About Recoll"), vstring.c_str()); QMessageBox::information(this, tr("About Recoll"), vstring.c_str());
} }
void RclMain::showMissingHelpers()
{
string miss = rclconfig->getMissingHelperDesc();
QString msg = tr("External applications/commands needed and not found "
"for indexing your file types:\n\n");
if (!miss.empty()) {
msg += QString::fromUtf8(miss.c_str());
} else {
msg += tr("No helpers found missing");
}
QMessageBox::information(this, tr("Missing helper programs"), msg);
}
// If a preview (toplevel) window gets closed by the user, we need to // If a preview (toplevel) window gets closed by the user, we need to
// clean up because there is no way to reopen it. And check the case // clean up because there is no way to reopen it. And check the case

View File

@ -82,6 +82,7 @@ public slots:
virtual void showSortDialog(); virtual void showSortDialog();
virtual void showSpellDialog(); virtual void showSpellDialog();
virtual void showAboutDialog(); virtual void showAboutDialog();
virtual void showMissingHelpers();
virtual void startManual(); virtual void startManual();
virtual void showDocHistory(); virtual void showDocHistory();
virtual void showExtIdxDialog(); virtual void showExtIdxDialog();

View File

@ -1,5 +1,5 @@
#ifndef lint #ifndef lint
static char rcsid[] = "@(#$Id: smallut.cpp,v 1.33 2008-09-15 08:02:03 dockes Exp $ (C) 2004 J.F.Dockes"; static char rcsid[] = "@(#$Id: smallut.cpp,v 1.34 2008-10-08 16:15:22 dockes Exp $ (C) 2004 J.F.Dockes";
#endif #endif
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -304,6 +304,10 @@ void stringsToString(const vector<string> &tokens, string &s)
{ {
stringsToString<vector<string> >(tokens, s); stringsToString<vector<string> >(tokens, s);
} }
void stringsToString(const set<string> &tokens, string &s)
{
stringsToString<set<string> >(tokens, s);
}
void stringToTokens(const string& str, list<string>& tokens, void stringToTokens(const string& str, list<string>& tokens,
const string& delims, bool skipinit) const string& delims, bool skipinit)

View File

@ -16,17 +16,19 @@
*/ */
#ifndef _SMALLUT_H_INCLUDED_ #ifndef _SMALLUT_H_INCLUDED_
#define _SMALLUT_H_INCLUDED_ #define _SMALLUT_H_INCLUDED_
/* @(#$Id: smallut.h,v 1.30 2008-09-15 08:02:03 dockes Exp $ (C) 2004 J.F.Dockes */ /* @(#$Id: smallut.h,v 1.31 2008-10-08 16:15:22 dockes Exp $ (C) 2004 J.F.Dockes */
#include <string> #include <string>
#include <list> #include <list>
#include <vector> #include <vector>
#include <map> #include <map>
#include <set>
#ifndef NO_NAMESPACES #ifndef NO_NAMESPACES
using std::string; using std::string;
using std::list; using std::list;
using std::vector; using std::vector;
using std::map; using std::map;
using std::set;
#endif /* NO_NAMESPACES */ #endif /* NO_NAMESPACES */
// Note these are all ascii routines // Note these are all ascii routines
@ -55,6 +57,7 @@ extern bool stringToStrings(const string &s, vector<string> &tokens);
*/ */
extern void stringsToString(const list<string> &tokens, string &s); extern void stringsToString(const list<string> &tokens, string &s);
extern void stringsToString(const vector<string> &tokens, string &s); extern void stringsToString(const vector<string> &tokens, string &s);
extern void stringsToString(const set<string> &tokens, string &s);
/** /**
* Split input string. No handling of quoting * Split input string. No handling of quoting