#include <QPainter>
#include <QLineEdit>
#include <QSettings>
+#include <QHideEvent>
#include <QShowEvent>
#include "QSizePolicy"
-#if QT_VERSION >= 0x050000
#include <QSvgRenderer>
-#endif
using namespace std;
using namespace lyx::support;
}
-GuiSearchWidget::GuiSearchWidget(QWidget * parent)
- : QWidget(parent)
+GuiSearchWidget::GuiSearchWidget(QWidget * parent, GuiView & view)
+ : QWidget(parent), view_(view)
{
setupUi(this);
connect(replacePB, SIGNAL(clicked()), this, SLOT(replaceClicked()));
connect(replacePrevPB, SIGNAL(clicked()), this, SLOT(replacePrevClicked()));
connect(replaceallPB, SIGNAL(clicked()), this, SLOT(replaceallClicked()));
+ connect(instantSearchCB, SIGNAL(clicked()), this, SLOT(immediateClicked()));
connect(findCO, SIGNAL(editTextChanged(QString)),
this, SLOT(findChanged()));
if(qApp->clipboard()->supportsFindBuffer()) {
bool GuiSearchWidget::initialiseParams(std::string const & str)
{
- if (!str.empty())
- findCO->lineEdit()->setText(toqstr(str));
+ if (!str.empty()) {
+ // selectAll & insert rather than setText in order to keep undo stack
+ findCO->lineEdit()->selectAll();
+ findCO->lineEdit()->insert(toqstr(str));
+ }
+ findCO->setFocus();
+ findCO->lineEdit()->selectAll();
return true;
}
return;
}
if (ev->key() == Qt::Key_Escape) {
+ Qt::KeyboardModifiers mod = ev->modifiers();
+ if (mod & Qt::AltModifier) {
+ QWidget::keyPressEvent(ev);
+ return;
+ }
+
dispatch(FuncRequest(LFUN_DIALOG_HIDE, "findreplace"));
+ view_.setFocus();
+ bv_->buffer().updateBuffer();
return;
}
act_casesense_->setChecked(caseCB->isChecked());
act_immediate_->setChecked(instantSearchCB->isChecked());
act_selection_->setChecked(selectionCB->isChecked());
+ act_selection_->setEnabled(!instantSearchCB->isChecked());
act_wholewords_->setChecked(wordsCB->isChecked());
act_wrap_->setChecked(wrapCB->isChecked());
blockSignals(false);
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/";
QPixmap bpixmap = getPixmap("images/", "search-options", "svgz,png");
QPixmap pm = bpixmap;
pm.fill(Qt::transparent);
QPainter painter(&pm);
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");
-#if QT_VERSION < 0x050000
- painter.drawPixmap(x, 0, spixmap);
-#else
- // With Qt5, we render SVG directly for HiDPI scalability
+ // We render SVG directly for HiDPI scalability
FileName fname = imageLibFileSearch(imagedir, "search-case-sensitive", "svgz,png");
QString fpath = toqstr(fname.absFileName());
if (!fpath.isEmpty()) {
svgRenderer.render(&painter, QRectF(0, 0, spixmap.width() * dpr,
spixmap.height() * dpr));
}
-#endif
x += (spixmap.width() * dpr) + gap;
}
if (wordsCB->isChecked()) {
tip += "<li>" + qt_("Whole words only");
QPixmap spixmap = getPixmap("images/", "search-whole-words", "svgz,png");
-#if QT_VERSION < 0x050000
- painter.drawPixmap(x, 0, spixmap);
-#else
FileName fname = imageLibFileSearch(imagedir, "search-whole-words", "svgz,png");
QString fpath = toqstr(fname.absFileName());
if (!fpath.isEmpty()) {
svgRenderer.render(&painter, QRectF(x, 0, spixmap.width() * dpr,
spixmap.height() * dpr));
}
-#endif
x += (spixmap.width() * dpr) + gap;
}
if (selectionCB->isChecked()) {
tip += "<li>" + qt_("Search only in selection");
QPixmap spixmap = getPixmap("images/", "search-selection", "svgz,png");
-#if QT_VERSION < 0x050000
- painter.drawPixmap(x, 0, spixmap);
-#else
FileName fname = imageLibFileSearch(imagedir, "search-selection", "svgz,png");
QString fpath = toqstr(fname.absFileName());
if (!fpath.isEmpty()) {
svgRenderer.render(&painter, QRectF(x, 0, spixmap.width() * dpr,
spixmap.height() * dpr));
}
-#endif
x += (spixmap.width() * dpr) + gap;
}
if (instantSearchCB->isChecked()) {
tip += "<li>" + qt_("Search as you type");
QPixmap spixmap = getPixmap("images/", "search-instant", "svgz,png");
-#if QT_VERSION < 0x050000
- painter.drawPixmap(x, 0, spixmap);
-#else
FileName fname = imageLibFileSearch(imagedir, "search-instant", "svgz,png");
QString fpath = toqstr(fname.absFileName());
if (!fpath.isEmpty()) {
svgRenderer.render(&painter, QRectF(x, 0, spixmap.width() * dpr,
spixmap.height() * dpr));
}
-#endif
x += (spixmap.width() * dpr) + gap;
}
if (wrapCB->isChecked()) {
tip += "<li>" + qt_("Wrap search");
QPixmap spixmap = getPixmap("images/", "search-wrap", "svgz,png");
-#if QT_VERSION < 0x050000
- painter.drawPixmap(x, 0, spixmap);
-#else
FileName fname = imageLibFileSearch(imagedir, "search-wrap", "svgz,png");
QString fpath = toqstr(fname.absFileName());
if (!fpath.isEmpty()) {
svgRenderer.render(&painter, QRectF(x, 0, spixmap.width() * dpr,
spixmap.height() * dpr));
}
-#endif
x += (spixmap.width() * dpr) + gap;
}
tip += "</ul>";
-#if QT_VERSION >= 0x050000
pm.setDevicePixelRatio(dpr);
-#endif
painter.end();
} else {
tip = qt_("Click here to change search options");
-#if QT_VERSION >= 0x050000
- // With Qt5, we render SVG directly for HiDPI scalability
+ // We render SVG directly for HiDPI scalability
FileName fname = imageLibFileSearch(imagedir, "search-options", "svgz,png");
QString fpath = toqstr(fname.absFileName());
if (!fpath.isEmpty()) {
pm.setDevicePixelRatio(dpr);
}
}
-#endif
}
if (dark_mode) {
QImage img = pm.toImage();
void GuiSearchWidget::immediateActTriggered()
{
- instantSearchCB->setChecked(act_immediate_->isChecked());
+ bool const immediate = act_immediate_->isChecked();
+ instantSearchCB->setChecked(immediate);
+ // FIXME: make these two work together eventually.
+ selectionCB->setEnabled(!immediate);
+ act_selection_->setEnabled(!immediate);
+ if (immediate) {
+ selectionCB->setChecked(false);
+ act_selection_->setChecked(false);
+ }
handleIndicators();
}
+void GuiSearchWidget::immediateClicked()
+{
+ // FIXME: make these two work together eventually.
+ bool const immediate = instantSearchCB->isChecked();
+ selectionCB->setEnabled(!immediate);
+ if (immediate)
+ selectionCB->setChecked(false);
+}
+
+
void GuiSearchWidget::wrapActTriggered()
{
wrapCB->setChecked(act_wrap_->isChecked());
void GuiSearchWidget::showEvent(QShowEvent * e)
{
findChanged();
- findPB->setFocus();
- findCO->lineEdit()->selectAll();
QWidget::showEvent(e);
}
+void GuiSearchWidget::hideEvent(QHideEvent *)
+{
+ dispatch(FuncRequest(LFUN_DIALOG_HIDE, "findreplace"));
+ view_.setFocus();
+ // update toolbar status
+ if (bv_)
+ bv_->buffer().updateBuffer();
+}
+
+
void GuiSearchWidget::findBufferChanged()
{
docstring search = theClipboard().getFindBuffer();
- if (!search.empty()) {
+ // update from find buffer, but only if the strings differ (else we
+ // might end up in loops with search as you type)
+ if (!search.empty() && toqstr(search) != findCO->lineEdit()->text()) {
LYXERR(Debug::CLIPBOARD, "from findbuffer: " << search);
+ // selectAll & insert rather than setText in order to keep undo stack
findCO->lineEdit()->selectAll();
findCO->lineEdit()->insert(toqstr(search));
- findCO->lineEdit()->selectAll();
}
}
act_casesense_->setChecked(settings.value(session_key + "/casesensitive", false).toBool());
wordsCB->setChecked(settings.value(session_key + "/words", false).toBool());
act_wholewords_->setChecked(settings.value(session_key + "/words", false).toBool());
- instantSearchCB->setChecked(settings.value(session_key + "/instant", false).toBool());
- act_immediate_->setChecked(settings.value(session_key + "/instant", false).toBool());
- wrapCB->setChecked(settings.value(session_key + "/wrap", false).toBool());
- act_wrap_->setChecked(settings.value(session_key + "/wrap", false).toBool());
- selectionCB->setChecked(settings.value(session_key + "/selection", false).toBool());
+ bool const immediate = settings.value(session_key + "/instant", false).toBool();
+ instantSearchCB->setChecked(immediate);
+ act_immediate_->setChecked(immediate);
+ wrapCB->setChecked(settings.value(session_key + "/wrap", true).toBool());
+ act_wrap_->setChecked(settings.value(session_key + "/wrap", true).toBool());
+ selectionCB->setChecked(settings.value(session_key + "/selection", false).toBool() && !immediate);
+ selectionCB->setEnabled(!immediate);
act_selection_->setChecked(settings.value(session_key + "/selection", false).toBool());
minimized_ = settings.value(session_key + "/minimized", false).toBool();
// initialize hidings
GuiSearch::GuiSearch(GuiView & parent, Qt::DockWidgetArea area, Qt::WindowFlags flags)
: DockView(parent, "findreplace", qt_("Search and Replace"), area, flags),
- widget_(new GuiSearchWidget(this))
+ widget_(new GuiSearchWidget(this, parent))
{
setWidget(widget_);
widget_->setBufferView(bufferview());
connect(widget_, SIGNAL(needSizeUpdate()), this, SLOT(updateSize()));
}
+
+void GuiSearch::mousePressEvent(QMouseEvent * event)
+{
+ if (isFloating() && event->button() == Qt::LeftButton) {
+#if QT_VERSION >= 0x060000
+ dragPosition = event->globalPosition().toPoint() - frameGeometry().topLeft();
+#else
+ dragPosition = event->globalPos() - frameGeometry().topLeft();
+#endif
+ event->accept();
+ } else
+ DockView::mousePressEvent(event);
+}
+
+
+void GuiSearch::mouseMoveEvent(QMouseEvent * event)
+{
+ if (isFloating() && event->buttons() & Qt::LeftButton) {
+#if QT_VERSION >= 0x060000
+ move(event->globalPosition().toPoint() - dragPosition);
+#else
+ move(event->globalPos() - dragPosition);
+#endif
+ event->accept();
+ } else
+ DockView::mouseMoveEvent(event);
+}
+
+
+void GuiSearch::mouseDoubleClickEvent(QMouseEvent * event)
+{
+ if (event->button() == Qt::LeftButton)
+ setFloating(!isFloating());
+ else
+ DockView::mouseDoubleClickEvent(event);
+}
+
+
void GuiSearch::onBufferViewChanged()
{
widget_->setEnabled(static_cast<bool>(bufferview()));
// remove title bar
setTitleBarWidget(new QWidget());
titleBarWidget()->hide();
- } else
+ } else if (titleBarWidget()) {
// restore title bar
setTitleBarWidget(nullptr);
+ }
}