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>
|
|
|
|
|
2021-02-14 18:56:25 +01:00
|
|
|
#include "GuiApplication.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-28 12:35:29 +01:00
|
|
|
#include "qt_helpers.h"
|
|
|
|
#include "support/filetools.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"
|
2021-02-28 12:35:29 +01:00
|
|
|
#include "support/FileName.h"
|
2013-07-21 17:51:53 +01:00
|
|
|
#include "frontends/alert.h"
|
2021-02-14 18:56:25 +01:00
|
|
|
#include "frontends/Clipboard.h"
|
2007-10-06 20:54:31 +00:00
|
|
|
|
2021-02-14 18:56:25 +01:00
|
|
|
#include <QClipboard>
|
2021-02-18 07:33:26 +01:00
|
|
|
#include <QPainter>
|
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"
|
2021-02-28 12:35:29 +01:00
|
|
|
#if QT_VERSION >= 0x050000
|
|
|
|
#include <QSvgRenderer>
|
|
|
|
#endif
|
2006-03-05 17:24:44 +00:00
|
|
|
|
2007-12-12 10:16:00 +00:00
|
|
|
using namespace std;
|
2021-02-28 12:35:29 +01:00
|
|
|
using namespace lyx::support;
|
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()));
|
2021-02-14 18:56:25 +01:00
|
|
|
if(qApp->clipboard()->supportsFindBuffer()) {
|
|
|
|
connect(qApp->clipboard(), SIGNAL(findBufferChanged()),
|
|
|
|
this, SLOT(findBufferChanged()));
|
|
|
|
findBufferChanged();
|
|
|
|
}
|
2007-04-24 13:27:23 +00:00
|
|
|
|
|
|
|
setFocusProxy(findCO);
|
2007-09-05 20:33:29 +00:00
|
|
|
|
2021-02-18 07:33:26 +01:00
|
|
|
// Use a FancyLineEdit due to the indicator icons
|
|
|
|
findLE_ = new FancyLineEdit(this);
|
|
|
|
findCO->setLineEdit(findLE_);
|
|
|
|
|
|
|
|
// And a menu in minimal mode
|
|
|
|
menu_ = new QMenu();
|
|
|
|
act_casesense_ = new QAction(qt_("&Case sensitive[[search]]"), this);
|
|
|
|
act_casesense_->setCheckable(true);
|
|
|
|
act_wholewords_ = new QAction(qt_("Wh&ole words"), this);
|
|
|
|
act_wholewords_->setCheckable(true);
|
|
|
|
act_selection_ = new QAction(qt_("Selection onl&y"), this);
|
|
|
|
act_selection_->setCheckable(true);
|
|
|
|
act_immediate_ = new QAction(qt_("Search as yo&u type"), this);
|
|
|
|
act_immediate_->setCheckable(true);
|
|
|
|
act_wrap_ = new QAction(qt_("&Wrap"), this);
|
|
|
|
act_wrap_->setCheckable(true);
|
|
|
|
|
|
|
|
menu_->addAction(act_casesense_);
|
|
|
|
menu_->addAction(act_wholewords_);
|
|
|
|
menu_->addAction(act_selection_);
|
|
|
|
menu_->addAction(act_immediate_);
|
|
|
|
menu_->addAction(act_wrap_);
|
|
|
|
findLE_->setButtonMenu(FancyLineEdit::Right, menu_);
|
|
|
|
|
|
|
|
connect(act_casesense_, SIGNAL(triggered()), this, SLOT(caseSenseActTriggered()));
|
|
|
|
connect(act_wholewords_, SIGNAL(triggered()), this, SLOT(wholeWordsActTriggered()));
|
|
|
|
connect(act_selection_, SIGNAL(triggered()), this, SLOT(searchSelActTriggered()));
|
|
|
|
connect(act_immediate_, SIGNAL(triggered()), this, SLOT(immediateActTriggered()));
|
|
|
|
connect(act_wrap_, SIGNAL(triggered()), this, SLOT(wrapActTriggered()));
|
|
|
|
|
2021-02-14 12:05:40 -05:00
|
|
|
findCO->setCompleter(nullptr);
|
|
|
|
replaceCO->setCompleter(nullptr);
|
2020-03-18 21:00:09 -04:00
|
|
|
|
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-15 16:04:17 +01:00
|
|
|
bool GuiSearchWidget::initialiseParams(std::string const & str)
|
|
|
|
{
|
|
|
|
if (!str.empty())
|
|
|
|
findCO->lineEdit()->setText(toqstr(str));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
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
|
2021-02-16 08:52:21 +01:00
|
|
|
if (ev->key() == Qt::Key_Return || ev->key() == Qt::Key_Enter) {
|
2021-02-17 14:48:31 +01:00
|
|
|
doFind(ev->modifiers() == Qt::ShiftModifier);
|
2021-02-14 17:18:00 +01:00
|
|
|
return;
|
|
|
|
}
|
2021-02-15 15:37:13 +01:00
|
|
|
if (ev->key() == Qt::Key_Escape) {
|
2021-02-16 13:30:31 +01:00
|
|
|
dispatch(FuncRequest(LFUN_DIALOG_HIDE, "findreplace"));
|
2021-02-15 15:37:13 +01:00
|
|
|
return;
|
|
|
|
}
|
2021-02-14 17:18:00 +01:00
|
|
|
|
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);
|
2021-02-17 14:48:31 +01:00
|
|
|
if (fr == FuncRequest(LFUN_WORD_FIND_FORWARD)
|
|
|
|
|| fr == FuncRequest(LFUN_WORD_FIND)) {
|
|
|
|
doFind();
|
2021-02-12 10:50:47 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (fr == FuncRequest(LFUN_WORD_FIND_BACKWARD)) {
|
2021-02-17 14:48:31 +01:00
|
|
|
doFind(true);
|
2021-02-12 10:50:47 +01:00
|
|
|
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 18:12:38 +01:00
|
|
|
CBFrame->setHidden(minimized_);
|
2021-02-18 07:33:26 +01:00
|
|
|
|
2021-02-14 17:18:00 +01:00
|
|
|
if (minimized_) {
|
|
|
|
minimizePB->setText(qt_("Ex&pand"));
|
2021-02-15 08:42:15 +01:00
|
|
|
minimizePB->setToolTip(qt_("Show replace and option widgets"));
|
2021-02-18 07:33:26 +01:00
|
|
|
// update menu items
|
|
|
|
blockSignals(true);
|
|
|
|
act_casesense_->setChecked(caseCB->isChecked());
|
|
|
|
act_immediate_->setChecked(instantSearchCB->isChecked());
|
|
|
|
act_selection_->setChecked(selectionCB->isChecked());
|
|
|
|
act_wholewords_->setChecked(wordsCB->isChecked());
|
|
|
|
act_wrap_->setChecked(wrapCB->isChecked());
|
|
|
|
blockSignals(false);
|
2021-02-14 17:18:00 +01:00
|
|
|
} else {
|
|
|
|
minimizePB->setText(qt_("&Minimize"));
|
2021-02-15 08:42:15 +01:00
|
|
|
minimizePB->setToolTip(qt_("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-18 07:33:26 +01:00
|
|
|
handleIndicators();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GuiSearchWidget::handleIndicators()
|
|
|
|
{
|
|
|
|
findLE_->setButtonVisible(FancyLineEdit::Right, minimized_);
|
|
|
|
|
|
|
|
QString tip;
|
|
|
|
|
|
|
|
if (minimized_) {
|
|
|
|
int pms = 0;
|
|
|
|
if (caseCB->isChecked())
|
|
|
|
++pms;
|
|
|
|
if (wordsCB->isChecked())
|
|
|
|
++pms;
|
|
|
|
if (selectionCB->isChecked())
|
|
|
|
++pms;
|
|
|
|
if (instantSearchCB->isChecked())
|
|
|
|
++pms;
|
|
|
|
if (wrapCB->isChecked())
|
|
|
|
++pms;
|
|
|
|
|
2021-02-28 12:35:29 +01:00
|
|
|
bool const dark_mode = guiApp && guiApp->isInDarkMode();
|
|
|
|
qreal dpr = 1.0;
|
|
|
|
#if QT_VERSION >= 0x050000
|
|
|
|
// Consider device/pixel ratio (HiDPI)
|
|
|
|
if (guiApp && guiApp->currentView())
|
|
|
|
dpr = guiApp->currentView()->devicePixelRatio();
|
|
|
|
#endif
|
|
|
|
QString imagedir = "images/";
|
2021-02-18 07:33:26 +01:00
|
|
|
QPixmap bpixmap = getPixmap("images/", "search-options", "svgz,png");
|
2021-02-28 12:35:29 +01:00
|
|
|
QPixmap pm = bpixmap;
|
2021-02-18 07:33:26 +01:00
|
|
|
|
|
|
|
if (pms > 0) {
|
|
|
|
int const gap = 3;
|
2021-02-28 12:35:29 +01:00
|
|
|
QPixmap scaled_pm = QPixmap(bpixmap.size() * dpr);
|
|
|
|
pm = QPixmap(pms * scaled_pm.width() + ((pms - 1) * gap),
|
|
|
|
scaled_pm.height());
|
|
|
|
pm.fill(Qt::transparent);
|
|
|
|
QPainter painter(&pm);
|
2021-02-18 07:33:26 +01:00
|
|
|
int x = 0;
|
|
|
|
|
|
|
|
tip = qt_("Active options:");
|
|
|
|
tip += "<ul>";
|
|
|
|
if (caseCB->isChecked()) {
|
|
|
|
tip += "<li>" + qt_("Case sensitive search");
|
|
|
|
QPixmap spixmap = getPixmap("images/", "search-case-sensitive", "svgz,png");
|
2021-02-28 12:35:29 +01:00
|
|
|
#if QT_VERSION < 0x050000
|
2021-02-18 07:33:26 +01:00
|
|
|
painter.drawPixmap(x, 0, spixmap);
|
2021-02-28 12:35:29 +01:00
|
|
|
#else
|
|
|
|
// With Qt5, we render SVG directly for HiDPI scalability
|
|
|
|
FileName fname = imageLibFileSearch(imagedir, "search-case-sensitive", "svgz,png");
|
|
|
|
QString fpath = toqstr(fname.absFileName());
|
|
|
|
if (!fpath.isEmpty()) {
|
|
|
|
QSvgRenderer svgRenderer(fpath);
|
|
|
|
if (svgRenderer.isValid())
|
|
|
|
svgRenderer.render(&painter, QRectF(0, 0, spixmap.width() * dpr,
|
|
|
|
spixmap.height() * dpr));
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
x += (spixmap.width() * dpr) + gap;
|
2021-02-18 07:33:26 +01:00
|
|
|
}
|
|
|
|
if (wordsCB->isChecked()) {
|
|
|
|
tip += "<li>" + qt_("Whole words only");
|
|
|
|
QPixmap spixmap = getPixmap("images/", "search-whole-words", "svgz,png");
|
2021-02-28 12:35:29 +01:00
|
|
|
#if QT_VERSION < 0x050000
|
2021-02-18 07:33:26 +01:00
|
|
|
painter.drawPixmap(x, 0, spixmap);
|
2021-02-28 12:35:29 +01:00
|
|
|
#else
|
|
|
|
FileName fname = imageLibFileSearch(imagedir, "search-whole-words", "svgz,png");
|
|
|
|
QString fpath = toqstr(fname.absFileName());
|
|
|
|
if (!fpath.isEmpty()) {
|
|
|
|
QSvgRenderer svgRenderer(fpath);
|
|
|
|
if (svgRenderer.isValid())
|
|
|
|
svgRenderer.render(&painter, QRectF(x, 0, spixmap.width() * dpr,
|
|
|
|
spixmap.height() * dpr));
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
x += (spixmap.width() * dpr) + gap;
|
2021-02-18 07:33:26 +01:00
|
|
|
}
|
|
|
|
if (selectionCB->isChecked()) {
|
|
|
|
tip += "<li>" + qt_("Search only in selection");
|
|
|
|
QPixmap spixmap = getPixmap("images/", "search-selection", "svgz,png");
|
2021-02-28 12:35:29 +01:00
|
|
|
#if QT_VERSION < 0x050000
|
2021-02-18 07:33:26 +01:00
|
|
|
painter.drawPixmap(x, 0, spixmap);
|
2021-02-28 12:35:29 +01:00
|
|
|
#else
|
|
|
|
FileName fname = imageLibFileSearch(imagedir, "search-selection", "svgz,png");
|
|
|
|
QString fpath = toqstr(fname.absFileName());
|
|
|
|
if (!fpath.isEmpty()) {
|
|
|
|
QSvgRenderer svgRenderer(fpath);
|
|
|
|
if (svgRenderer.isValid())
|
|
|
|
svgRenderer.render(&painter, QRectF(x, 0, spixmap.width() * dpr,
|
|
|
|
spixmap.height() * dpr));
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
x += (spixmap.width() * dpr) + gap;
|
2021-02-18 07:33:26 +01:00
|
|
|
}
|
|
|
|
if (instantSearchCB->isChecked()) {
|
|
|
|
tip += "<li>" + qt_("Search as you type");
|
|
|
|
QPixmap spixmap = getPixmap("images/", "search-instant", "svgz,png");
|
2021-02-28 12:35:29 +01:00
|
|
|
#if QT_VERSION < 0x050000
|
2021-02-18 07:33:26 +01:00
|
|
|
painter.drawPixmap(x, 0, spixmap);
|
2021-02-28 12:35:29 +01:00
|
|
|
#else
|
|
|
|
FileName fname = imageLibFileSearch(imagedir, "search-instant", "svgz,png");
|
|
|
|
QString fpath = toqstr(fname.absFileName());
|
|
|
|
if (!fpath.isEmpty()) {
|
|
|
|
QSvgRenderer svgRenderer(fpath);
|
|
|
|
if (svgRenderer.isValid())
|
|
|
|
svgRenderer.render(&painter, QRectF(x, 0, spixmap.width() * dpr,
|
|
|
|
spixmap.height() * dpr));
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
x += (spixmap.width() * dpr) + gap;
|
2021-02-18 07:33:26 +01:00
|
|
|
}
|
|
|
|
if (wrapCB->isChecked()) {
|
|
|
|
tip += "<li>" + qt_("Wrap search");
|
|
|
|
QPixmap spixmap = getPixmap("images/", "search-wrap", "svgz,png");
|
2021-02-28 12:35:29 +01:00
|
|
|
#if QT_VERSION < 0x050000
|
2021-02-18 07:33:26 +01:00
|
|
|
painter.drawPixmap(x, 0, spixmap);
|
2021-02-28 12:35:29 +01:00
|
|
|
#else
|
|
|
|
FileName fname = imageLibFileSearch(imagedir, "search-wrap", "svgz,png");
|
|
|
|
QString fpath = toqstr(fname.absFileName());
|
|
|
|
if (!fpath.isEmpty()) {
|
|
|
|
QSvgRenderer svgRenderer(fpath);
|
|
|
|
if (svgRenderer.isValid())
|
|
|
|
svgRenderer.render(&painter, QRectF(x, 0, spixmap.width() * dpr,
|
|
|
|
spixmap.height() * dpr));
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
x += (spixmap.width() * dpr) + gap;
|
2021-02-18 07:33:26 +01:00
|
|
|
}
|
|
|
|
tip += "</ul>";
|
2021-02-28 12:35:29 +01:00
|
|
|
#if QT_VERSION >= 0x050000
|
|
|
|
pm.setDevicePixelRatio(dpr);
|
|
|
|
#endif
|
2021-02-18 15:44:27 +01:00
|
|
|
painter.end();
|
2021-02-18 07:33:26 +01:00
|
|
|
} else {
|
|
|
|
tip = qt_("Click here to change search options");
|
2021-02-28 12:35:29 +01:00
|
|
|
#if QT_VERSION >= 0x050000
|
|
|
|
// With Qt5, we render SVG directly for HiDPI scalability
|
|
|
|
FileName fname = imageLibFileSearch(imagedir, "search-options", "svgz,png");
|
|
|
|
QString fpath = toqstr(fname.absFileName());
|
|
|
|
if (!fpath.isEmpty()) {
|
|
|
|
QSvgRenderer svgRenderer(fpath);
|
|
|
|
if (svgRenderer.isValid()) {
|
|
|
|
pm = QPixmap(bpixmap.size() * dpr);
|
|
|
|
pm.fill(Qt::transparent);
|
|
|
|
QPainter painter(&pm);
|
|
|
|
svgRenderer.render(&painter);
|
|
|
|
pm.setDevicePixelRatio(dpr);
|
|
|
|
}
|
2021-02-18 15:44:27 +01:00
|
|
|
}
|
2021-02-28 12:35:29 +01:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
if (dark_mode) {
|
|
|
|
QImage img = pm.toImage();
|
|
|
|
img.invertPixels();
|
|
|
|
pm.convertFromImage(img);
|
2021-02-18 07:33:26 +01:00
|
|
|
}
|
2021-02-28 12:35:29 +01:00
|
|
|
findLE_->setButtonPixmap(FancyLineEdit::Right, pm);
|
2021-02-18 07:33:26 +01:00
|
|
|
}
|
|
|
|
findLE_->setButtonToolTip(FancyLineEdit::Right, tip);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GuiSearchWidget::caseSenseActTriggered()
|
|
|
|
{
|
|
|
|
caseCB->setChecked(act_casesense_->isChecked());
|
|
|
|
handleIndicators();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GuiSearchWidget::wholeWordsActTriggered()
|
|
|
|
{
|
|
|
|
wordsCB->setChecked(act_wholewords_->isChecked());
|
|
|
|
handleIndicators();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GuiSearchWidget::searchSelActTriggered()
|
|
|
|
{
|
|
|
|
selectionCB->setChecked(act_selection_->isChecked());
|
|
|
|
handleIndicators();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GuiSearchWidget::immediateActTriggered()
|
|
|
|
{
|
|
|
|
instantSearchCB->setChecked(act_immediate_->isChecked());
|
|
|
|
handleIndicators();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GuiSearchWidget::wrapActTriggered()
|
|
|
|
{
|
|
|
|
wrapCB->setChecked(act_wrap_->isChecked());
|
|
|
|
handleIndicators();
|
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 18:56:25 +01:00
|
|
|
void GuiSearchWidget::findBufferChanged()
|
|
|
|
{
|
|
|
|
docstring search = theClipboard().getFindBuffer();
|
2021-02-28 17:38:01 +01:00
|
|
|
// update from find buffer, but only if the strings differ (else we
|
2021-02-28 17:34:42 +01:00
|
|
|
// might end up in loops with search as you type)
|
|
|
|
if (!search.empty() && toqstr(search) != findCO->lineEdit()->text()) {
|
2021-02-14 18:56:25 +01:00
|
|
|
LYXERR(Debug::CLIPBOARD, "from findbuffer: " << search);
|
2021-02-18 08:05:15 +01:00
|
|
|
findCO->lineEdit()->selectAll();
|
|
|
|
findCO->lineEdit()->insert(toqstr(search));
|
2021-02-18 15:55:05 +01:00
|
|
|
findCO->lineEdit()->selectAll();
|
2021-02-14 18:56:25 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-02-14 17:18:00 +01:00
|
|
|
void GuiSearchWidget::findChanged()
|
2007-04-24 13:27:23 +00:00
|
|
|
{
|
2021-02-15 10:53:23 +01:00
|
|
|
bool const emptytext = findCO->currentText().isEmpty();
|
|
|
|
findPB->setEnabled(!emptytext);
|
|
|
|
findPrevPB->setEnabled(!emptytext);
|
|
|
|
bool const replace = !emptytext && 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);
|
2021-02-17 16:55:55 +01:00
|
|
|
if (instantSearchCB->isChecked())
|
2021-02-17 14:48:31 +01:00
|
|
|
doFind(false, true);
|
2007-04-24 13:27:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-02-17 14:48:31 +01:00
|
|
|
void GuiSearchWidget::findClicked()
|
2007-04-24 13:27:23 +00:00
|
|
|
{
|
2021-02-17 14:48:31 +01:00
|
|
|
doFind();
|
2007-04-24 13:27:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-02-14 17:18:00 +01:00
|
|
|
void GuiSearchWidget::findPrevClicked()
|
|
|
|
{
|
2021-02-17 14:48:31 +01:00
|
|
|
doFind(true);
|
2021-02-14 17:18:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-02-17 14:48:31 +01:00
|
|
|
void GuiSearchWidget::replaceClicked()
|
2007-04-24 13:27:23 +00:00
|
|
|
{
|
2021-02-17 14:48:31 +01:00
|
|
|
doReplace();
|
2007-04-24 13:27:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-02-14 17:18:00 +01:00
|
|
|
void GuiSearchWidget::replacePrevClicked()
|
|
|
|
{
|
2021-02-17 14:48:31 +01:00
|
|
|
doReplace(true);
|
2021-02-14 17:18:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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()),
|
2021-02-16 08:11:09 +01:00
|
|
|
caseCB->isChecked(), wordsCB->isChecked(),
|
|
|
|
true, true, true, selectionCB->isChecked());
|
2007-04-24 13:27:23 +00:00
|
|
|
uniqueInsert(findCO, findCO->currentText());
|
|
|
|
uniqueInsert(replaceCO, replaceCO->currentText());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-02-17 14:48:31 +01:00
|
|
|
void GuiSearchWidget::doFind(bool const backwards, bool const instant)
|
|
|
|
{
|
|
|
|
docstring const needle = qstring_to_ucs4(findCO->currentText());
|
|
|
|
find(needle, caseCB->isChecked(), wordsCB->isChecked(), !backwards,
|
|
|
|
instant, wrapCB->isChecked(), selectionCB->isChecked());
|
|
|
|
uniqueInsert(findCO, findCO->currentText());
|
|
|
|
if (!instant)
|
|
|
|
findCO->lineEdit()->selectAll();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-02-14 17:18:00 +01:00
|
|
|
void GuiSearchWidget::find(docstring const & search, bool casesensitive,
|
2021-02-17 14:48:31 +01:00
|
|
|
bool matchword, bool forward, bool instant,
|
|
|
|
bool wrap, bool onlysel)
|
2006-03-05 17:24:44 +00:00
|
|
|
{
|
2018-02-24 01:01:34 -05:00
|
|
|
docstring const sdata =
|
2021-02-15 14:12:07 +01:00
|
|
|
find2string(search, casesensitive, matchword,
|
2021-02-16 08:11:09 +01:00
|
|
|
forward, wrap, instant, onlysel);
|
2021-02-15 10:53:23 +01:00
|
|
|
|
2018-02-24 01:01:34 -05:00
|
|
|
dispatch(FuncRequest(LFUN_WORD_FIND, sdata));
|
2006-03-05 17:24:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-02-17 14:48:31 +01:00
|
|
|
void GuiSearchWidget::doReplace(bool const backwards)
|
|
|
|
{
|
|
|
|
docstring const needle = qstring_to_ucs4(findCO->currentText());
|
|
|
|
docstring const repl = qstring_to_ucs4(replaceCO->currentText());
|
|
|
|
replace(needle, repl, caseCB->isChecked(), wordsCB->isChecked(),
|
|
|
|
!backwards, false, wrapCB->isChecked(), selectionCB->isChecked());
|
|
|
|
uniqueInsert(findCO, findCO->currentText());
|
|
|
|
uniqueInsert(replaceCO, replaceCO->currentText());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
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,
|
2021-02-16 08:11:09 +01:00
|
|
|
bool forward, bool all, bool wrap, bool onlysel)
|
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,
|
2021-02-16 08:11:09 +01:00
|
|
|
matchword, all, forward, true, wrap, onlysel);
|
2021-02-17 14:48:31 +01:00
|
|
|
|
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());
|
2021-02-15 10:53:23 +01:00
|
|
|
settings.setValue(session_key + "/instant", instantSearchCB->isChecked());
|
2021-02-15 11:30:03 +01:00
|
|
|
settings.setValue(session_key + "/wrap", wrapCB->isChecked());
|
2021-02-16 08:11:09 +01:00
|
|
|
settings.setValue(session_key + "/selection", selectionCB->isChecked());
|
2021-02-14 17:18:00 +01:00
|
|
|
settings.setValue(session_key + "/minimized", minimized_);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GuiSearchWidget::restoreSession(QString const & session_key)
|
|
|
|
{
|
|
|
|
QSettings settings;
|
|
|
|
caseCB->setChecked(settings.value(session_key + "/casesensitive", false).toBool());
|
2021-02-18 07:33:26 +01:00
|
|
|
act_casesense_->setChecked(settings.value(session_key + "/casesensitive", false).toBool());
|
2021-02-14 17:18:00 +01:00
|
|
|
wordsCB->setChecked(settings.value(session_key + "/words", false).toBool());
|
2021-02-18 07:33:26 +01:00
|
|
|
act_wholewords_->setChecked(settings.value(session_key + "/words", false).toBool());
|
2021-02-15 10:53:23 +01:00
|
|
|
instantSearchCB->setChecked(settings.value(session_key + "/instant", false).toBool());
|
2021-02-18 07:33:26 +01:00
|
|
|
act_immediate_->setChecked(settings.value(session_key + "/instant", false).toBool());
|
2021-02-15 11:30:03 +01:00
|
|
|
wrapCB->setChecked(settings.value(session_key + "/wrap", false).toBool());
|
2021-02-18 07:33:26 +01:00
|
|
|
act_wrap_->setChecked(settings.value(session_key + "/wrap", false).toBool());
|
2021-02-16 08:11:09 +01:00
|
|
|
selectionCB->setChecked(settings.value(session_key + "/selection", false).toBool());
|
2021-02-18 07:33:26 +01:00
|
|
|
act_selection_->setChecked(settings.value(session_key + "/selection", false).toBool());
|
2021-02-14 17:18:00 +01:00
|
|
|
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());
|
2021-02-16 13:30:31 +01:00
|
|
|
setFocusProxy(widget_);
|
2021-02-14 17:18:00 +01:00
|
|
|
|
|
|
|
connect(widget_, SIGNAL(needTitleBarUpdate()), this, SLOT(updateTitle()));
|
|
|
|
connect(widget_, SIGNAL(needSizeUpdate()), this, SLOT(updateSize()));
|
|
|
|
}
|
|
|
|
|
2021-03-19 07:37:11 +01:00
|
|
|
|
|
|
|
void GuiSearch::mousePressEvent(QMouseEvent *event)
|
|
|
|
{
|
|
|
|
if (isFloating() && event->button() == Qt::LeftButton) {
|
|
|
|
dragPosition = event->globalPos() - frameGeometry().topLeft();
|
|
|
|
event->accept();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GuiSearch::mouseMoveEvent(QMouseEvent *event)
|
|
|
|
{
|
|
|
|
if (isFloating() && event->buttons() & Qt::LeftButton) {
|
|
|
|
move(event->globalPos() - dragPosition);
|
|
|
|
event->accept();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GuiSearch::mouseDoubleClickEvent(QMouseEvent *event)
|
|
|
|
{
|
|
|
|
if (event->button() == Qt::LeftButton) {
|
|
|
|
setFloating(!isFloating());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-02-14 17:18:00 +01:00
|
|
|
void GuiSearch::onBufferViewChanged()
|
|
|
|
{
|
2021-02-14 12:30:24 -05:00
|
|
|
widget_->setEnabled(static_cast<bool>(bufferview()));
|
2021-02-14 17:18:00 +01:00
|
|
|
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())
|
|
|
|
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"
|