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 "GuiSearch.h"
18 #include "qt_helpers.h"
19 #include "FuncRequest.h"
21 #include "BufferView.h"
24 #include "FuncRequest.h"
26 #include "GuiKeySymbol.h"
29 #include "support/debug.h"
30 #include "support/gettext.h"
31 #include "frontends/alert.h"
36 #include "QSizePolicy"
45 static void uniqueInsert(QComboBox * box, QString const & text)
47 for (int i = box->count(); --i >= 0; )
48 if (box->itemText(i) == text)
51 box->insertItem(0, text);
55 GuiSearchWidget::GuiSearchWidget(QWidget * parent)
60 // fix height to minimum
61 setFixedHeight(sizeHint().height());
63 // align items in grid on top
64 gridLayout->setAlignment(Qt::AlignTop);
66 connect(findPB, SIGNAL(clicked()), this, SLOT(findClicked()));
67 connect(findPrevPB, SIGNAL(clicked()), this, SLOT(findPrevClicked()));
68 connect(minimizePB, SIGNAL(clicked()), this, SLOT(minimizeClicked()));
69 connect(replacePB, SIGNAL(clicked()), this, SLOT(replaceClicked()));
70 connect(replacePrevPB, SIGNAL(clicked()), this, SLOT(replacePrevClicked()));
71 connect(replaceallPB, SIGNAL(clicked()), this, SLOT(replaceallClicked()));
72 connect(findCO, SIGNAL(editTextChanged(QString)),
73 this, SLOT(findChanged()));
75 setFocusProxy(findCO);
77 findCO->setCompleter(0);
78 replaceCO->setCompleter(0);
80 replacePB->setEnabled(false);
81 replacePrevPB->setEnabled(false);
82 replaceallPB->setEnabled(false);
86 void GuiSearchWidget::keyPressEvent(QKeyEvent * ev)
89 setKeySymbol(&sym, ev);
91 // catch Return and Shift-Return
92 if (ev->key() == Qt::Key_Return) {
93 findClicked(ev->modifiers() == Qt::ShiftModifier);
97 // we catch the key sequences for forward and backwards search
99 KeyModifier mod = lyx::q_key_state(ev->modifiers());
100 KeySequence keyseq(&theTopLevelKeymap(), &theTopLevelKeymap());
101 FuncRequest fr = keyseq.addkey(sym, mod);
102 if (fr == FuncRequest(LFUN_WORD_FIND_FORWARD) || fr == FuncRequest(LFUN_WORD_FIND)) {
106 if (fr == FuncRequest(LFUN_WORD_FIND_BACKWARD)) {
110 if (fr == FuncRequest(LFUN_DIALOG_TOGGLE, "findreplace")) {
115 QWidget::keyPressEvent(ev);
119 void GuiSearchWidget::minimizeClicked(bool const toggle)
122 minimized_ = !minimized_;
124 replaceLA->setHidden(minimized_);
125 replaceCO->setHidden(minimized_);
126 replacePB->setHidden(minimized_);
127 replacePrevPB->setHidden(minimized_);
128 replaceallPB->setHidden(minimized_);
129 wordsCB->setHidden(minimized_);
130 caseCB->setHidden(minimized_);
131 CBGroupBox->setHidden(minimized_);
133 minimizePB->setText(qt_("Ex&pand"));
134 minimizePB->setToolTip("Show replace and option widgets");
136 minimizePB->setText(qt_("&Minimize"));
137 minimizePB->setToolTip("Hide replace and option widgets");
140 Q_EMIT needSizeUpdate();
141 Q_EMIT needTitleBarUpdate();
145 void GuiSearchWidget::showEvent(QShowEvent * e)
149 findCO->lineEdit()->selectAll();
150 QWidget::showEvent(e);
154 void GuiSearchWidget::findChanged()
156 findPB->setEnabled(!findCO->currentText().isEmpty());
157 findPrevPB->setEnabled(!findCO->currentText().isEmpty());
158 bool const replace = !findCO->currentText().isEmpty()
159 && bv_ && !bv_->buffer().isReadonly();
160 replacePB->setEnabled(replace);
161 replacePrevPB->setEnabled(replace);
162 replaceallPB->setEnabled(replace);
163 replaceLA->setEnabled(replace);
164 replaceCO->setEnabled(replace);
168 void GuiSearchWidget::findClicked(bool const backwards)
170 docstring const needle = qstring_to_ucs4(findCO->currentText());
171 find(needle, caseCB->isChecked(), wordsCB->isChecked(), !backwards);
172 uniqueInsert(findCO, findCO->currentText());
173 findCO->lineEdit()->selectAll();
177 void GuiSearchWidget::findPrevClicked()
183 void GuiSearchWidget::replaceClicked(bool const backwards)
185 docstring const needle = qstring_to_ucs4(findCO->currentText());
186 docstring const repl = qstring_to_ucs4(replaceCO->currentText());
187 replace(needle, repl, caseCB->isChecked(), wordsCB->isChecked(),
189 uniqueInsert(findCO, findCO->currentText());
190 uniqueInsert(replaceCO, replaceCO->currentText());
194 void GuiSearchWidget::replacePrevClicked()
196 replaceClicked(true);
200 void GuiSearchWidget::replaceallClicked()
202 replace(qstring_to_ucs4(findCO->currentText()),
203 qstring_to_ucs4(replaceCO->currentText()),
204 caseCB->isChecked(), wordsCB->isChecked(), true, true);
205 uniqueInsert(findCO, findCO->currentText());
206 uniqueInsert(replaceCO, replaceCO->currentText());
210 void GuiSearchWidget::find(docstring const & search, bool casesensitive,
211 bool matchword, bool forward)
213 docstring const sdata =
214 find2string(search, casesensitive, matchword, forward);
215 dispatch(FuncRequest(LFUN_WORD_FIND, sdata));
219 void GuiSearchWidget::replace(docstring const & search, docstring const & replace,
220 bool casesensitive, bool matchword,
221 bool forward, bool all)
223 docstring const sdata =
224 replace2string(replace, search, casesensitive,
225 matchword, all, forward);
226 dispatch(FuncRequest(LFUN_WORD_REPLACE, sdata));
229 void GuiSearchWidget::saveSession(QSettings & settings, QString const & session_key) const
231 settings.setValue(session_key + "/casesensitive", caseCB->isChecked());
232 settings.setValue(session_key + "/words", wordsCB->isChecked());
233 settings.setValue(session_key + "/minimized", minimized_);
237 void GuiSearchWidget::restoreSession(QString const & session_key)
240 caseCB->setChecked(settings.value(session_key + "/casesensitive", false).toBool());
241 wordsCB->setChecked(settings.value(session_key + "/words", false).toBool());
242 minimized_ = settings.value(session_key + "/minimized", false).toBool();
243 // initialize hidings
244 minimizeClicked(false);
248 GuiSearch::GuiSearch(GuiView & parent, Qt::DockWidgetArea area, Qt::WindowFlags flags)
249 : DockView(parent, "findreplace", qt_("Search and Replace"), area, flags),
250 widget_(new GuiSearchWidget(this))
253 widget_->setBufferView(bufferview());
254 setFocusProxy(widget_->findCO);
256 connect(widget_, SIGNAL(needTitleBarUpdate()), this, SLOT(updateTitle()));
257 connect(widget_, SIGNAL(needSizeUpdate()), this, SLOT(updateSize()));
260 void GuiSearch::onBufferViewChanged()
262 widget_->setEnabled((bool)bufferview());
263 widget_->setBufferView(bufferview());
267 void GuiSearch::updateView()
274 void GuiSearch::saveSession(QSettings & settings) const
276 Dialog::saveSession(settings);
277 widget_->saveSession(settings, sessionKey());
281 void GuiSearch::restoreSession()
283 DockView::restoreSession();
284 widget_->restoreSession(sessionKey());
288 void GuiSearch::updateTitle()
290 if (widget_->isMinimized()) {
292 setTitleBarWidget(new QWidget());
293 titleBarWidget()->hide();
296 setTitleBarWidget(nullptr);
300 void GuiSearch::updateSize()
302 widget_->setFixedHeight(widget_->sizeHint().height());
303 if (widget_->isMinimized())
304 // FIXME still a bit too tall
305 setFixedHeight(widget_->sizeHint().height());
307 // undo setFixedHeight
308 setMaximumHeight(QWIDGETSIZE_MAX);
315 } // namespace frontend
319 #include "moc_GuiSearch.cpp"