webcache editor: handle interactions with indexer

This commit is contained in:
Jean-Francois Dockes 2016-04-14 09:32:53 +02:00
parent 759d8eca9f
commit f41e3f5aea
6 changed files with 155 additions and 58 deletions

View File

@ -17,6 +17,7 @@
#include "autoconfig.h" #include "autoconfig.h"
#include <signal.h> #include <signal.h>
#include "safeunistd.h"
#include <QMessageBox> #include <QMessageBox>
#include <QTimer> #include <QTimer>
@ -30,7 +31,7 @@
using namespace std; using namespace std;
void RclMain::idxStatus() void RclMain::updateIdxStatus()
{ {
ConfSimple cs(theconfig->getIdxStatusFile().c_str(), 1); ConfSimple cs(theconfig->getIdxStatusFile().c_str(), 1);
QString msg = tr("Indexing in progress: "); QString msg = tr("Indexing in progress: ");
@ -109,7 +110,7 @@ void RclMain::periodic100()
// update/show status even if the status file did not // update/show status even if the status file did not
// change (else the status line goes blank during // change (else the status line goes blank during
// lengthy operations). // lengthy operations).
idxStatus(); updateIdxStatus();
} }
} }
// Update the "start/stop indexing" menu entry, can't be done from // Update the "start/stop indexing" menu entry, can't be done from
@ -124,7 +125,16 @@ void RclMain::periodic100()
periodictimer->setInterval(200); periodictimer->setInterval(200);
} else { } else {
Pidfile pidfile(theconfig->getPidfile()); Pidfile pidfile(theconfig->getPidfile());
if (pidfile.open() == 0) { pid_t pid = pidfile.open();
if (pid == getpid()) {
// Locked by me
m_indexerState = IXST_NOTRUNNING;
fileToggleIndexingAction->setText(tr("Index locked"));
fileToggleIndexingAction->setEnabled(false);
fileRebuildIndexAction->setEnabled(false);
actionSpecial_Indexing->setEnabled(false);
periodictimer->setInterval(1000);
} else if (pid == 0) {
m_indexerState = IXST_NOTRUNNING; m_indexerState = IXST_NOTRUNNING;
fileToggleIndexingAction->setText(tr("Update &Index")); fileToggleIndexingAction->setText(tr("Update &Index"));
fileToggleIndexingAction->setEnabled(true); fileToggleIndexingAction->setEnabled(true);

View File

@ -77,16 +77,47 @@ void RclMain::showSpellDialog()
void RclMain::showWebcacheDialog() void RclMain::showWebcacheDialog()
{ {
switch (indexerState()) {
case RclMain::IXST_UNKNOWN:
QMessageBox::warning(0, "Recoll", tr("Unknown indexer state. "
"Can't access webcache file."));
return;
case RclMain::IXST_RUNNINGMINE:
case RclMain::IXST_RUNNINGNOTMINE:
QMessageBox::warning(0, "Recoll", tr("Indexer is running. "
"Can't access webcache file."));
return;
case RclMain::IXST_NOTRUNNING:
break;
}
if (!m_pidfile) {
m_pidfile = new Pidfile(theconfig->getPidfile());
if (m_pidfile->open() != 0) {
deleteZ(m_pidfile);
return;
}
if (m_pidfile->write_pid() != 0) {
deleteZ(m_pidfile);
return;
}
}
if (webcache == 0) { if (webcache == 0) {
webcache = new WebcacheEdit(0); webcache = new WebcacheEdit(this);
connect(new QShortcut(quitKeySeq, webcache), SIGNAL (activated()), webcache->setAttribute(Qt::WA_DeleteOnClose);
connect(new QShortcut(quitKeySeq, webcache), SIGNAL (activated()),
this, SLOT (fileExit())); this, SLOT (fileExit()));
webcache->show(); connect(webcache, SIGNAL(destroyed(QObject*)),
} else { this, SLOT(onWebcacheDestroyed(QObject*)) );
webcache->close();
webcache->show(); webcache->show();
} }
} }
void RclMain::onWebcacheDestroyed(QObject *)
{
deleteZ(m_pidfile);
webcache = 0;
}
void RclMain::showIndexStatistics() void RclMain::showIndexStatistics()
{ {

View File

@ -303,7 +303,8 @@ void RclMain::init()
sc = new QShortcut(seql, this); sc = new QShortcut(seql, this);
connect(sc, SIGNAL (activated()), sSearch, SLOT (takeFocus())); connect(sc, SIGNAL (activated()), sSearch, SLOT (takeFocus()));
connect(&m_watcher, SIGNAL(fileChanged(QString)), this, SLOT(idxStatus())); connect(&m_watcher, SIGNAL(fileChanged(QString)),
this, SLOT(updateIdxStatus()));
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
connect(sSearch, connect(sSearch,
@ -350,8 +351,12 @@ void RclMain::init()
this, SLOT(showAdvSearchDialog())); this, SLOT(showAdvSearchDialog()));
connect(toolsSpellAction, SIGNAL(triggered()), connect(toolsSpellAction, SIGNAL(triggered()),
this, SLOT(showSpellDialog())); this, SLOT(showSpellDialog()));
#ifdef _WIN32
actionWebcache_Editor->setEnabled(false);
#else
connect(actionWebcache_Editor, SIGNAL(triggered()), connect(actionWebcache_Editor, SIGNAL(triggered()),
this, SLOT(showWebcacheDialog())); this, SLOT(showWebcacheDialog()));
#endif
connect(actionQuery_Fragments, SIGNAL(triggered()), connect(actionQuery_Fragments, SIGNAL(triggered()),
this, SLOT(showFragButs())); this, SLOT(showFragButs()));
connect(actionSpecial_Indexing, SIGNAL(triggered()), connect(actionSpecial_Indexing, SIGNAL(triggered()),

View File

@ -47,80 +47,84 @@ class WebcacheEdit;
#include "ui_rclmain.h" #include "ui_rclmain.h"
namespace confgui { namespace confgui {
class ConfIndexW; class ConfIndexW;
} }
using confgui::ConfIndexW; using confgui::ConfIndexW;
class RclTrayIcon; class RclTrayIcon;
class RclMain : public QMainWindow, public Ui::RclMainBase class RclMain : public QMainWindow, public Ui::RclMainBase {
{ Q_OBJECT;
Q_OBJECT
public: public:
enum IndexerState {IXST_UNKNOWN, IXST_NOTRUNNING, RclMain(QWidget * parent = 0)
IXST_RUNNINGMINE, IXST_RUNNINGNOTMINE}; : QMainWindow(parent),
RclMain(QWidget * parent = 0) curPreview(0),
: QMainWindow(parent), asearchform(0),
curPreview(0), uiprefs(0),
asearchform(0), indexConfig(0),
uiprefs(0), indexSched(0),
indexConfig(0), cronTool(0),
indexSched(0), rtiTool(0),
cronTool(0), spellform(0),
rtiTool(0),
spellform(0),
fragbuts(0), fragbuts(0),
specidx(0), specidx(0),
periodictimer(0), periodictimer(0),
webcache(0), webcache(0),
restable(0), restable(0),
displayingTable(0), displayingTable(0),
m_idNoStem(0), m_idNoStem(0),
m_idAllStem(0), m_idAllStem(0),
m_toolsTB(0), m_resTB(0), m_toolsTB(0), m_resTB(0),
m_filtFRM(0), m_filtCMB(0), m_filtBGRP(0), m_filtMN(0), m_filtFRM(0), m_filtCMB(0), m_filtBGRP(0), m_filtMN(0),
m_idxproc(0), m_idxproc(0),
m_idxkilled(false), m_idxkilled(false),
m_catgbutvecidx(0), m_catgbutvecidx(0),
m_sortspecnochange(false), m_sortspecnochange(false),
m_indexerState(IXST_UNKNOWN), m_indexerState(IXST_UNKNOWN),
m_queryActive(false), m_queryActive(false),
m_firstIndexing(false), m_firstIndexing(false),
m_searchIsSimple(false) m_searchIsSimple(false),
{ m_pidfile(0) {
setupUi(this); setupUi(this);
init(); init();
} }
~RclMain() {} ~RclMain() {}
QString getQueryDescription(); QString getQueryDescription();
/** This is only called from main() to set an URL to be displayed (using /** This is only called from main() to set an URL to be displayed (using
recoll as a doc extracter for embedded docs */ recoll as a doc extracter for embedded docs */
virtual void setUrlToView(const QString& u) {m_urltoview = u;} virtual void setUrlToView(const QString& u) {
m_urltoview = u;
}
/** Same usage: actually display the current urltoview */ /** Same usage: actually display the current urltoview */
virtual void viewUrl(); virtual void viewUrl();
bool lastSearchSimple() bool lastSearchSimple() {
{ return m_searchIsSimple;
return m_searchIsSimple;
} }
// Takes copies of the args instead of refs. Lazy and safe. // Takes copies of the args instead of refs. Lazy and safe.
void newDupsW(const Rcl::Doc doc, const std::vector<Rcl::Doc> dups); void newDupsW(const Rcl::Doc doc, const std::vector<Rcl::Doc> dups);
protected: enum IndexerState {IXST_UNKNOWN, IXST_NOTRUNNING,
virtual void showEvent(QShowEvent *); IXST_RUNNINGMINE, IXST_RUNNINGNOTMINE};
IndexerState indexerState() const {
return m_indexerState;
}
public slots: public slots:
virtual void fileExit(); virtual void fileExit();
virtual void idxStatus();
virtual void periodic100(); virtual void periodic100();
virtual void toggleIndexing(); virtual void toggleIndexing();
virtual void rebuildIndex(); virtual void rebuildIndex();
virtual void specialIndex(); virtual void specialIndex();
virtual void startSearch(STD_SHARED_PTR<Rcl::SearchData> sdata, bool issimple); virtual void startSearch(STD_SHARED_PTR<Rcl::SearchData> sdata,
bool issimple);
virtual void previewClosed(Preview *w); virtual void previewClosed(Preview *w);
virtual void showAdvSearchDialog(); virtual void showAdvSearchDialog();
virtual void showSpellDialog(); virtual void showSpellDialog();
@ -153,8 +157,8 @@ public slots:
virtual void showSnippets(Rcl::Doc); virtual void showSnippets(Rcl::Doc);
virtual void startPreview(int docnum, Rcl::Doc doc, int keymods); virtual void startPreview(int docnum, Rcl::Doc doc, int keymods);
virtual void startPreview(Rcl::Doc); virtual void startPreview(Rcl::Doc);
virtual void startNativeViewer(Rcl::Doc, int pagenum = -1, virtual void startNativeViewer(Rcl::Doc, int pagenum = -1,
QString term=QString()); QString term = QString());
virtual void openWith(Rcl::Doc, string); virtual void openWith(Rcl::Doc, string);
virtual void saveDocToFile(Rcl::Doc); virtual void saveDocToFile(Rcl::Doc);
virtual void previewNextInTab(Preview *, int sid, int docnum); virtual void previewNextInTab(Preview *, int sid, int docnum);
@ -181,6 +185,9 @@ public slots:
virtual void setFilterCtlStyle(int stl); virtual void setFilterCtlStyle(int stl);
virtual void showTrayMessage(const QString& text); virtual void showTrayMessage(const QString& text);
private slots:
virtual void updateIdxStatus();
virtual void onWebcacheDestroyed(QObject *);
signals: signals:
void docSourceChanged(STD_SHARED_PTR<DocSequence>); void docSourceChanged(STD_SHARED_PTR<DocSequence>);
void stemLangChanged(const QString& lang); void stemLangChanged(const QString& lang);
@ -189,7 +196,9 @@ signals:
void searchReset(); void searchReset();
protected: protected:
virtual void closeEvent( QCloseEvent * ); virtual void closeEvent(QCloseEvent *);
virtual void showEvent(QShowEvent *);
private: private:
Preview *curPreview; Preview *curPreview;
@ -236,10 +245,13 @@ private:
RclTrayIcon *m_trayicon; RclTrayIcon *m_trayicon;
// We sometimes take the indexer lock (e.g.: when editing the webcache)
Pidfile *m_pidfile;
virtual void init(); virtual void init();
virtual void setupResTB(bool combo); virtual void setupResTB(bool combo);
virtual void previewPrevOrNextInTab(Preview *, int sid, int docnum, virtual void previewPrevOrNextInTab(Preview *, int sid, int docnum,
bool next); bool next);
virtual void execViewer(const map<string, string>& subs, bool enterHistory, virtual void execViewer(const map<string, string>& subs, bool enterHistory,
const string& execpath, const vector<string>& lcmd, const string& execpath, const vector<string>& lcmd,
const string& cmd, Rcl::Doc doc); const string& cmd, Rcl::Doc doc);

View File

@ -34,12 +34,15 @@
#include <QShortcut> #include <QShortcut>
#include <QMenu> #include <QMenu>
#include <QClipboard> #include <QClipboard>
#include <QTimer>
#include <QMessageBox>
#include "recoll.h" #include "recoll.h"
#include "webcache.h" #include "webcache.h"
#include "beaglequeuecache.h" #include "beaglequeuecache.h"
#include "circache.h" #include "circache.h"
#include "conftree.h" #include "conftree.h"
#include "rclmain_w.h"
using namespace std; using namespace std;
@ -66,6 +69,10 @@ WebcacheModel::WebcacheModel(QObject *parent)
//qDebug() << "WebcacheModel::WebcacheModel()"; //qDebug() << "WebcacheModel::WebcacheModel()";
reload(); reload();
} }
WebcacheModel::~WebcacheModel()
{
delete m;
}
void WebcacheModel::reload() void WebcacheModel::reload()
{ {
@ -214,8 +221,8 @@ static const char *wwnm = "/Recoll/prefs/webcachew";
static const char *whnm = "/Recoll/prefs/webcacheh"; static const char *whnm = "/Recoll/prefs/webcacheh";
static const QKeySequence closeKS(Qt::ControlModifier+Qt::Key_W); static const QKeySequence closeKS(Qt::ControlModifier+Qt::Key_W);
WebcacheEdit::WebcacheEdit(QWidget *parent) WebcacheEdit::WebcacheEdit(RclMain *parent)
: QDialog(parent) : QDialog(parent), m_recoll(parent), m_modified(false)
{ {
//qDebug() << "WebcacheEdit::WebcacheEdit()"; //qDebug() << "WebcacheEdit::WebcacheEdit()";
setupUi(this); setupUi(this);
@ -271,7 +278,26 @@ void WebcacheEdit::createPopupMenu(const QPoint& pos)
if (selsz == 1) { if (selsz == 1) {
popup->addAction(tr("Copy URL"), this, SLOT(copyURL())); popup->addAction(tr("Copy URL"), this, SLOT(copyURL()));
} }
popup->addAction(tr("Delete selection"), this, SLOT(deleteSelected())); if (m_recoll) {
RclMain::IndexerState ixstate = m_recoll->indexerState();
switch (ixstate) {
case RclMain::IXST_UNKNOWN:
QMessageBox::warning(0, "Recoll",
tr("Unknown indexer state. "
"Can't edit webcache file."));
break;
case RclMain::IXST_RUNNINGMINE:
case RclMain::IXST_RUNNINGNOTMINE:
QMessageBox::warning(0, "Recoll",
tr("Indexer is running. "
"Can't edit webcache file."));
break;
case RclMain::IXST_NOTRUNNING:
popup->addAction(tr("Delete selection"),
this, SLOT(deleteSelected()));
break;
}
}
popup->popup(tableview->mapToGlobal(pos)); popup->popup(tableview->mapToGlobal(pos));
} }
@ -280,7 +306,9 @@ void WebcacheEdit::deleteSelected()
{ {
QModelIndexList selection = tableview->selectionModel()->selectedRows(); QModelIndexList selection = tableview->selectionModel()->selectedRows();
for (int i = 0; i < selection.size(); i++) { for (int i = 0; i < selection.size(); i++) {
m_model->deleteIdx(selection[i].row()); if (m_model->deleteIdx(selection[i].row())) {
m_modified = true;
}
} }
m_model->reload(); m_model->reload();
m_model->setSearchFilter(searchLE->text()); m_model->setSearchFilter(searchLE->text());
@ -318,6 +346,12 @@ void WebcacheEdit::saveColState()
void WebcacheEdit::closeEvent(QCloseEvent *event) void WebcacheEdit::closeEvent(QCloseEvent *event)
{ {
if (m_modified) {
QMessageBox::information(0, "Recoll",
tr("Webcache was modified, you will need "
"to run the indexer after closing this "
"window."));
}
if (!isFullScreen()) { if (!isFullScreen()) {
QSettings settings; QSettings settings;
settings.setValue(wwnm, width()); settings.setValue(wwnm, width());

View File

@ -34,6 +34,7 @@ class WebcacheModel : public QAbstractTableModel {
public: public:
WebcacheModel(QObject *parent = 0); WebcacheModel(QObject *parent = 0);
~WebcacheModel();
// Reimplemented methods // Reimplemented methods
virtual int rowCount (const QModelIndex& = QModelIndex()) const; virtual int rowCount (const QModelIndex& = QModelIndex()) const;
@ -44,20 +45,22 @@ public:
int role = Qt::DisplayRole ) const; int role = Qt::DisplayRole ) const;
bool deleteIdx(unsigned int idx); bool deleteIdx(unsigned int idx);
std::string getURL(unsigned int idx); std::string getURL(unsigned int idx);
void reload();
public slots: public slots:
void setSearchFilter(const QString&); void setSearchFilter(const QString&);
void reload();
private: private:
WebcacheModelInternal *m; WebcacheModelInternal *m;
}; };
class RclMain;
class WebcacheEdit : public QDialog, public Ui::Webcache { class WebcacheEdit : public QDialog, public Ui::Webcache {
Q_OBJECT; Q_OBJECT;
public: public:
WebcacheEdit(QWidget *parent); WebcacheEdit(RclMain *parent);
public slots: public slots:
void saveColState(); void saveColState();
void createPopupMenu(const QPoint&); void createPopupMenu(const QPoint&);
@ -67,6 +70,8 @@ protected:
void closeEvent(QCloseEvent *); void closeEvent(QCloseEvent *);
private: private:
WebcacheModel *m_model; WebcacheModel *m_model;
RclMain *m_recoll;
bool m_modified;
}; };