]> git.lyx.org Git - lyx.git/blobdiff - src/frontends/qt4/GuiSearch.cpp
On Linux show in crash message box the backtrace
[lyx.git] / src / frontends / qt4 / GuiSearch.cpp
index 03fb76ba77257886f472bbc32123eab3fbf4578b..712464738093463ff100f58c69f572d9717897c4 100644 (file)
@@ -5,49 +5,53 @@
  *
  * \author John Levon
  * \author Edwin Leuven
+ * \author Angus Leeming
  *
  * Full author contact details are available in file CREDITS.
  */
 
 #include <config.h>
 
+#include "lyxfind.h"
+#include "qt_helpers.h"
+#include "FuncRequest.h"
+#include "BufferView.h"
+#include "Buffer.h"
+#include "Cursor.h"
 #include "GuiSearch.h"
+#include "GuiView.h"
 
-#include "ControlSearch.h"
-#include "qt_helpers.h"
+#include "support/gettext.h"
+#include "frontends/alert.h"
 
 #include <QLineEdit>
-#include <QCloseEvent>
-
-using std::string;
+#include <QShowEvent>
 
+using namespace std;
 
 namespace lyx {
 namespace frontend {
 
 static void uniqueInsert(QComboBox * box, QString const & text)
 {
-       for (int i = 0; i < box->count(); ++i) {
+       for (int i = box->count(); --i >= 0; )
                if (box->itemText(i) == text)
                        return;
-       }
 
-       box->addItem(text);
+       box->insertItem(0, text);
 }
 
 
-GuiSearchDialog::GuiSearchDialog(LyXView & lv)
-       : GuiDialog(lv, "findreplace"
+GuiSearch::GuiSearch(GuiView & lv)
+       : GuiDialog(lv, "findreplace", qt_("Find and Replace"))
 {
        setupUi(this);
-       setController(new ControlSearch(*this));
-       setViewTitle(_("Find and Replace"));
 
        connect(closePB, SIGNAL(clicked()), this, SLOT(slotClose()));
        connect(findPB, SIGNAL(clicked()), this, SLOT(findClicked()));
        connect(replacePB, SIGNAL(clicked()), this, SLOT(replaceClicked()));
        connect(replaceallPB, SIGNAL(clicked()), this, SLOT(replaceallClicked()));
-       connect(findCO, SIGNAL(editTextChanged(const QString &)),
+       connect(findCO, SIGNAL(editTextChanged(QString)),
                this, SLOT(findChanged()));
 
        setFocusProxy(findCO);
@@ -63,27 +67,15 @@ GuiSearchDialog::GuiSearchDialog(LyXView & lv)
 }
 
 
-ControlSearch & GuiSearchDialog::controller() const
-{
-       return static_cast<ControlSearch &>(GuiDialog::controller());
-}
-
-
-void GuiSearchDialog::showView()
-{
-       findCO->lineEdit()->setSelection(0, findCO->lineEdit()->text().length());
-       GuiDialog::showView();
-}
-
-
-void GuiSearchDialog::closeEvent(QCloseEvent * e)
+void GuiSearch::showEvent(QShowEvent * e)
 {
-       slotWMHide();
-       e->accept();
+       findPB->setFocus();
+       findCO->lineEdit()->selectAll();
+       GuiDialog::showEvent(e);
 }
 
 
-void GuiSearchDialog::findChanged()
+void GuiSearch::findChanged()
 {
        if (findCO->currentText().isEmpty()) {
                findPB->setEnabled(false);
@@ -91,60 +83,105 @@ void GuiSearchDialog::findChanged()
                replaceallPB->setEnabled(false);
        } else {
                findPB->setEnabled(true);
-               replacePB->setEnabled(!readOnly());
-               replaceallPB->setEnabled(!readOnly());
+               replacePB->setEnabled(!isBufferReadonly());
+               replaceallPB->setEnabled(!isBufferReadonly());
        }
 }
 
 
-void GuiSearchDialog::findClicked()
+void GuiSearch::findClicked()
 {
        docstring const needle = qstring_to_ucs4(findCO->currentText());
        find(needle, caseCB->isChecked(), wordsCB->isChecked(),
-               backwardsCB->isChecked());
+               !backwardsCB->isChecked());
        uniqueInsert(findCO, findCO->currentText());
-       findCO->lineEdit()->setSelection(0, findCO->lineEdit()->text().length());
+       findCO->lineEdit()->selectAll();
 }
 
 
-void GuiSearchDialog::replaceClicked()
+void GuiSearch::replaceClicked()
 {
        docstring const needle = qstring_to_ucs4(findCO->currentText());
        docstring const repl = qstring_to_ucs4(replaceCO->currentText());
        replace(needle, repl, caseCB->isChecked(), wordsCB->isChecked(),
-               backwardsCB->isChecked(), false);
+               !backwardsCB->isChecked(), false);
        uniqueInsert(findCO, findCO->currentText());
        uniqueInsert(replaceCO, replaceCO->currentText());
 }
 
 
-void GuiSearchDialog::replaceallClicked()
+void GuiSearch::replaceallClicked()
 {
        replace(qstring_to_ucs4(findCO->currentText()),
                qstring_to_ucs4(replaceCO->currentText()),
-               caseCB->isChecked(), wordsCB->isChecked(), false, true);
+               caseCB->isChecked(), wordsCB->isChecked(), true, true);
        uniqueInsert(findCO, findCO->currentText());
        uniqueInsert(replaceCO, replaceCO->currentText());
 }
 
 
-void GuiSearchDialog::find(docstring const & str, bool casesens,
-       bool words, bool backwards)
+void GuiSearch::wrap_dispatch(const FuncRequest & func, bool forward)
+{
+       dispatch(func);
+
+       BufferView * bv = const_cast<BufferView *>(bufferview());
+
+       if (!bv->cursor().result().dispatched()) {
+               GuiView & lv = *const_cast<GuiView *>(&lyxview());
+               DocIterator cur_orig(bv->cursor());
+               docstring q;
+               if (forward)
+                       q = _("End of file reached while searching forward.\n"
+                         "Continue searching from the beginning?");
+               else
+                       q = _("Beginning of file reached while searching backward.\n"
+                         "Continue searching from the end?");
+               int wrap_answer = frontend::Alert::prompt(_("Wrap search?"),
+                       q, 0, 1, _("&Yes"), _("&No"));
+               if (wrap_answer == 0) {
+                       if (forward) {
+                               bv->cursor().clear();
+                               bv->cursor().push_back(CursorSlice(bv->buffer().inset()));
+                       } else {
+                               bv->cursor().setCursor(doc_iterator_end(&bv->buffer()));
+                               bv->cursor().backwardPos();
+                       }
+                       bv->clearSelection();
+                       dispatch(func);
+                       if (bv->cursor().result().dispatched())
+                               return;
+               }
+               bv->cursor().setCursor(cur_orig);
+               lv.message(_("String not found."));
+       }
+}
+
+
+void GuiSearch::find(docstring const & search, bool casesensitive,
+                        bool matchword, bool forward)
 {
-       controller().find(str, casesens, words, !backwards);
+       docstring const data =
+               find2string(search, casesensitive, matchword, forward);
+       wrap_dispatch(FuncRequest(LFUN_WORD_FIND, data), forward);
 }
 
 
-void GuiSearchDialog::replace(docstring const & findstr,
-       docstring const & replacestr,
-       bool casesens, bool words, bool backwards, bool all)
+void GuiSearch::replace(docstring const & search, docstring const & replace,
+                           bool casesensitive, bool matchword,
+                           bool forward, bool all)
 {
-       controller().replace(findstr, replacestr, casesens, words,
-                            !backwards, all);
+       docstring const data =
+               replace2string(replace, search, casesensitive,
+                                    matchword, all, forward);
+       wrap_dispatch(FuncRequest(LFUN_WORD_REPLACE, data), forward);
 }
 
+
+Dialog * createGuiSearch(GuiView & lv) { return new GuiSearch(lv); }
+
+
 } // namespace frontend
 } // namespace lyx
 
 
-#include "GuiSearch_moc.cpp"
+#include "moc_GuiSearch.cpp"