3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
8 * \author Angus Leeming
10 * Full author contact details are available in file CREDITS.
15 #include "GuiApplication.h"
16 #include "GuiSearch.h"
19 #include "qt_helpers.h"
20 #include "FuncRequest.h"
22 #include "BufferView.h"
25 #include "FuncRequest.h"
27 #include "GuiKeySymbol.h"
30 #include "support/debug.h"
31 #include "support/gettext.h"
32 #include "frontends/alert.h"
33 #include "frontends/Clipboard.h"
39 #include "QSizePolicy"
48 static void uniqueInsert(QComboBox * box, QString const & text)
50 for (int i = box->count(); --i >= 0; )
51 if (box->itemText(i) == text)
54 box->insertItem(0, text);
58 GuiSearchWidget::GuiSearchWidget(QWidget * parent)
63 // fix height to minimum
64 setFixedHeight(sizeHint().height());
66 // align items in grid on top
67 gridLayout->setAlignment(Qt::AlignTop);
69 connect(findPB, SIGNAL(clicked()), this, SLOT(findClicked()));
70 connect(findPrevPB, SIGNAL(clicked()), this, SLOT(findPrevClicked()));
71 connect(minimizePB, SIGNAL(clicked()), this, SLOT(minimizeClicked()));
72 connect(replacePB, SIGNAL(clicked()), this, SLOT(replaceClicked()));
73 connect(replacePrevPB, SIGNAL(clicked()), this, SLOT(replacePrevClicked()));
74 connect(replaceallPB, SIGNAL(clicked()), this, SLOT(replaceallClicked()));
75 connect(findCO, SIGNAL(editTextChanged(QString)),
76 this, SLOT(findChanged()));
77 if(qApp->clipboard()->supportsFindBuffer()) {
78 connect(qApp->clipboard(), SIGNAL(findBufferChanged()),
79 this, SLOT(findBufferChanged()));
83 setFocusProxy(findCO);
85 findCO->setCompleter(nullptr);
86 replaceCO->setCompleter(nullptr);
88 replacePB->setEnabled(false);
89 replacePrevPB->setEnabled(false);
90 replaceallPB->setEnabled(false);
94 bool GuiSearchWidget::initialiseParams(std::string const & str)
97 findCO->lineEdit()->setText(toqstr(str));
102 void GuiSearchWidget::keyPressEvent(QKeyEvent * ev)
105 setKeySymbol(&sym, ev);
107 // catch Return and Shift-Return
108 if (ev->key() == Qt::Key_Return) {
109 findClicked(ev->modifiers() == Qt::ShiftModifier);
112 if (ev->key() == Qt::Key_Escape) {
113 dispatch(FuncRequest(LFUN_DIALOG_TOGGLE, "findreplace"));
117 // we catch the key sequences for forward and backwards search
119 KeyModifier mod = lyx::q_key_state(ev->modifiers());
120 KeySequence keyseq(&theTopLevelKeymap(), &theTopLevelKeymap());
121 FuncRequest fr = keyseq.addkey(sym, mod);
122 if (fr == FuncRequest(LFUN_WORD_FIND_FORWARD) || fr == FuncRequest(LFUN_WORD_FIND)) {
126 if (fr == FuncRequest(LFUN_WORD_FIND_BACKWARD)) {
130 if (fr == FuncRequest(LFUN_DIALOG_TOGGLE, "findreplace")) {
135 QWidget::keyPressEvent(ev);
139 void GuiSearchWidget::minimizeClicked(bool const toggle)
142 minimized_ = !minimized_;
144 replaceLA->setHidden(minimized_);
145 replaceCO->setHidden(minimized_);
146 replacePB->setHidden(minimized_);
147 replacePrevPB->setHidden(minimized_);
148 replaceallPB->setHidden(minimized_);
149 CBFrame->setHidden(minimized_);
151 minimizePB->setText(qt_("Ex&pand"));
152 minimizePB->setToolTip(qt_("Show replace and option widgets"));
154 minimizePB->setText(qt_("&Minimize"));
155 minimizePB->setToolTip(qt_("Hide replace and option widgets"));
158 Q_EMIT needSizeUpdate();
159 Q_EMIT needTitleBarUpdate();
163 void GuiSearchWidget::showEvent(QShowEvent * e)
167 findCO->lineEdit()->selectAll();
168 QWidget::showEvent(e);
172 void GuiSearchWidget::findBufferChanged()
174 docstring search = theClipboard().getFindBuffer();
175 if (!search.empty()) {
176 LYXERR(Debug::CLIPBOARD, "from findbuffer: " << search);
177 #if QT_VERSION > 0x050000
178 findCO->setCurrentText(toqstr(search));
180 findCO->setEditText(toqstr(search));
186 void GuiSearchWidget::findChanged()
188 bool const emptytext = findCO->currentText().isEmpty();
189 findPB->setEnabled(!emptytext);
190 findPrevPB->setEnabled(!emptytext);
191 bool const replace = !emptytext && bv_ && !bv_->buffer().isReadonly();
192 replacePB->setEnabled(replace);
193 replacePrevPB->setEnabled(replace);
194 replaceallPB->setEnabled(replace);
195 if (instantSearchCB->isChecked() && !emptytext)
200 void GuiSearchWidget::findClicked(bool const backwards)
202 docstring const needle = qstring_to_ucs4(findCO->currentText());
203 find(needle, caseCB->isChecked(), wordsCB->isChecked(), !backwards,
204 instantSearchCB->isChecked(), wrapCB->isChecked(), selectionCB->isChecked());
205 uniqueInsert(findCO, findCO->currentText());
206 if (!instantSearchCB->isChecked())
207 findCO->lineEdit()->selectAll();
211 void GuiSearchWidget::findPrevClicked()
217 void GuiSearchWidget::replaceClicked(bool const backwards)
219 docstring const needle = qstring_to_ucs4(findCO->currentText());
220 docstring const repl = qstring_to_ucs4(replaceCO->currentText());
221 replace(needle, repl, caseCB->isChecked(), wordsCB->isChecked(),
222 !backwards, false, wrapCB->isChecked(), selectionCB->isChecked());
223 uniqueInsert(findCO, findCO->currentText());
224 uniqueInsert(replaceCO, replaceCO->currentText());
228 void GuiSearchWidget::replacePrevClicked()
230 replaceClicked(true);
234 void GuiSearchWidget::replaceallClicked()
236 replace(qstring_to_ucs4(findCO->currentText()),
237 qstring_to_ucs4(replaceCO->currentText()),
238 caseCB->isChecked(), wordsCB->isChecked(),
239 true, true, true, selectionCB->isChecked());
240 uniqueInsert(findCO, findCO->currentText());
241 uniqueInsert(replaceCO, replaceCO->currentText());
245 void GuiSearchWidget::find(docstring const & search, bool casesensitive,
246 bool matchword, bool forward, bool instant,
247 bool wrap, bool onlysel)
249 docstring const sdata =
250 find2string(search, casesensitive, matchword,
251 forward, wrap, instant, onlysel);
253 dispatch(FuncRequest(LFUN_WORD_FIND, sdata));
257 void GuiSearchWidget::replace(docstring const & search, docstring const & replace,
258 bool casesensitive, bool matchword,
259 bool forward, bool all, bool wrap, bool onlysel)
261 docstring const sdata =
262 replace2string(replace, search, casesensitive,
263 matchword, all, forward, true, wrap, onlysel);
264 dispatch(FuncRequest(LFUN_WORD_REPLACE, sdata));
267 void GuiSearchWidget::saveSession(QSettings & settings, QString const & session_key) const
269 settings.setValue(session_key + "/casesensitive", caseCB->isChecked());
270 settings.setValue(session_key + "/words", wordsCB->isChecked());
271 settings.setValue(session_key + "/instant", instantSearchCB->isChecked());
272 settings.setValue(session_key + "/wrap", wrapCB->isChecked());
273 settings.setValue(session_key + "/selection", selectionCB->isChecked());
274 settings.setValue(session_key + "/minimized", minimized_);
278 void GuiSearchWidget::restoreSession(QString const & session_key)
281 caseCB->setChecked(settings.value(session_key + "/casesensitive", false).toBool());
282 wordsCB->setChecked(settings.value(session_key + "/words", false).toBool());
283 instantSearchCB->setChecked(settings.value(session_key + "/instant", false).toBool());
284 wrapCB->setChecked(settings.value(session_key + "/wrap", false).toBool());
285 selectionCB->setChecked(settings.value(session_key + "/selection", false).toBool());
286 minimized_ = settings.value(session_key + "/minimized", false).toBool();
287 // initialize hidings
288 minimizeClicked(false);
292 GuiSearch::GuiSearch(GuiView & parent, Qt::DockWidgetArea area, Qt::WindowFlags flags)
293 : DockView(parent, "findreplace", qt_("Search and Replace"), area, flags),
294 widget_(new GuiSearchWidget(this))
297 widget_->setBufferView(bufferview());
298 setFocusProxy(widget_->findCO);
300 connect(widget_, SIGNAL(needTitleBarUpdate()), this, SLOT(updateTitle()));
301 connect(widget_, SIGNAL(needSizeUpdate()), this, SLOT(updateSize()));
304 void GuiSearch::onBufferViewChanged()
306 widget_->setEnabled(static_cast<bool>(bufferview()));
307 widget_->setBufferView(bufferview());
311 void GuiSearch::updateView()
318 void GuiSearch::saveSession(QSettings & settings) const
320 Dialog::saveSession(settings);
321 widget_->saveSession(settings, sessionKey());
325 void GuiSearch::restoreSession()
327 DockView::restoreSession();
328 widget_->restoreSession(sessionKey());
332 void GuiSearch::updateTitle()
334 if (widget_->isMinimized()) {
336 setTitleBarWidget(new QWidget());
337 titleBarWidget()->hide();
340 setTitleBarWidget(nullptr);
344 void GuiSearch::updateSize()
346 widget_->setFixedHeight(widget_->sizeHint().height());
347 if (widget_->isMinimized())
348 setFixedHeight(widget_->sizeHint().height());
350 // undo setFixedHeight
351 setMaximumHeight(QWIDGETSIZE_MAX);
358 } // namespace frontend
362 #include "moc_GuiSearch.cpp"