GUI: added menu entry to show all the mime types actually indexed (by content)

This commit is contained in:
Jean-Francois Dockes 2011-11-25 19:47:56 +01:00
parent 607d3cc27b
commit 1931595637
9 changed files with 259 additions and 0 deletions

View File

@ -547,6 +547,50 @@ void FileInterner::getMissingDescription(FIMissingStore *st, string& out)
}
}
void FileInterner::getMissingFromDescription(FIMissingStore *st, const string& in)
{
if (st == 0)
return;
// The "missing" file is text. Each line defines a missing filter
// and the list of mime types actually encountered that needed it (see method
// getMissingDescription())
vector<string> lines;
stringToTokens(in, lines, "\n");
for (vector<string>::const_iterator it = lines.begin();
it != lines.end(); it++) {
// Lines from the file are like:
//
// filter name string (mime1 mime2)
//
// We can't be too sure that there will never be a parenthesis
// inside the filter string as this comes from the filter
// itself. The list part is safer, so we start from the end.
const string& line = *it;
string::size_type lastopen = line.find_last_of("(");
if (lastopen == string::npos)
continue;
string::size_type lastclose = line.find_last_of(")");
if (lastclose == string::npos || lastclose <= lastopen + 1)
continue;
string smtypes = line.substr(lastopen+1, lastclose - lastopen - 1);
vector<string> mtypes;
stringToTokens(smtypes, mtypes);
string filter = line.substr(0, lastopen);
trimstring(filter);
if (filter.empty())
continue;
st->m_missingExternal.insert(filter);
for (vector<string>::const_iterator itt = mtypes.begin();
itt != mtypes.end(); itt++) {
st->m_typesForMissing[filter].insert(*itt);
}
}
}
// Helper for extracting a value from a map.
static inline bool getKeyValue(const map<string, string>& docdata,
const string& key, string& value)

View File

@ -193,6 +193,8 @@ class FileInterner {
const string& getReason() const {return m_reason;}
static void getMissingExternal(FIMissingStore *st, string& missing);
static void getMissingDescription(FIMissingStore *st, string& desc);
// Parse "missing" file contents into memory struct
static void getMissingFromDescription(FIMissingStore *st, const string& desc);
bool ok() {return m_ok;}
private:

32
src/qtgui/listdialog.h Normal file
View File

@ -0,0 +1,32 @@
/*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef LISTDIALOG_H
#define LISTDIALOG_H
#include "ui_listdialog.h"
class ListDialog : public QDialog, public Ui::ListDialog {
Q_OBJECT
public:
ListDialog(QWidget * parent = 0)
: QDialog(parent)
{
setupUi(this);
}
};
#endif // LISTDIALOG_H

79
src/qtgui/listdialog.ui Normal file
View File

@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ListDialog</class>
<widget class="QDialog" name="ListDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>GroupBox</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QListWidget" name="listWidget"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Ok</set>
</property>
<property name="centerButtons">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>ListDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>ListDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -138,7 +138,9 @@
<addaction name="separator"/>
<addaction name="fileEraseSearchHistoryAction"/>
<addaction name="fileEraseDocHistoryAction"/>
<addaction name="separator"/>
<addaction name="showMissingHelpers_Action"/>
<addaction name="showActiveTypes_Action"/>
<addaction name="separator"/>
<addaction name="toggleFullScreenAction"/>
<addaction name="separator"/>
@ -169,6 +171,7 @@
</property>
<addaction name="userManualAction"/>
<addaction name="showMissingHelpers_Action"/>
<addaction name="showActiveTypes_Action"/>
<addaction name="separator"/>
<addaction name="helpAbout_RecollAction"/>
</widget>
@ -221,6 +224,14 @@
<cstring>showMissingHelpers_Action</cstring>
</property>
</action>
<action name="showActiveTypes_Action">
<property name="text">
<string>&amp;Show indexed types</string>
</property>
<property name="name" stdset="0">
<cstring>showActiveTypes_Action</cstring>
</property>
</action>
<action name="helpAbout_RecollAction">
<property name="text">
<string>&amp;About Recoll</string>

View File

@ -68,6 +68,7 @@ using std::pair;
#include "docseqhist.h"
#include "confguiindex.h"
#include "restable.h"
#include "listdialog.h"
using namespace confgui;
@ -225,6 +226,8 @@ void RclMain::init()
this, SLOT(showAboutDialog()));
connect(showMissingHelpers_Action, SIGNAL(activated()),
this, SLOT(showMissingHelpers()));
connect(showActiveTypes_Action, SIGNAL(activated()),
this, SLOT(showActiveTypes()));
connect(userManualAction, SIGNAL(activated()),
this, SLOT(startManual()));
connect(toolsDoc_HistoryAction, SIGNAL(activated()),
@ -749,6 +752,86 @@ void RclMain::showMissingHelpers()
QMessageBox::information(this, tr("Missing helper programs"), msg);
}
void RclMain::showActiveTypes()
{
if (rcldb == 0) {
QMessageBox::warning(0, tr("Error"),
tr("Index not open"),
QMessageBox::Ok,
QMessageBox::NoButton);
return;
}
// Get list of all mime types in index. For this, we use a
// wildcard field search on mtype
Rcl::TermMatchResult matches;
string prefix;
if (!rcldb->termMatch(Rcl::Db::ET_WILD, "", "*", matches, -1, "mtype",
&prefix)) {
QMessageBox::warning(0, tr("Error"),
tr("Index query error"),
QMessageBox::Ok,
QMessageBox::NoButton);
return;
}
// Build the set of mtypes, stripping the prefix
set<string> mtypesfromdb;
for (list<Rcl::TermMatchEntry>::const_iterator it = matches.entries.begin();
it != matches.entries.end(); it++) {
mtypesfromdb.insert(it->term.substr(prefix.size()));
}
// All types listed in mimeconf:
list<string> mtypesfromconfig = theconfig->getAllMimeTypes();
// Intersect file system types with config types (those not in the
// config can be indexed by name, not by content)
set<string> mtypesfromdbconf;
for (list<string>::const_iterator it = mtypesfromconfig.begin();
it != mtypesfromconfig.end(); it++) {
if (mtypesfromdb.find(*it) != mtypesfromdb.end())
mtypesfromdbconf.insert(*it);
}
// Substract the types for missing helpers (the docs are indexed by name only):
string miss = theconfig->getMissingHelperDesc();
if (!miss.empty()) {
FIMissingStore st;
FileInterner::getMissingFromDescription(&st, miss);
map<string, set<string> >::const_iterator it;
for (it = st.m_typesForMissing.begin();
it != st.m_typesForMissing.end(); it++) {
set<string>::const_iterator it1;
for (it1 = it->second.begin();
it1 != it->second.end(); it1++) {
set<string>::iterator it2 = mtypesfromdbconf.find(*it1);
if (it2 != mtypesfromdbconf.end())
mtypesfromdbconf.erase(it2);
}
}
}
ListDialog dialog;
dialog.setWindowTitle(tr("Indexed Mime Types"));
// Turn the result into a string and display
dialog.groupBox->setTitle(tr("Content has been indexed for these mime types:"));
// We replace the list with an editor so that the user can copy/paste
delete dialog.listWidget;
QTextEdit *editor = new QTextEdit(dialog.groupBox);
editor->setReadOnly(TRUE);
dialog.horizontalLayout->addWidget(editor);
for (set<string>::const_iterator it = mtypesfromdbconf.begin();
it != mtypesfromdbconf.end(); it++) {
editor->append(QString::fromAscii(it->c_str()));
}
editor->moveCursor(QTextCursor::Start);
editor->ensureCursorVisible();
dialog.exec();
}
// 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
// where the current one is closed

View File

@ -69,6 +69,7 @@ public slots:
virtual void showSpellDialog();
virtual void showAboutDialog();
virtual void showMissingHelpers();
virtual void showActiveTypes();
virtual void startManual();
virtual void startManual(const string&);
virtual void showDocHistory();

View File

@ -7,6 +7,7 @@ HEADERS += \
advsearch_w.h \
confgui/confgui.h \
confgui/confguiindex.h \
listdialog.h \
preview_w.h \
rclhelp.h \
rclmain_w.h \
@ -41,6 +42,7 @@ SOURCES += \
FORMS = \
advsearch.ui \
listdialog.ui \
rclmain.ui \
restable.ui \
spell.ui \

View File

@ -139,6 +139,11 @@ date_range_filter(int y1, int m1, int d1, int y2, int m2, int d2)
}
// Expand categories and mime type wild card exps
// Actually, using getAllMimeTypes() here is a bit problematic because
// there maybe other types in the index, not indexed by content, but
// which could be searched by file name. It would probably be
// preferable to do a termMatch() on field "mtype", which would
// retrieve all values from the index.
bool SearchData::expandFileTypes(RclConfig *cfg, vector<string>& tps)
{
if (!cfg) {