]> git.lyx.org Git - lyx.git/blobdiff - src/frontends/qt/GuiSearch.cpp
Few string fixes from Dan.
[lyx.git] / src / frontends / qt / GuiSearch.cpp
index 169c7aa8b63d26073d23acc619c4f7fcf328d764..3ca4f4904d649bacfcf1cf44cb80791275a733b9 100644 (file)
 #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;
@@ -63,8 +62,8 @@ static void uniqueInsert(QComboBox * box, QString const & text)
 }
 
 
-GuiSearchWidget::GuiSearchWidget(QWidget * parent)
-       :       QWidget(parent)
+GuiSearchWidget::GuiSearchWidget(QWidget * parent, GuiView & view)
+       :       QWidget(parent), view_(view)
 {
        setupUi(this);
 
@@ -80,6 +79,7 @@ GuiSearchWidget::GuiSearchWidget(QWidget * parent)
        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()) {
@@ -131,8 +131,13 @@ GuiSearchWidget::GuiSearchWidget(QWidget * parent)
 
 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;
 }
 
@@ -148,7 +153,15 @@ void GuiSearchWidget::keyPressEvent(QKeyEvent * ev)
                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;
        }
 
@@ -195,6 +208,7 @@ void GuiSearchWidget::minimizeClicked(bool const toggle)
                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);
@@ -230,11 +244,9 @@ void GuiSearchWidget::handleIndicators()
 
                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;
@@ -247,16 +259,13 @@ void GuiSearchWidget::handleIndicators()
                        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()) {
@@ -265,15 +274,11 @@ void GuiSearchWidget::handleIndicators()
                                                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()) {
@@ -282,15 +287,11 @@ void GuiSearchWidget::handleIndicators()
                                                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()) {
@@ -299,15 +300,11 @@ void GuiSearchWidget::handleIndicators()
                                                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()) {
@@ -316,15 +313,11 @@ void GuiSearchWidget::handleIndicators()
                                                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()) {
@@ -333,18 +326,14 @@ void GuiSearchWidget::handleIndicators()
                                                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()) {
@@ -357,7 +346,6 @@ void GuiSearchWidget::handleIndicators()
                                        pm.setDevicePixelRatio(dpr);
                                }
                        }
-#endif
                }
                if (dark_mode) {
                        QImage img = pm.toImage();
@@ -393,11 +381,29 @@ void GuiSearchWidget::searchSelActTriggered()
 
 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());
@@ -408,20 +414,30 @@ void GuiSearchWidget::wrapActTriggered()
 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();
        }
 }
 
@@ -538,11 +554,13 @@ void GuiSearchWidget::restoreSession(QString const & session_key)
        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
@@ -552,7 +570,7 @@ void GuiSearchWidget::restoreSession(QString const & session_key)
 
 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());
@@ -562,6 +580,44 @@ GuiSearch::GuiSearch(GuiView & parent, Qt::DockWidgetArea area, Qt::WindowFlags
        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()));
@@ -596,9 +652,10 @@ void GuiSearch::updateTitle()
                // remove title bar
                setTitleBarWidget(new QWidget());
                titleBarWidget()->hide();
-       } else
+       } else if (titleBarWidget()) {
                // restore title bar
                setTitleBarWidget(nullptr);
+       }
 }