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_);
132 minimizePB->setText(qt_("Ex&pand"));
133 minimizePB->setToolTip("Show replace and option widgets");
135 minimizePB->setText(qt_("&Minimize"));
136 minimizePB->setToolTip("Hide replace and option widgets");
139 Q_EMIT needSizeUpdate();
140 Q_EMIT needTitleBarUpdate();
144 void GuiSearchWidget::showEvent(QShowEvent * e)
148 findCO->lineEdit()->selectAll();
149 QWidget::showEvent(e);
153 void GuiSearchWidget::findChanged()
155 findPB->setEnabled(!findCO->currentText().isEmpty());
156 findPrevPB->setEnabled(!findCO->currentText().isEmpty());
157 bool const replace = !findCO->currentText().isEmpty()
158 && bv_ && !bv_->buffer().isReadonly();
159 replacePB->setEnabled(replace);
160 replacePrevPB->setEnabled(replace);
161 replaceallPB->setEnabled(replace);
162 replaceLA->setEnabled(replace);
163 replaceCO->setEnabled(replace);
167 void GuiSearchWidget::findClicked(bool const backwards)
169 docstring const needle = qstring_to_ucs4(findCO->currentText());
170 find(needle, caseCB->isChecked(), wordsCB->isChecked(), !backwards);
171 uniqueInsert(findCO, findCO->currentText());
172 findCO->lineEdit()->selectAll();
176 void GuiSearchWidget::findPrevClicked()
182 void GuiSearchWidget::replaceClicked(bool const backwards)
184 docstring const needle = qstring_to_ucs4(findCO->currentText());
185 docstring const repl = qstring_to_ucs4(replaceCO->currentText());
186 replace(needle, repl, caseCB->isChecked(), wordsCB->isChecked(),
188 uniqueInsert(findCO, findCO->currentText());
189 uniqueInsert(replaceCO, replaceCO->currentText());
193 void GuiSearchWidget::replacePrevClicked()
195 replaceClicked(true);
199 void GuiSearchWidget::replaceallClicked()
201 replace(qstring_to_ucs4(findCO->currentText()),
202 qstring_to_ucs4(replaceCO->currentText()),
203 caseCB->isChecked(), wordsCB->isChecked(), true, true);
204 uniqueInsert(findCO, findCO->currentText());
205 uniqueInsert(replaceCO, replaceCO->currentText());
209 void GuiSearchWidget::find(docstring const & search, bool casesensitive,
210 bool matchword, bool forward)
212 docstring const sdata =
213 find2string(search, casesensitive, matchword, forward);
214 dispatch(FuncRequest(LFUN_WORD_FIND, sdata));
218 void GuiSearchWidget::replace(docstring const & search, docstring const & replace,
219 bool casesensitive, bool matchword,
220 bool forward, bool all)
222 docstring const sdata =
223 replace2string(replace, search, casesensitive,
224 matchword, all, forward);
225 dispatch(FuncRequest(LFUN_WORD_REPLACE, sdata));
228 void GuiSearchWidget::saveSession(QSettings & settings, QString const & session_key) const
230 settings.setValue(session_key + "/casesensitive", caseCB->isChecked());
231 settings.setValue(session_key + "/words", wordsCB->isChecked());
232 settings.setValue(session_key + "/minimized", minimized_);
236 void GuiSearchWidget::restoreSession(QString const & session_key)
239 caseCB->setChecked(settings.value(session_key + "/casesensitive", false).toBool());
240 wordsCB->setChecked(settings.value(session_key + "/words", false).toBool());
241 minimized_ = settings.value(session_key + "/minimized", false).toBool();
242 // initialize hidings
243 minimizeClicked(false);
247 GuiSearch::GuiSearch(GuiView & parent, Qt::DockWidgetArea area, Qt::WindowFlags flags)
248 : DockView(parent, "findreplace", qt_("Search and Replace"), area, flags),
249 widget_(new GuiSearchWidget(this))
252 widget_->setBufferView(bufferview());
253 setFocusProxy(widget_->findCO);
255 connect(widget_, SIGNAL(needTitleBarUpdate()), this, SLOT(updateTitle()));
256 connect(widget_, SIGNAL(needSizeUpdate()), this, SLOT(updateSize()));
259 void GuiSearch::onBufferViewChanged()
261 widget_->setEnabled((bool)bufferview());
262 widget_->setBufferView(bufferview());
266 void GuiSearch::updateView()
273 void GuiSearch::saveSession(QSettings & settings) const
275 Dialog::saveSession(settings);
276 widget_->saveSession(settings, sessionKey());
280 void GuiSearch::restoreSession()
282 DockView::restoreSession();
283 widget_->restoreSession(sessionKey());
287 void GuiSearch::updateTitle()
289 if (widget_->isMinimized()) {
291 setTitleBarWidget(new QWidget());
292 titleBarWidget()->hide();
295 setTitleBarWidget(nullptr);
299 void GuiSearch::updateSize()
301 widget_->setFixedHeight(widget_->sizeHint().height());
302 if (widget_->isMinimized())
303 // FIXME still a bit too tall
304 setFixedHeight(widget_->sizeHint().height());
306 // undo setFixedHeight
307 setMaximumHeight(QWIDGETSIZE_MAX);
314 } // namespace frontend
318 #include "moc_GuiSearch.cpp"