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 void GuiSearchWidget::keyPressEvent(QKeyEvent * ev)
97 setKeySymbol(&sym, ev);
99 // catch Return and Shift-Return
100 if (ev->key() == Qt::Key_Return) {
101 findClicked(ev->modifiers() == Qt::ShiftModifier);
104 if (ev->key() == Qt::Key_Escape) {
105 dispatch(FuncRequest(LFUN_DIALOG_TOGGLE, "findreplace"));
109 // we catch the key sequences for forward and backwards search
111 KeyModifier mod = lyx::q_key_state(ev->modifiers());
112 KeySequence keyseq(&theTopLevelKeymap(), &theTopLevelKeymap());
113 FuncRequest fr = keyseq.addkey(sym, mod);
114 if (fr == FuncRequest(LFUN_WORD_FIND_FORWARD) || fr == FuncRequest(LFUN_WORD_FIND)) {
118 if (fr == FuncRequest(LFUN_WORD_FIND_BACKWARD)) {
122 if (fr == FuncRequest(LFUN_DIALOG_TOGGLE, "findreplace")) {
127 QWidget::keyPressEvent(ev);
131 void GuiSearchWidget::minimizeClicked(bool const toggle)
134 minimized_ = !minimized_;
136 replaceLA->setHidden(minimized_);
137 replaceCO->setHidden(minimized_);
138 replacePB->setHidden(minimized_);
139 replacePrevPB->setHidden(minimized_);
140 replaceallPB->setHidden(minimized_);
141 CBFrame->setHidden(minimized_);
143 minimizePB->setText(qt_("Ex&pand"));
144 minimizePB->setToolTip(qt_("Show replace and option widgets"));
146 minimizePB->setText(qt_("&Minimize"));
147 minimizePB->setToolTip(qt_("Hide replace and option widgets"));
150 Q_EMIT needSizeUpdate();
151 Q_EMIT needTitleBarUpdate();
155 void GuiSearchWidget::showEvent(QShowEvent * e)
159 findCO->lineEdit()->selectAll();
160 QWidget::showEvent(e);
164 void GuiSearchWidget::findBufferChanged()
166 docstring search = theClipboard().getFindBuffer();
167 if (!search.empty()) {
168 LYXERR(Debug::CLIPBOARD, "from findbuffer: " << search);
169 #if QT_VERSION > 0x050000
170 findCO->setCurrentText(toqstr(search));
172 findCO->setEditText(toqstr(search));
178 void GuiSearchWidget::findChanged()
180 bool const emptytext = findCO->currentText().isEmpty();
181 findPB->setEnabled(!emptytext);
182 findPrevPB->setEnabled(!emptytext);
183 bool const replace = !emptytext && bv_ && !bv_->buffer().isReadonly();
184 replacePB->setEnabled(replace);
185 replacePrevPB->setEnabled(replace);
186 replaceallPB->setEnabled(replace);
187 if (instantSearchCB->isChecked() && !emptytext)
192 void GuiSearchWidget::findClicked(bool const backwards)
194 docstring const needle = qstring_to_ucs4(findCO->currentText());
195 find(needle, caseCB->isChecked(), wordsCB->isChecked(), !backwards,
196 instantSearchCB->isChecked(), wrapCB->isChecked());
197 uniqueInsert(findCO, findCO->currentText());
198 if (!instantSearchCB->isChecked())
199 findCO->lineEdit()->selectAll();
203 void GuiSearchWidget::findPrevClicked()
209 void GuiSearchWidget::replaceClicked(bool const backwards)
211 docstring const needle = qstring_to_ucs4(findCO->currentText());
212 docstring const repl = qstring_to_ucs4(replaceCO->currentText());
213 replace(needle, repl, caseCB->isChecked(), wordsCB->isChecked(),
214 !backwards, false, wrapCB->isChecked());
215 uniqueInsert(findCO, findCO->currentText());
216 uniqueInsert(replaceCO, replaceCO->currentText());
220 void GuiSearchWidget::replacePrevClicked()
222 replaceClicked(true);
226 void GuiSearchWidget::replaceallClicked()
228 replace(qstring_to_ucs4(findCO->currentText()),
229 qstring_to_ucs4(replaceCO->currentText()),
230 caseCB->isChecked(), wordsCB->isChecked(), true, true, true);
231 uniqueInsert(findCO, findCO->currentText());
232 uniqueInsert(replaceCO, replaceCO->currentText());
236 void GuiSearchWidget::find(docstring const & search, bool casesensitive,
237 bool matchword, bool forward, bool instant,
240 docstring const sdata =
241 find2string(search, casesensitive, matchword,
242 forward, wrap, instant);
244 dispatch(FuncRequest(LFUN_WORD_FIND, sdata));
248 void GuiSearchWidget::replace(docstring const & search, docstring const & replace,
249 bool casesensitive, bool matchword,
250 bool forward, bool all, bool wrap)
252 docstring const sdata =
253 replace2string(replace, search, casesensitive,
254 matchword, all, forward, wrap);
255 dispatch(FuncRequest(LFUN_WORD_REPLACE, sdata));
258 void GuiSearchWidget::saveSession(QSettings & settings, QString const & session_key) const
260 settings.setValue(session_key + "/casesensitive", caseCB->isChecked());
261 settings.setValue(session_key + "/words", wordsCB->isChecked());
262 settings.setValue(session_key + "/instant", instantSearchCB->isChecked());
263 settings.setValue(session_key + "/wrap", wrapCB->isChecked());
264 settings.setValue(session_key + "/minimized", minimized_);
268 void GuiSearchWidget::restoreSession(QString const & session_key)
271 caseCB->setChecked(settings.value(session_key + "/casesensitive", false).toBool());
272 wordsCB->setChecked(settings.value(session_key + "/words", false).toBool());
273 instantSearchCB->setChecked(settings.value(session_key + "/instant", false).toBool());
274 wrapCB->setChecked(settings.value(session_key + "/wrap", false).toBool());
275 minimized_ = settings.value(session_key + "/minimized", false).toBool();
276 // initialize hidings
277 minimizeClicked(false);
281 GuiSearch::GuiSearch(GuiView & parent, Qt::DockWidgetArea area, Qt::WindowFlags flags)
282 : DockView(parent, "findreplace", qt_("Search and Replace"), area, flags),
283 widget_(new GuiSearchWidget(this))
286 widget_->setBufferView(bufferview());
287 setFocusProxy(widget_->findCO);
289 connect(widget_, SIGNAL(needTitleBarUpdate()), this, SLOT(updateTitle()));
290 connect(widget_, SIGNAL(needSizeUpdate()), this, SLOT(updateSize()));
293 void GuiSearch::onBufferViewChanged()
295 widget_->setEnabled(static_cast<bool>(bufferview()));
296 widget_->setBufferView(bufferview());
300 void GuiSearch::updateView()
307 void GuiSearch::saveSession(QSettings & settings) const
309 Dialog::saveSession(settings);
310 widget_->saveSession(settings, sessionKey());
314 void GuiSearch::restoreSession()
316 DockView::restoreSession();
317 widget_->restoreSession(sessionKey());
321 void GuiSearch::updateTitle()
323 if (widget_->isMinimized()) {
325 setTitleBarWidget(new QWidget());
326 titleBarWidget()->hide();
329 setTitleBarWidget(nullptr);
333 void GuiSearch::updateSize()
335 widget_->setFixedHeight(widget_->sizeHint().height());
336 if (widget_->isMinimized())
337 setFixedHeight(widget_->sizeHint().height());
339 // undo setFixedHeight
340 setMaximumHeight(QWIDGETSIZE_MAX);
347 } // namespace frontend
351 #include "moc_GuiSearch.cpp"