2006-03-05 17:24:44 +00:00
|
|
|
/**
|
2007-08-31 05:53:55 +00:00
|
|
|
* \file GuiSearch.cpp
|
2006-03-05 17:24:44 +00:00
|
|
|
* This file is part of LyX, the document processor.
|
|
|
|
* Licence details can be found in the file COPYING.
|
|
|
|
*
|
|
|
|
* \author John Levon
|
2007-04-24 13:27:23 +00:00
|
|
|
* \author Edwin Leuven
|
2007-10-06 20:54:31 +00:00
|
|
|
* \author Angus Leeming
|
2006-03-05 17:24:44 +00:00
|
|
|
*
|
|
|
|
* Full author contact details are available in file CREDITS.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
2020-10-25 00:47:13 +03:00
|
|
|
#include "GuiSearch.h"
|
|
|
|
|
2013-07-21 17:51:53 +01:00
|
|
|
#include "lyxfind.h"
|
2008-02-11 07:12:06 +00:00
|
|
|
#include "qt_helpers.h"
|
2007-10-06 20:54:31 +00:00
|
|
|
#include "FuncRequest.h"
|
2021-02-14 17:18:00 +01:00
|
|
|
#include "LyX.h"
|
2013-07-21 17:51:53 +01:00
|
|
|
#include "BufferView.h"
|
|
|
|
#include "Buffer.h"
|
|
|
|
#include "Cursor.h"
|
2021-02-12 10:50:47 +01:00
|
|
|
#include "FuncRequest.h"
|
|
|
|
#include "KeyMap.h"
|
|
|
|
#include "GuiKeySymbol.h"
|
2013-07-21 17:51:53 +01:00
|
|
|
#include "GuiView.h"
|
|
|
|
|
2021-02-14 17:18:00 +01:00
|
|
|
#include "support/debug.h"
|
2013-07-21 17:51:53 +01:00
|
|
|
#include "support/gettext.h"
|
|
|
|
#include "frontends/alert.h"
|
2007-10-06 20:54:31 +00:00
|
|
|
|
2008-02-11 07:12:06 +00:00
|
|
|
#include <QLineEdit>
|
2021-02-14 17:18:00 +01:00
|
|
|
#include <QSettings>
|
2007-12-09 22:35:04 +00:00
|
|
|
#include <QShowEvent>
|
2021-02-14 17:18:00 +01:00
|
|
|
#include "QSizePolicy"
|
2006-03-05 17:24:44 +00:00
|
|
|
|
2007-12-12 10:16:00 +00:00
|
|
|
using namespace std;
|
2007-09-05 20:33:29 +00:00
|
|
|
|
2021-02-12 10:50:47 +01:00
|
|
|
using lyx::KeySymbol;
|
|
|
|
|
2006-03-05 17:24:44 +00:00
|
|
|
namespace lyx {
|
|
|
|
namespace frontend {
|
|
|
|
|
2007-04-24 13:27:23 +00:00
|
|
|
static void uniqueInsert(QComboBox * box, QString const & text)
|
|
|
|
{
|
2007-10-09 21:21:01 +00:00
|
|
|
for (int i = box->count(); --i >= 0; )
|
2007-04-24 13:27:23 +00:00
|
|
|
if (box->itemText(i) == text)
|
|
|
|
return;
|
|
|
|
|
2008-09-09 13:20:44 +00:00
|
|
|
box->insertItem(0, text);
|
2007-04-24 13:27:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-02-14 17:18:00 +01:00
|
|
|
GuiSearchWidget::GuiSearchWidget(QWidget * parent)
|
|
|
|
: QWidget(parent)
|
2007-04-24 13:27:23 +00:00
|
|
|
{
|
|
|
|
setupUi(this);
|
|
|
|
|
2018-12-24 14:47:48 +01:00
|
|
|
// fix height to minimum
|
|
|
|
setFixedHeight(sizeHint().height());
|
|
|
|
|
2018-12-25 18:20:02 +01:00
|
|
|
// align items in grid on top
|
2021-02-14 17:18:00 +01:00
|
|
|
gridLayout->setAlignment(Qt::AlignTop);
|
2018-12-25 18:20:02 +01:00
|
|
|
|
2007-08-12 12:44:42 +00:00
|
|
|
connect(findPB, SIGNAL(clicked()), this, SLOT(findClicked()));
|
2021-02-14 17:18:00 +01:00
|
|
|
connect(findPrevPB, SIGNAL(clicked()), this, SLOT(findPrevClicked()));
|
|
|
|
connect(minimizePB, SIGNAL(clicked()), this, SLOT(minimizeClicked()));
|
2007-08-12 12:44:42 +00:00
|
|
|
connect(replacePB, SIGNAL(clicked()), this, SLOT(replaceClicked()));
|
2021-02-14 17:18:00 +01:00
|
|
|
connect(replacePrevPB, SIGNAL(clicked()), this, SLOT(replacePrevClicked()));
|
2007-08-12 12:44:42 +00:00
|
|
|
connect(replaceallPB, SIGNAL(clicked()), this, SLOT(replaceallClicked()));
|
2007-10-09 19:34:27 +00:00
|
|
|
connect(findCO, SIGNAL(editTextChanged(QString)),
|
2007-04-24 13:27:23 +00:00
|
|
|
this, SLOT(findChanged()));
|
|
|
|
|
|
|
|
setFocusProxy(findCO);
|
2007-09-05 20:33:29 +00:00
|
|
|
|
2020-03-18 21:00:09 -04:00
|
|
|
findCO->setCompleter(0);
|
|
|
|
replaceCO->setCompleter(0);
|
|
|
|
|
2007-09-05 20:33:29 +00:00
|
|
|
replacePB->setEnabled(false);
|
2021-02-14 17:18:00 +01:00
|
|
|
replacePrevPB->setEnabled(false);
|
2007-09-05 20:33:29 +00:00
|
|
|
replaceallPB->setEnabled(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-02-14 17:18:00 +01:00
|
|
|
void GuiSearchWidget::keyPressEvent(QKeyEvent * ev)
|
2021-02-12 10:50:47 +01:00
|
|
|
{
|
|
|
|
KeySymbol sym;
|
|
|
|
setKeySymbol(&sym, ev);
|
|
|
|
|
2021-02-14 17:18:00 +01:00
|
|
|
// catch Return and Shift-Return
|
|
|
|
if (ev->key() == Qt::Key_Return) {
|
|
|
|
findClicked(ev->modifiers() == Qt::ShiftModifier);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-02-12 10:50:47 +01:00
|
|
|
// we catch the key sequences for forward and backwards search
|
|
|
|
if (sym.isOK()) {
|
|
|
|
KeyModifier mod = lyx::q_key_state(ev->modifiers());
|
|
|
|
KeySequence keyseq(&theTopLevelKeymap(), &theTopLevelKeymap());
|
|
|
|
FuncRequest fr = keyseq.addkey(sym, mod);
|
|
|
|
if (fr == FuncRequest(LFUN_WORD_FIND_FORWARD) || fr == FuncRequest(LFUN_WORD_FIND)) {
|
|
|
|
findClicked();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (fr == FuncRequest(LFUN_WORD_FIND_BACKWARD)) {
|
|
|
|
findClicked(true);
|
|
|
|
return;
|
|
|
|
}
|
2021-02-14 17:18:00 +01:00
|
|
|
if (fr == FuncRequest(LFUN_DIALOG_TOGGLE, "findreplace")) {
|
|
|
|
dispatch(fr);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
QWidget::keyPressEvent(ev);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GuiSearchWidget::minimizeClicked(bool const toggle)
|
|
|
|
{
|
|
|
|
if (toggle)
|
|
|
|
minimized_ = !minimized_;
|
|
|
|
|
|
|
|
replaceLA->setHidden(minimized_);
|
|
|
|
replaceCO->setHidden(minimized_);
|
|
|
|
replacePB->setHidden(minimized_);
|
|
|
|
replacePrevPB->setHidden(minimized_);
|
|
|
|
replaceallPB->setHidden(minimized_);
|
2021-02-14 11:34:49 -05:00
|
|
|
CBGroupBox->setHidden(minimized_);
|
2021-02-14 17:18:00 +01:00
|
|
|
if (minimized_) {
|
|
|
|
minimizePB->setText(qt_("Ex&pand"));
|
|
|
|
minimizePB->setToolTip("Show replace and option widgets");
|
|
|
|
} else {
|
|
|
|
minimizePB->setText(qt_("&Minimize"));
|
|
|
|
minimizePB->setToolTip("Hide replace and option widgets");
|
2021-02-12 10:50:47 +01:00
|
|
|
}
|
2021-02-14 17:18:00 +01:00
|
|
|
|
|
|
|
Q_EMIT needSizeUpdate();
|
|
|
|
Q_EMIT needTitleBarUpdate();
|
2021-02-12 10:50:47 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-02-14 17:18:00 +01:00
|
|
|
void GuiSearchWidget::showEvent(QShowEvent * e)
|
2007-04-24 13:27:23 +00:00
|
|
|
{
|
2020-12-03 15:31:35 +01:00
|
|
|
findChanged();
|
2008-03-12 16:17:25 +00:00
|
|
|
findPB->setFocus();
|
2007-10-30 13:16:45 +00:00
|
|
|
findCO->lineEdit()->selectAll();
|
2021-02-14 17:18:00 +01:00
|
|
|
QWidget::showEvent(e);
|
2007-04-24 13:27:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-02-14 17:18:00 +01:00
|
|
|
void GuiSearchWidget::findChanged()
|
2007-04-24 13:27:23 +00:00
|
|
|
{
|
2020-12-14 14:19:08 +01:00
|
|
|
findPB->setEnabled(!findCO->currentText().isEmpty());
|
2021-02-14 17:18:00 +01:00
|
|
|
findPrevPB->setEnabled(!findCO->currentText().isEmpty());
|
|
|
|
bool const replace = !findCO->currentText().isEmpty()
|
|
|
|
&& bv_ && !bv_->buffer().isReadonly();
|
2020-12-03 15:31:35 +01:00
|
|
|
replacePB->setEnabled(replace);
|
2021-02-14 17:18:00 +01:00
|
|
|
replacePrevPB->setEnabled(replace);
|
2020-12-03 15:31:35 +01:00
|
|
|
replaceallPB->setEnabled(replace);
|
|
|
|
replaceLA->setEnabled(replace);
|
|
|
|
replaceCO->setEnabled(replace);
|
2007-04-24 13:27:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-02-14 17:18:00 +01:00
|
|
|
void GuiSearchWidget::findClicked(bool const backwards)
|
2007-04-24 13:27:23 +00:00
|
|
|
{
|
2007-09-05 20:33:29 +00:00
|
|
|
docstring const needle = qstring_to_ucs4(findCO->currentText());
|
2021-02-14 17:18:00 +01:00
|
|
|
find(needle, caseCB->isChecked(), wordsCB->isChecked(), !backwards);
|
2007-04-24 13:27:23 +00:00
|
|
|
uniqueInsert(findCO, findCO->currentText());
|
2007-10-30 13:16:45 +00:00
|
|
|
findCO->lineEdit()->selectAll();
|
2007-04-24 13:27:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-02-14 17:18:00 +01:00
|
|
|
void GuiSearchWidget::findPrevClicked()
|
|
|
|
{
|
|
|
|
findClicked(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GuiSearchWidget::replaceClicked(bool const backwards)
|
2007-04-24 13:27:23 +00:00
|
|
|
{
|
2007-09-05 20:33:29 +00:00
|
|
|
docstring const needle = qstring_to_ucs4(findCO->currentText());
|
|
|
|
docstring const repl = qstring_to_ucs4(replaceCO->currentText());
|
|
|
|
replace(needle, repl, caseCB->isChecked(), wordsCB->isChecked(),
|
2021-02-14 17:18:00 +01:00
|
|
|
!backwards, false);
|
2007-04-24 13:27:23 +00:00
|
|
|
uniqueInsert(findCO, findCO->currentText());
|
|
|
|
uniqueInsert(replaceCO, replaceCO->currentText());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-02-14 17:18:00 +01:00
|
|
|
void GuiSearchWidget::replacePrevClicked()
|
|
|
|
{
|
|
|
|
replaceClicked(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GuiSearchWidget::replaceallClicked()
|
2007-04-24 13:27:23 +00:00
|
|
|
{
|
2007-09-05 20:33:29 +00:00
|
|
|
replace(qstring_to_ucs4(findCO->currentText()),
|
2007-04-24 13:27:23 +00:00
|
|
|
qstring_to_ucs4(replaceCO->currentText()),
|
2007-10-06 20:54:31 +00:00
|
|
|
caseCB->isChecked(), wordsCB->isChecked(), true, true);
|
2007-04-24 13:27:23 +00:00
|
|
|
uniqueInsert(findCO, findCO->currentText());
|
|
|
|
uniqueInsert(replaceCO, replaceCO->currentText());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-02-14 17:18:00 +01:00
|
|
|
void GuiSearchWidget::find(docstring const & search, bool casesensitive,
|
2007-10-06 20:54:31 +00:00
|
|
|
bool matchword, bool forward)
|
2006-03-05 17:24:44 +00:00
|
|
|
{
|
2018-02-24 01:01:34 -05:00
|
|
|
docstring const sdata =
|
2007-10-09 21:21:01 +00:00
|
|
|
find2string(search, casesensitive, matchword, forward);
|
2018-02-24 01:01:34 -05:00
|
|
|
dispatch(FuncRequest(LFUN_WORD_FIND, sdata));
|
2006-03-05 17:24:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-02-14 17:18:00 +01:00
|
|
|
void GuiSearchWidget::replace(docstring const & search, docstring const & replace,
|
2007-10-06 20:54:31 +00:00
|
|
|
bool casesensitive, bool matchword,
|
|
|
|
bool forward, bool all)
|
2006-03-05 17:24:44 +00:00
|
|
|
{
|
2018-02-24 01:01:34 -05:00
|
|
|
docstring const sdata =
|
2009-07-04 23:02:27 +00:00
|
|
|
replace2string(replace, search, casesensitive,
|
2007-10-06 20:54:31 +00:00
|
|
|
matchword, all, forward);
|
2018-02-24 01:01:34 -05:00
|
|
|
dispatch(FuncRequest(LFUN_WORD_REPLACE, sdata));
|
2006-03-05 17:24:44 +00:00
|
|
|
}
|
|
|
|
|
2021-02-14 17:18:00 +01:00
|
|
|
void GuiSearchWidget::saveSession(QSettings & settings, QString const & session_key) const
|
|
|
|
{
|
|
|
|
settings.setValue(session_key + "/casesensitive", caseCB->isChecked());
|
|
|
|
settings.setValue(session_key + "/words", wordsCB->isChecked());
|
|
|
|
settings.setValue(session_key + "/minimized", minimized_);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GuiSearchWidget::restoreSession(QString const & session_key)
|
|
|
|
{
|
|
|
|
QSettings settings;
|
|
|
|
caseCB->setChecked(settings.value(session_key + "/casesensitive", false).toBool());
|
|
|
|
wordsCB->setChecked(settings.value(session_key + "/words", false).toBool());
|
|
|
|
minimized_ = settings.value(session_key + "/minimized", false).toBool();
|
|
|
|
// initialize hidings
|
|
|
|
minimizeClicked(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
GuiSearch::GuiSearch(GuiView & parent, Qt::DockWidgetArea area, Qt::WindowFlags flags)
|
|
|
|
: DockView(parent, "findreplace", qt_("Search and Replace"), area, flags),
|
|
|
|
widget_(new GuiSearchWidget(this))
|
|
|
|
{
|
|
|
|
setWidget(widget_);
|
|
|
|
widget_->setBufferView(bufferview());
|
|
|
|
setFocusProxy(widget_->findCO);
|
|
|
|
|
|
|
|
connect(widget_, SIGNAL(needTitleBarUpdate()), this, SLOT(updateTitle()));
|
|
|
|
connect(widget_, SIGNAL(needSizeUpdate()), this, SLOT(updateSize()));
|
|
|
|
}
|
|
|
|
|
|
|
|
void GuiSearch::onBufferViewChanged()
|
|
|
|
{
|
|
|
|
widget_->setEnabled((bool)bufferview());
|
|
|
|
widget_->setBufferView(bufferview());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GuiSearch::updateView()
|
|
|
|
{
|
|
|
|
updateTitle();
|
|
|
|
updateSize();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GuiSearch::saveSession(QSettings & settings) const
|
|
|
|
{
|
|
|
|
Dialog::saveSession(settings);
|
|
|
|
widget_->saveSession(settings, sessionKey());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GuiSearch::restoreSession()
|
|
|
|
{
|
|
|
|
DockView::restoreSession();
|
|
|
|
widget_->restoreSession(sessionKey());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GuiSearch::updateTitle()
|
|
|
|
{
|
|
|
|
if (widget_->isMinimized()) {
|
|
|
|
// remove title bar
|
|
|
|
setTitleBarWidget(new QWidget());
|
|
|
|
titleBarWidget()->hide();
|
|
|
|
} else
|
|
|
|
// restore title bar
|
|
|
|
setTitleBarWidget(nullptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GuiSearch::updateSize()
|
|
|
|
{
|
|
|
|
widget_->setFixedHeight(widget_->sizeHint().height());
|
|
|
|
if (widget_->isMinimized())
|
|
|
|
// FIXME still a bit too tall
|
|
|
|
setFixedHeight(widget_->sizeHint().height());
|
|
|
|
else {
|
|
|
|
// undo setFixedHeight
|
|
|
|
setMaximumHeight(QWIDGETSIZE_MAX);
|
|
|
|
setMinimumHeight(0);
|
|
|
|
}
|
|
|
|
update();
|
|
|
|
}
|
|
|
|
|
2013-07-21 17:51:53 +01:00
|
|
|
|
2006-03-05 17:24:44 +00:00
|
|
|
} // namespace frontend
|
|
|
|
} // namespace lyx
|
2007-04-24 13:27:23 +00:00
|
|
|
|
|
|
|
|
2008-11-14 14:28:50 +00:00
|
|
|
#include "moc_GuiSearch.cpp"
|