exit more abruptly to avoid mysterious core dump on quitting program
This commit is contained in:
commit
96f181cad3
1113 changed files with 427683 additions and 0 deletions
455
src/qtgui/rclm_wins.cpp
Normal file
455
src/qtgui/rclm_wins.cpp
Normal file
|
@ -0,0 +1,455 @@
|
|||
/* Copyright (C) 2005 J.F.Dockes
|
||||
* 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.
|
||||
*/
|
||||
#include "autoconfig.h"
|
||||
|
||||
#include <QShortcut>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include "debuglog.h"
|
||||
#include "internfile.h"
|
||||
#include "listdialog.h"
|
||||
#include "confgui/confguiindex.h"
|
||||
#include "idxsched.h"
|
||||
#include "crontool.h"
|
||||
#include "rtitool.h"
|
||||
#include "snippets_w.h"
|
||||
#include "fragbuts.h"
|
||||
#include "specialindex.h"
|
||||
#include "rclmain_w.h"
|
||||
#include "webcache.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
static const QKeySequence quitKeySeq("Ctrl+q");
|
||||
static const QKeySequence closeKeySeq("Ctrl+w");
|
||||
|
||||
// Open advanced search dialog.
|
||||
void RclMain::showAdvSearchDialog()
|
||||
{
|
||||
if (asearchform == 0) {
|
||||
asearchform = new AdvSearch(0);
|
||||
if (asearchform == 0) {
|
||||
return;
|
||||
}
|
||||
connect(new QShortcut(quitKeySeq, asearchform), SIGNAL (activated()),
|
||||
this, SLOT (fileExit()));
|
||||
|
||||
connect(asearchform,
|
||||
SIGNAL(startSearch(STD_SHARED_PTR<Rcl::SearchData>, bool)),
|
||||
this, SLOT(startSearch(STD_SHARED_PTR<Rcl::SearchData>, bool)));
|
||||
asearchform->show();
|
||||
} else {
|
||||
// Close and reopen, in hope that makes us visible...
|
||||
asearchform->close();
|
||||
asearchform->show();
|
||||
}
|
||||
}
|
||||
|
||||
void RclMain::showSpellDialog()
|
||||
{
|
||||
if (spellform == 0) {
|
||||
spellform = new SpellW(0);
|
||||
connect(new QShortcut(quitKeySeq, spellform), SIGNAL (activated()),
|
||||
this, SLOT (fileExit()));
|
||||
connect(spellform, SIGNAL(wordSelect(QString)),
|
||||
sSearch, SLOT(addTerm(QString)));
|
||||
spellform->show();
|
||||
} else {
|
||||
// Close and reopen, in hope that makes us visible...
|
||||
spellform->close();
|
||||
spellform->show();
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
webcache = new WebcacheEdit(this);
|
||||
webcache->setAttribute(Qt::WA_DeleteOnClose);
|
||||
connect(new QShortcut(quitKeySeq, webcache), SIGNAL (activated()),
|
||||
this, SLOT (fileExit()));
|
||||
connect(webcache, SIGNAL(destroyed(QObject*)),
|
||||
this, SLOT(onWebcacheDestroyed(QObject*)) );
|
||||
webcache->show();
|
||||
}
|
||||
}
|
||||
void RclMain::onWebcacheDestroyed(QObject *)
|
||||
{
|
||||
deleteZ(m_pidfile);
|
||||
webcache = 0;
|
||||
}
|
||||
|
||||
void RclMain::showIndexStatistics()
|
||||
{
|
||||
showSpellDialog();
|
||||
if (spellform == 0)
|
||||
return;
|
||||
spellform->setMode(SpellW::TYPECMB_STATS);
|
||||
}
|
||||
|
||||
void RclMain::showFragButs()
|
||||
{
|
||||
if (fragbuts && fragbuts->isStale(0)) {
|
||||
deleteZ(fragbuts);
|
||||
}
|
||||
if (fragbuts == 0) {
|
||||
fragbuts = new FragButs(0);
|
||||
if (fragbuts->ok()) {
|
||||
fragbuts->show();
|
||||
connect(fragbuts, SIGNAL(fragmentsChanged()),
|
||||
this, SLOT(onFragmentsChanged()));
|
||||
} else {
|
||||
deleteZ(fragbuts);
|
||||
}
|
||||
} else {
|
||||
// Close and reopen, in hope that makes us visible...
|
||||
fragbuts->close();
|
||||
fragbuts->show();
|
||||
}
|
||||
}
|
||||
|
||||
void RclMain::showSpecIdx()
|
||||
{
|
||||
if (specidx == 0) {
|
||||
specidx = new SpecIdxW(0);
|
||||
connect(specidx, SIGNAL(accepted()), this, SLOT(specialIndex()));
|
||||
specidx->show();
|
||||
} else {
|
||||
// Close and reopen, in hope that makes us visible...
|
||||
specidx->close();
|
||||
specidx->show();
|
||||
}
|
||||
}
|
||||
|
||||
void RclMain::showIndexConfig()
|
||||
{
|
||||
showIndexConfig(false);
|
||||
}
|
||||
void RclMain::execIndexConfig()
|
||||
{
|
||||
showIndexConfig(true);
|
||||
}
|
||||
void RclMain::showIndexConfig(bool modal)
|
||||
{
|
||||
LOGDEB(("showIndexConfig()\n"));
|
||||
if (indexConfig == 0) {
|
||||
indexConfig = new ConfIndexW(0, theconfig);
|
||||
connect(new QShortcut(quitKeySeq, indexConfig), SIGNAL (activated()),
|
||||
this, SLOT (fileExit()));
|
||||
} else {
|
||||
// Close and reopen, in hope that makes us visible...
|
||||
indexConfig->close();
|
||||
indexConfig->reloadPanels();
|
||||
}
|
||||
if (modal) {
|
||||
indexConfig->exec();
|
||||
indexConfig->setModal(false);
|
||||
} else {
|
||||
indexConfig->show();
|
||||
}
|
||||
}
|
||||
|
||||
void RclMain::showIndexSched()
|
||||
{
|
||||
showIndexSched(false);
|
||||
}
|
||||
void RclMain::execIndexSched()
|
||||
{
|
||||
showIndexSched(true);
|
||||
}
|
||||
void RclMain::showIndexSched(bool modal)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
QMessageBox::information(this, tr("Index scheduling"),
|
||||
tr("Sorry, not available under Windows for now, use the File menu entries "
|
||||
"to update the index"));
|
||||
return;
|
||||
#endif
|
||||
LOGDEB(("showIndexSched()\n"));
|
||||
if (indexSched == 0) {
|
||||
indexSched = new IdxSchedW(this);
|
||||
connect(new QShortcut(quitKeySeq, indexSched), SIGNAL (activated()),
|
||||
this, SLOT (fileExit()));
|
||||
connect(indexSched->cronCLB, SIGNAL(clicked()),
|
||||
this, SLOT(execCronTool()));
|
||||
if (theconfig && theconfig->isDefaultConfig()) {
|
||||
#ifdef RCL_MONITOR
|
||||
connect(indexSched->rtidxCLB, SIGNAL(clicked()),
|
||||
this, SLOT(execRTITool()));
|
||||
#else
|
||||
indexSched->rtidxCLB->setEnabled(false);
|
||||
indexSched->rtidxCLB->setToolTip(tr("Disabled because the real time indexer was not compiled in."));
|
||||
#endif
|
||||
} else {
|
||||
indexSched->rtidxCLB->setEnabled(false);
|
||||
indexSched->rtidxCLB->setToolTip(tr("This configuration tool only works for the main index."));
|
||||
}
|
||||
} else {
|
||||
// Close and reopen, in hope that makes us visible...
|
||||
indexSched->close();
|
||||
}
|
||||
if (modal) {
|
||||
indexSched->exec();
|
||||
indexSched->setModal(false);
|
||||
} else {
|
||||
indexSched->show();
|
||||
}
|
||||
}
|
||||
|
||||
void RclMain::showCronTool()
|
||||
{
|
||||
showCronTool(false);
|
||||
}
|
||||
void RclMain::execCronTool()
|
||||
{
|
||||
showCronTool(true);
|
||||
}
|
||||
void RclMain::showCronTool(bool modal)
|
||||
{
|
||||
LOGDEB(("showCronTool()\n"));
|
||||
if (cronTool == 0) {
|
||||
cronTool = new CronToolW(0);
|
||||
connect(new QShortcut(quitKeySeq, cronTool), SIGNAL (activated()),
|
||||
this, SLOT (fileExit()));
|
||||
} else {
|
||||
// Close and reopen, in hope that makes us visible...
|
||||
cronTool->close();
|
||||
}
|
||||
if (modal) {
|
||||
cronTool->exec();
|
||||
cronTool->setModal(false);
|
||||
} else {
|
||||
cronTool->show();
|
||||
}
|
||||
}
|
||||
|
||||
void RclMain::showRTITool()
|
||||
{
|
||||
showRTITool(false);
|
||||
}
|
||||
void RclMain::execRTITool()
|
||||
{
|
||||
showRTITool(true);
|
||||
}
|
||||
void RclMain::showRTITool(bool modal)
|
||||
{
|
||||
LOGDEB(("showRTITool()\n"));
|
||||
if (rtiTool == 0) {
|
||||
rtiTool = new RTIToolW(0);
|
||||
connect(new QShortcut(quitKeySeq, rtiTool), SIGNAL (activated()),
|
||||
this, SLOT (fileExit()));
|
||||
} else {
|
||||
// Close and reopen, in hope that makes us visible...
|
||||
rtiTool->close();
|
||||
}
|
||||
if (modal) {
|
||||
rtiTool->exec();
|
||||
rtiTool->setModal(false);
|
||||
} else {
|
||||
rtiTool->show();
|
||||
}
|
||||
}
|
||||
|
||||
void RclMain::showUIPrefs()
|
||||
{
|
||||
if (uiprefs == 0) {
|
||||
uiprefs = new UIPrefsDialog(this);
|
||||
connect(new QShortcut(quitKeySeq, uiprefs), SIGNAL (activated()),
|
||||
this, SLOT (fileExit()));
|
||||
connect(uiprefs, SIGNAL(uiprefsDone()), this, SLOT(setUIPrefs()));
|
||||
connect(this, SIGNAL(stemLangChanged(const QString&)),
|
||||
uiprefs, SLOT(setStemLang(const QString&)));
|
||||
} else {
|
||||
// Close and reopen, in hope that makes us visible...
|
||||
uiprefs->close();
|
||||
rwSettings(false);
|
||||
uiprefs->setFromPrefs();
|
||||
}
|
||||
uiprefs->show();
|
||||
}
|
||||
|
||||
void RclMain::showExtIdxDialog()
|
||||
{
|
||||
showUIPrefs();
|
||||
uiprefs->tabWidget->setCurrentIndex(3);
|
||||
}
|
||||
|
||||
void RclMain::showAboutDialog()
|
||||
{
|
||||
string vstring = Rcl::version_string() +
|
||||
string("<br> http://www.recoll.org") +
|
||||
string("<br> http://www.xapian.org");
|
||||
QMessageBox::information(this, tr("About Recoll"), vstring.c_str());
|
||||
}
|
||||
|
||||
void RclMain::showMissingHelpers()
|
||||
{
|
||||
string miss;
|
||||
if (!theconfig->getMissingHelperDesc(miss)) {
|
||||
QMessageBox::information(this, "", tr("Indexing did not run yet"));
|
||||
return;
|
||||
}
|
||||
QString msg = QString::fromUtf8("<p>") +
|
||||
tr("External applications/commands needed for your file types "
|
||||
"and not found, as stored by the last indexing pass in ");
|
||||
msg += "<i>";
|
||||
msg += QString::fromLocal8Bit(theconfig->getConfDir().c_str());
|
||||
msg += "/missing</i>:<pre>\n";
|
||||
if (!miss.empty()) {
|
||||
msg += QString::fromUtf8(miss.c_str());
|
||||
} else {
|
||||
msg += tr("No helpers found missing");
|
||||
}
|
||||
msg += "</pre>";
|
||||
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;
|
||||
}
|
||||
|
||||
// All mime types in index.
|
||||
vector<string> vdbtypes;
|
||||
if (!rcldb->getAllDbMimeTypes(vdbtypes)) {
|
||||
QMessageBox::warning(0, tr("Error"),
|
||||
tr("Index query error"),
|
||||
QMessageBox::Ok,
|
||||
QMessageBox::NoButton);
|
||||
return;
|
||||
}
|
||||
set<string> mtypesfromdb;
|
||||
mtypesfromdb.insert(vdbtypes.begin(), vdbtypes.end());
|
||||
|
||||
// All types listed in mimeconf:
|
||||
vector<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 (vector<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;
|
||||
if (theconfig->getMissingHelperDesc(miss) && !miss.empty()) {
|
||||
FIMissingStore 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::fromUtf8(it->c_str()));
|
||||
}
|
||||
editor->moveCursor(QTextCursor::Start);
|
||||
editor->ensureCursorVisible();
|
||||
dialog.exec();
|
||||
}
|
||||
|
||||
void RclMain::newDupsW(const Rcl::Doc, const vector<Rcl::Doc> dups)
|
||||
{
|
||||
ListDialog dialog;
|
||||
dialog.setWindowTitle(tr("Duplicate documents"));
|
||||
|
||||
dialog.groupBox->setTitle(tr("These Urls ( | ipath) share the same"
|
||||
" content:"));
|
||||
// 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 (vector<Rcl::Doc>::const_iterator it = dups.begin();
|
||||
it != dups.end(); it++) {
|
||||
if (it->ipath.empty())
|
||||
editor->append(QString::fromLocal8Bit(it->url.c_str()));
|
||||
else
|
||||
editor->append(QString::fromLocal8Bit(it->url.c_str()) + " | " +
|
||||
QString::fromUtf8(it->ipath.c_str()));
|
||||
}
|
||||
editor->moveCursor(QTextCursor::Start);
|
||||
editor->ensureCursorVisible();
|
||||
dialog.exec();
|
||||
}
|
||||
|
||||
void RclMain::showSnippets(Rcl::Doc doc)
|
||||
{
|
||||
SnippetsW *sp = new SnippetsW(doc, m_source);
|
||||
connect(sp, SIGNAL(startNativeViewer(Rcl::Doc, int, QString)),
|
||||
this, SLOT(startNativeViewer(Rcl::Doc, int, QString)));
|
||||
connect(new QShortcut(quitKeySeq, sp), SIGNAL (activated()),
|
||||
this, SLOT (fileExit()));
|
||||
connect(new QShortcut(closeKeySeq, sp), SIGNAL (activated()),
|
||||
sp, SLOT (close()));
|
||||
sp->show();
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue