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 || ev->key() == Qt::Key_Enter) {
109 doFind(ev->modifiers() == Qt::ShiftModifier);
112 if (ev->key() == Qt::Key_Escape) {
113 dispatch(FuncRequest(LFUN_DIALOG_HIDE, "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)
123 || fr == FuncRequest(LFUN_WORD_FIND)) {
127 if (fr == FuncRequest(LFUN_WORD_FIND_BACKWARD)) {
131 if (fr == FuncRequest(LFUN_DIALOG_TOGGLE, "findreplace")) {
136 QWidget::keyPressEvent(ev);
140 void GuiSearchWidget::minimizeClicked(bool const toggle)
143 minimized_ = !minimized_;
145 replaceLA->setHidden(minimized_);
146 replaceCO->setHidden(minimized_);
147 replacePB->setHidden(minimized_);
148 replacePrevPB->setHidden(minimized_);
149 replaceallPB->setHidden(minimized_);
150 CBFrame->setHidden(minimized_);
152 minimizePB->setText(qt_("Ex&pand"));
153 minimizePB->setToolTip(qt_("Show replace and option widgets"));
155 minimizePB->setText(qt_("&Minimize"));
156 minimizePB->setToolTip(qt_("Hide replace and option widgets"));
159 Q_EMIT needSizeUpdate();
160 Q_EMIT needTitleBarUpdate();
164 void GuiSearchWidget::showEvent(QShowEvent * e)
168 findCO->lineEdit()->selectAll();
169 QWidget::showEvent(e);
173 void GuiSearchWidget::findBufferChanged()
175 docstring search = theClipboard().getFindBuffer();
176 if (!search.empty()) {
177 LYXERR(Debug::CLIPBOARD, "from findbuffer: " << search);
178 #if QT_VERSION > 0x050000
179 findCO->setCurrentText(toqstr(search));
181 findCO->setEditText(toqstr(search));
187 void GuiSearchWidget::findChanged()
189 bool const emptytext = findCO->currentText().isEmpty();
190 findPB->setEnabled(!emptytext);
191 findPrevPB->setEnabled(!emptytext);
192 bool const replace = !emptytext && bv_ && !bv_->buffer().isReadonly();
193 replacePB->setEnabled(replace);
194 replacePrevPB->setEnabled(replace);
195 replaceallPB->setEnabled(replace);
196 if (instantSearchCB->isChecked())
201 void GuiSearchWidget::findClicked()
207 void GuiSearchWidget::findPrevClicked()
213 void GuiSearchWidget::replaceClicked()
219 void GuiSearchWidget::replacePrevClicked()
225 void GuiSearchWidget::replaceallClicked()
227 replace(qstring_to_ucs4(findCO->currentText()),
228 qstring_to_ucs4(replaceCO->currentText()),
229 caseCB->isChecked(), wordsCB->isChecked(),
230 true, true, true, selectionCB->isChecked());
231 uniqueInsert(findCO, findCO->currentText());
232 uniqueInsert(replaceCO, replaceCO->currentText());
236 void GuiSearchWidget::doFind(bool const backwards, bool const instant)
238 docstring const needle = qstring_to_ucs4(findCO->currentText());
239 find(needle, caseCB->isChecked(), wordsCB->isChecked(), !backwards,
240 instant, wrapCB->isChecked(), selectionCB->isChecked());
241 uniqueInsert(findCO, findCO->currentText());
243 findCO->lineEdit()->selectAll();
247 void GuiSearchWidget::find(docstring const & search, bool casesensitive,
248 bool matchword, bool forward, bool instant,
249 bool wrap, bool onlysel)
251 docstring const sdata =
252 find2string(search, casesensitive, matchword,
253 forward, wrap, instant, onlysel);
255 dispatch(FuncRequest(LFUN_WORD_FIND, sdata));
259 void GuiSearchWidget::doReplace(bool const backwards)
261 docstring const needle = qstring_to_ucs4(findCO->currentText());
262 docstring const repl = qstring_to_ucs4(replaceCO->currentText());
263 replace(needle, repl, caseCB->isChecked(), wordsCB->isChecked(),
264 !backwards, false, wrapCB->isChecked(), selectionCB->isChecked());
265 uniqueInsert(findCO, findCO->currentText());
266 uniqueInsert(replaceCO, replaceCO->currentText());
270 void GuiSearchWidget::replace(docstring const & search, docstring const & replace,
271 bool casesensitive, bool matchword,
272 bool forward, bool all, bool wrap, bool onlysel)
274 docstring const sdata =
275 replace2string(replace, search, casesensitive,
276 matchword, all, forward, true, wrap, onlysel);
278 dispatch(FuncRequest(LFUN_WORD_REPLACE, sdata));
281 void GuiSearchWidget::saveSession(QSettings & settings, QString const & session_key) const
283 settings.setValue(session_key + "/casesensitive", caseCB->isChecked());
284 settings.setValue(session_key + "/words", wordsCB->isChecked());
285 settings.setValue(session_key + "/instant", instantSearchCB->isChecked());
286 settings.setValue(session_key + "/wrap", wrapCB->isChecked());
287 settings.setValue(session_key + "/selection", selectionCB->isChecked());
288 settings.setValue(session_key + "/minimized", minimized_);
292 void GuiSearchWidget::restoreSession(QString const & session_key)
295 caseCB->setChecked(settings.value(session_key + "/casesensitive", false).toBool());
296 wordsCB->setChecked(settings.value(session_key + "/words", false).toBool());
297 instantSearchCB->setChecked(settings.value(session_key + "/instant", false).toBool());
298 wrapCB->setChecked(settings.value(session_key + "/wrap", false).toBool());
299 selectionCB->setChecked(settings.value(session_key + "/selection", false).toBool());
300 minimized_ = settings.value(session_key + "/minimized", false).toBool();
301 // initialize hidings
302 minimizeClicked(false);
306 GuiSearch::GuiSearch(GuiView & parent, Qt::DockWidgetArea area, Qt::WindowFlags flags)
307 : DockView(parent, "findreplace", qt_("Search and Replace"), area, flags),
308 widget_(new GuiSearchWidget(this))
311 widget_->setBufferView(bufferview());
312 setFocusProxy(widget_);
314 connect(widget_, SIGNAL(needTitleBarUpdate()), this, SLOT(updateTitle()));
315 connect(widget_, SIGNAL(needSizeUpdate()), this, SLOT(updateSize()));
318 void GuiSearch::onBufferViewChanged()
320 widget_->setEnabled(static_cast<bool>(bufferview()));
321 widget_->setBufferView(bufferview());
325 void GuiSearch::updateView()
332 void GuiSearch::saveSession(QSettings & settings) const
334 Dialog::saveSession(settings);
335 widget_->saveSession(settings, sessionKey());
339 void GuiSearch::restoreSession()
341 DockView::restoreSession();
342 widget_->restoreSession(sessionKey());
346 void GuiSearch::updateTitle()
348 if (widget_->isMinimized()) {
350 setTitleBarWidget(new QWidget());
351 titleBarWidget()->hide();
354 setTitleBarWidget(nullptr);
358 void GuiSearch::updateSize()
360 widget_->setFixedHeight(widget_->sizeHint().height());
361 if (widget_->isMinimized())
362 setFixedHeight(widget_->sizeHint().height());
364 // undo setFixedHeight
365 setMaximumHeight(QWIDGETSIZE_MAX);
372 } // namespace frontend
376 #include "moc_GuiSearch.cpp"