]> git.lyx.org Git - lyx.git/blob - src/frontends/qt/GuiSearch.cpp
#12423 fix a focus change problem
[lyx.git] / src / frontends / qt / GuiSearch.cpp
1 /**
2  * \file GuiSearch.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author John Levon
7  * \author Edwin Leuven
8  * \author Angus Leeming
9  *
10  * Full author contact details are available in file CREDITS.
11  */
12
13 #include <config.h>
14
15 #include "GuiApplication.h"
16 #include "GuiSearch.h"
17
18 #include "lyxfind.h"
19 #include "qt_helpers.h"
20 #include "FuncRequest.h"
21 #include "LyX.h"
22 #include "BufferView.h"
23 #include "Buffer.h"
24 #include "Cursor.h"
25 #include "FuncRequest.h"
26 #include "KeyMap.h"
27 #include "GuiKeySymbol.h"
28 #include "GuiView.h"
29
30 #include "qt_helpers.h"
31 #include "support/filetools.h"
32 #include "support/debug.h"
33 #include "support/gettext.h"
34 #include "support/FileName.h"
35 #include "frontends/alert.h"
36 #include "frontends/Clipboard.h"
37
38 #include <QClipboard>
39 #include <QPainter>
40 #include <QLineEdit>
41 #include <QSettings>
42 #include <QHideEvent>
43 #include <QShowEvent>
44 #include "QSizePolicy"
45 #if QT_VERSION >= 0x050000
46 #include <QSvgRenderer>
47 #endif
48
49 using namespace std;
50 using namespace lyx::support;
51
52 using lyx::KeySymbol;
53
54 namespace lyx {
55 namespace frontend {
56
57 static void uniqueInsert(QComboBox * box, QString const & text)
58 {
59         for (int i = box->count(); --i >= 0; )
60                 if (box->itemText(i) == text)
61                         return;
62
63         box->insertItem(0, text);
64 }
65
66
67 GuiSearchWidget::GuiSearchWidget(QWidget * parent, GuiView & view)
68         :       QWidget(parent), view_(view)
69 {
70         setupUi(this);
71
72         // fix height to minimum
73         setFixedHeight(sizeHint().height());
74
75         // align items in grid on top
76         gridLayout->setAlignment(Qt::AlignTop);
77
78         connect(findPB, SIGNAL(clicked()), this, SLOT(findClicked()));
79         connect(findPrevPB, SIGNAL(clicked()), this, SLOT(findPrevClicked()));
80         connect(minimizePB, SIGNAL(clicked()), this, SLOT(minimizeClicked()));
81         connect(replacePB, SIGNAL(clicked()), this, SLOT(replaceClicked()));
82         connect(replacePrevPB, SIGNAL(clicked()), this, SLOT(replacePrevClicked()));
83         connect(replaceallPB, SIGNAL(clicked()), this, SLOT(replaceallClicked()));
84         connect(findCO, SIGNAL(editTextChanged(QString)),
85                 this, SLOT(findChanged()));
86         if(qApp->clipboard()->supportsFindBuffer()) {
87                 connect(qApp->clipboard(), SIGNAL(findBufferChanged()),
88                         this, SLOT(findBufferChanged()));
89                 findBufferChanged();
90         }
91
92         setFocusProxy(findCO);
93
94         // Use a FancyLineEdit due to the indicator icons
95         findLE_ = new FancyLineEdit(this);
96         findCO->setLineEdit(findLE_);
97
98         // And a menu in minimal mode
99         menu_ = new QMenu();
100         act_casesense_ = new QAction(qt_("&Case sensitive[[search]]"), this);
101         act_casesense_->setCheckable(true);
102         act_wholewords_ = new QAction(qt_("Wh&ole words"), this);
103         act_wholewords_->setCheckable(true);
104         act_selection_ = new QAction(qt_("Selection onl&y"), this);
105         act_selection_->setCheckable(true);
106         act_immediate_ = new QAction(qt_("Search as yo&u type"), this);
107         act_immediate_->setCheckable(true);
108         act_wrap_ = new QAction(qt_("&Wrap"), this);
109         act_wrap_->setCheckable(true);
110
111         menu_->addAction(act_casesense_);
112         menu_->addAction(act_wholewords_);
113         menu_->addAction(act_selection_);
114         menu_->addAction(act_immediate_);
115         menu_->addAction(act_wrap_);
116         findLE_->setButtonMenu(FancyLineEdit::Right, menu_);
117
118         connect(act_casesense_, SIGNAL(triggered()), this, SLOT(caseSenseActTriggered()));
119         connect(act_wholewords_, SIGNAL(triggered()), this, SLOT(wholeWordsActTriggered()));
120         connect(act_selection_, SIGNAL(triggered()), this, SLOT(searchSelActTriggered()));
121         connect(act_immediate_, SIGNAL(triggered()), this, SLOT(immediateActTriggered()));
122         connect(act_wrap_, SIGNAL(triggered()), this, SLOT(wrapActTriggered()));
123
124         findCO->setCompleter(nullptr);
125         replaceCO->setCompleter(nullptr);
126
127         replacePB->setEnabled(false);
128         replacePrevPB->setEnabled(false);
129         replaceallPB->setEnabled(false);
130 }
131
132
133 bool GuiSearchWidget::initialiseParams(std::string const & str)
134 {
135         if (!str.empty())
136                 findCO->lineEdit()->setText(toqstr(str));
137         return true;
138 }
139
140
141 void GuiSearchWidget::keyPressEvent(QKeyEvent * ev)
142 {
143         KeySymbol sym;
144         setKeySymbol(&sym, ev);
145
146         // catch Return and Shift-Return
147         if (ev->key() == Qt::Key_Return || ev->key() == Qt::Key_Enter) {
148                 doFind(ev->modifiers() == Qt::ShiftModifier);
149                 return;
150         }
151         if (ev->key() == Qt::Key_Escape) {
152                 dispatch(FuncRequest(LFUN_DIALOG_HIDE, "findreplace"));
153                 view_.setFocus();
154                 bv_->buffer().updateBuffer();
155                 return;
156         }
157
158         // we catch the key sequences for forward and backwards search
159         if (sym.isOK()) {
160                 KeyModifier mod = lyx::q_key_state(ev->modifiers());
161                 KeySequence keyseq(&theTopLevelKeymap(), &theTopLevelKeymap());
162                 FuncRequest fr = keyseq.addkey(sym, mod);
163                 if (fr == FuncRequest(LFUN_WORD_FIND_FORWARD)
164                     || fr == FuncRequest(LFUN_WORD_FIND)) {
165                         doFind();
166                         return;
167                 }
168                 if (fr == FuncRequest(LFUN_WORD_FIND_BACKWARD)) {
169                         doFind(true);
170                         return;
171                 }
172                 if (fr == FuncRequest(LFUN_DIALOG_TOGGLE, "findreplace")) {
173                         dispatch(fr);
174                         return;
175                 }
176         }
177         QWidget::keyPressEvent(ev);
178 }
179
180
181 void GuiSearchWidget::minimizeClicked(bool const toggle)
182 {
183         if (toggle)
184                 minimized_ = !minimized_;
185
186         replaceLA->setHidden(minimized_);
187         replaceCO->setHidden(minimized_);
188         replacePB->setHidden(minimized_);
189         replacePrevPB->setHidden(minimized_);
190         replaceallPB->setHidden(minimized_);
191         CBFrame->setHidden(minimized_);
192
193         if (minimized_) {
194                 minimizePB->setText(qt_("Ex&pand"));
195                 minimizePB->setToolTip(qt_("Show replace and option widgets"));
196                 // update menu items
197                 blockSignals(true);
198                 act_casesense_->setChecked(caseCB->isChecked());
199                 act_immediate_->setChecked(instantSearchCB->isChecked());
200                 act_selection_->setChecked(selectionCB->isChecked());
201                 act_wholewords_->setChecked(wordsCB->isChecked());
202                 act_wrap_->setChecked(wrapCB->isChecked());
203                 blockSignals(false);
204         } else {
205                 minimizePB->setText(qt_("&Minimize"));
206                 minimizePB->setToolTip(qt_("Hide replace and option widgets"));
207         }
208
209         Q_EMIT needSizeUpdate();
210         Q_EMIT needTitleBarUpdate();
211         handleIndicators();
212 }
213
214
215 void GuiSearchWidget::handleIndicators()
216 {
217         findLE_->setButtonVisible(FancyLineEdit::Right, minimized_);
218
219         QString tip;
220
221         if (minimized_) {
222                 int pms = 0;
223                 if (caseCB->isChecked())
224                         ++pms;
225                 if (wordsCB->isChecked())
226                         ++pms;
227                 if (selectionCB->isChecked())
228                         ++pms;
229                 if (instantSearchCB->isChecked())
230                         ++pms;
231                 if (wrapCB->isChecked())
232                         ++pms;
233
234                 bool const dark_mode = guiApp && guiApp->isInDarkMode();
235                 qreal dpr = 1.0;
236 #if QT_VERSION >= 0x050000
237                 // Consider device/pixel ratio (HiDPI)
238                 if (guiApp && guiApp->currentView())
239                         dpr = guiApp->currentView()->devicePixelRatio();
240 #endif
241                 QString imagedir = "images/";
242                 QPixmap bpixmap = getPixmap("images/", "search-options", "svgz,png");
243                 QPixmap pm = bpixmap;
244
245                 if (pms > 0) {
246                         int const gap = 3;
247                         QPixmap scaled_pm = QPixmap(bpixmap.size() * dpr);
248                         pm = QPixmap(pms * scaled_pm.width() + ((pms - 1) * gap),
249                                      scaled_pm.height());
250                         pm.fill(Qt::transparent);
251                         QPainter painter(&pm);
252                         int x = 0;
253                         
254                         tip = qt_("Active options:");
255                         tip += "<ul>";
256                         if (caseCB->isChecked()) {
257                                 tip += "<li>" + qt_("Case sensitive search");
258                                 QPixmap spixmap = getPixmap("images/", "search-case-sensitive", "svgz,png");
259 #if QT_VERSION < 0x050000
260                                 painter.drawPixmap(x, 0, spixmap);
261 #else
262                                 // With Qt5, we render SVG directly for HiDPI scalability
263                                 FileName fname = imageLibFileSearch(imagedir, "search-case-sensitive", "svgz,png");
264                                 QString fpath = toqstr(fname.absFileName());
265                                 if (!fpath.isEmpty()) {
266                                         QSvgRenderer svgRenderer(fpath);
267                                         if (svgRenderer.isValid())
268                                                 svgRenderer.render(&painter, QRectF(0, 0, spixmap.width() * dpr,
269                                                                                     spixmap.height() * dpr));
270                                 }
271 #endif
272                                 x += (spixmap.width() * dpr) + gap;
273                         }
274                         if (wordsCB->isChecked()) {
275                                 tip += "<li>" + qt_("Whole words only");
276                                 QPixmap spixmap = getPixmap("images/", "search-whole-words", "svgz,png");
277 #if QT_VERSION < 0x050000
278                                 painter.drawPixmap(x, 0, spixmap);
279 #else
280                                 FileName fname = imageLibFileSearch(imagedir, "search-whole-words", "svgz,png");
281                                 QString fpath = toqstr(fname.absFileName());
282                                 if (!fpath.isEmpty()) {
283                                         QSvgRenderer svgRenderer(fpath);
284                                         if (svgRenderer.isValid())
285                                                 svgRenderer.render(&painter, QRectF(x, 0, spixmap.width() * dpr,
286                                                                                     spixmap.height() * dpr));
287                                 }
288 #endif
289                                 x += (spixmap.width() * dpr) + gap;
290                         }
291                         if (selectionCB->isChecked()) {
292                                 tip += "<li>" + qt_("Search only in selection");
293                                 QPixmap spixmap = getPixmap("images/", "search-selection", "svgz,png");
294 #if QT_VERSION < 0x050000
295                                 painter.drawPixmap(x, 0, spixmap);
296 #else
297                                 FileName fname = imageLibFileSearch(imagedir, "search-selection", "svgz,png");
298                                 QString fpath = toqstr(fname.absFileName());
299                                 if (!fpath.isEmpty()) {
300                                         QSvgRenderer svgRenderer(fpath);
301                                         if (svgRenderer.isValid())
302                                                 svgRenderer.render(&painter, QRectF(x, 0, spixmap.width() * dpr,
303                                                                                     spixmap.height() * dpr));
304                                 }
305 #endif
306                                 x += (spixmap.width() * dpr) + gap;
307                         }
308                         if (instantSearchCB->isChecked()) {
309                                 tip += "<li>" + qt_("Search as you type");
310                                 QPixmap spixmap = getPixmap("images/", "search-instant", "svgz,png");
311 #if QT_VERSION < 0x050000
312                                 painter.drawPixmap(x, 0, spixmap);
313 #else
314                                 FileName fname = imageLibFileSearch(imagedir, "search-instant", "svgz,png");
315                                 QString fpath = toqstr(fname.absFileName());
316                                 if (!fpath.isEmpty()) {
317                                         QSvgRenderer svgRenderer(fpath);
318                                         if (svgRenderer.isValid())
319                                                 svgRenderer.render(&painter, QRectF(x, 0, spixmap.width() * dpr,
320                                                                                     spixmap.height() * dpr));
321                                 }
322 #endif
323                                 x += (spixmap.width() * dpr) + gap;
324                         }
325                         if (wrapCB->isChecked()) {
326                                 tip += "<li>" + qt_("Wrap search");
327                                 QPixmap spixmap = getPixmap("images/", "search-wrap", "svgz,png");
328 #if QT_VERSION < 0x050000
329                                 painter.drawPixmap(x, 0, spixmap);
330 #else
331                                 FileName fname = imageLibFileSearch(imagedir, "search-wrap", "svgz,png");
332                                 QString fpath = toqstr(fname.absFileName());
333                                 if (!fpath.isEmpty()) {
334                                         QSvgRenderer svgRenderer(fpath);
335                                         if (svgRenderer.isValid())
336                                                 svgRenderer.render(&painter, QRectF(x, 0, spixmap.width() * dpr,
337                                                                                     spixmap.height() * dpr));
338                                 }
339 #endif
340                                 x += (spixmap.width() * dpr) + gap;
341                         }
342                         tip += "</ul>";
343 #if QT_VERSION >= 0x050000
344                         pm.setDevicePixelRatio(dpr);
345 #endif
346                         painter.end();
347                 } else {
348                         tip = qt_("Click here to change search options");
349 #if QT_VERSION >= 0x050000
350                         // With Qt5, we render SVG directly for HiDPI scalability
351                         FileName fname = imageLibFileSearch(imagedir, "search-options", "svgz,png");
352                         QString fpath = toqstr(fname.absFileName());
353                         if (!fpath.isEmpty()) {
354                                 QSvgRenderer svgRenderer(fpath);
355                                 if (svgRenderer.isValid()) {
356                                         pm = QPixmap(bpixmap.size() * dpr);
357                                         pm.fill(Qt::transparent);
358                                         QPainter painter(&pm);
359                                         svgRenderer.render(&painter);
360                                         pm.setDevicePixelRatio(dpr);
361                                 }
362                         }
363 #endif
364                 }
365                 if (dark_mode) {
366                         QImage img = pm.toImage();
367                         img.invertPixels();
368                         pm.convertFromImage(img);
369                 }
370                 findLE_->setButtonPixmap(FancyLineEdit::Right, pm);
371         }
372         findLE_->setButtonToolTip(FancyLineEdit::Right, tip);
373 }
374
375
376 void GuiSearchWidget::caseSenseActTriggered()
377 {
378         caseCB->setChecked(act_casesense_->isChecked());
379         handleIndicators();
380 }
381
382
383 void GuiSearchWidget::wholeWordsActTriggered()
384 {
385         wordsCB->setChecked(act_wholewords_->isChecked());
386         handleIndicators();
387 }
388
389
390 void GuiSearchWidget::searchSelActTriggered()
391 {
392         selectionCB->setChecked(act_selection_->isChecked());
393         handleIndicators();
394 }
395
396
397 void GuiSearchWidget::immediateActTriggered()
398 {
399         instantSearchCB->setChecked(act_immediate_->isChecked());
400         handleIndicators();
401 }
402
403
404 void GuiSearchWidget::wrapActTriggered()
405 {
406         wrapCB->setChecked(act_wrap_->isChecked());
407         handleIndicators();
408 }
409
410
411 void GuiSearchWidget::showEvent(QShowEvent * e)
412 {
413         findChanged();
414         findPB->setFocus();
415         findCO->lineEdit()->selectAll();
416         QWidget::showEvent(e);
417 }
418
419
420 void GuiSearchWidget::hideEvent(QHideEvent *)
421 {
422         dispatch(FuncRequest(LFUN_DIALOG_HIDE, "findreplace"));
423         view_.setFocus();
424         // update toolbar status
425         if (bv_)
426                 bv_->buffer().updateBuffer();
427 }
428
429
430 void GuiSearchWidget::findBufferChanged()
431 {
432         docstring search = theClipboard().getFindBuffer();
433         // update from find buffer, but only if the strings differ (else we
434         // might end up in loops with search as you type)
435         if (!search.empty() && toqstr(search) != findCO->lineEdit()->text()) {
436                 LYXERR(Debug::CLIPBOARD, "from findbuffer: " << search);
437                 findCO->lineEdit()->selectAll();
438                 findCO->lineEdit()->insert(toqstr(search));
439                 findCO->lineEdit()->selectAll();
440         }
441 }
442
443
444 void GuiSearchWidget::findChanged()
445 {
446         bool const emptytext = findCO->currentText().isEmpty();
447         findPB->setEnabled(!emptytext);
448         findPrevPB->setEnabled(!emptytext);
449         bool const replace = !emptytext && bv_ && !bv_->buffer().isReadonly();
450         replacePB->setEnabled(replace);
451         replacePrevPB->setEnabled(replace);
452         replaceallPB->setEnabled(replace);
453         if (instantSearchCB->isChecked())
454                 doFind(false, true);
455 }
456
457
458 void GuiSearchWidget::findClicked()
459 {
460         doFind();
461 }
462
463
464 void GuiSearchWidget::findPrevClicked()
465 {
466         doFind(true);
467 }
468
469
470 void GuiSearchWidget::replaceClicked()
471 {
472         doReplace();
473 }
474
475
476 void GuiSearchWidget::replacePrevClicked()
477 {
478         doReplace(true);
479 }
480
481
482 void GuiSearchWidget::replaceallClicked()
483 {
484         replace(qstring_to_ucs4(findCO->currentText()),
485                 qstring_to_ucs4(replaceCO->currentText()),
486                 caseCB->isChecked(), wordsCB->isChecked(),
487                 true, true, true, selectionCB->isChecked());
488         uniqueInsert(findCO, findCO->currentText());
489         uniqueInsert(replaceCO, replaceCO->currentText());
490 }
491
492
493 void GuiSearchWidget::doFind(bool const backwards, bool const instant)
494 {
495         docstring const needle = qstring_to_ucs4(findCO->currentText());
496         find(needle, caseCB->isChecked(), wordsCB->isChecked(), !backwards,
497              instant, wrapCB->isChecked(), selectionCB->isChecked());
498         uniqueInsert(findCO, findCO->currentText());
499         if (!instant)
500                 findCO->lineEdit()->selectAll();
501 }
502
503
504 void GuiSearchWidget::find(docstring const & search, bool casesensitive,
505                            bool matchword, bool forward, bool instant,
506                            bool wrap, bool onlysel)
507 {
508         docstring const sdata =
509                 find2string(search, casesensitive, matchword,
510                             forward, wrap, instant, onlysel);
511
512         dispatch(FuncRequest(LFUN_WORD_FIND, sdata));
513 }
514
515
516 void GuiSearchWidget::doReplace(bool const backwards)
517 {
518         docstring const needle = qstring_to_ucs4(findCO->currentText());
519         docstring const repl = qstring_to_ucs4(replaceCO->currentText());
520         replace(needle, repl, caseCB->isChecked(), wordsCB->isChecked(),
521                 !backwards, false, wrapCB->isChecked(), selectionCB->isChecked());
522         uniqueInsert(findCO, findCO->currentText());
523         uniqueInsert(replaceCO, replaceCO->currentText());
524 }
525
526
527 void GuiSearchWidget::replace(docstring const & search, docstring const & replace,
528                             bool casesensitive, bool matchword,
529                             bool forward, bool all, bool wrap, bool onlysel)
530 {
531         docstring const sdata =
532                 replace2string(replace, search, casesensitive,
533                                matchword, all, forward, true, wrap, onlysel);
534
535         dispatch(FuncRequest(LFUN_WORD_REPLACE, sdata));
536 }
537
538 void GuiSearchWidget::saveSession(QSettings & settings, QString const & session_key) const
539 {
540         settings.setValue(session_key + "/casesensitive", caseCB->isChecked());
541         settings.setValue(session_key + "/words", wordsCB->isChecked());
542         settings.setValue(session_key + "/instant", instantSearchCB->isChecked());
543         settings.setValue(session_key + "/wrap", wrapCB->isChecked());
544         settings.setValue(session_key + "/selection", selectionCB->isChecked());
545         settings.setValue(session_key + "/minimized", minimized_);
546 }
547
548
549 void GuiSearchWidget::restoreSession(QString const & session_key)
550 {
551         QSettings settings;
552         caseCB->setChecked(settings.value(session_key + "/casesensitive", false).toBool());
553         act_casesense_->setChecked(settings.value(session_key + "/casesensitive", false).toBool());
554         wordsCB->setChecked(settings.value(session_key + "/words", false).toBool());
555         act_wholewords_->setChecked(settings.value(session_key + "/words", false).toBool());
556         instantSearchCB->setChecked(settings.value(session_key + "/instant", false).toBool());
557         act_immediate_->setChecked(settings.value(session_key + "/instant", false).toBool());
558         wrapCB->setChecked(settings.value(session_key + "/wrap", true).toBool());
559         act_wrap_->setChecked(settings.value(session_key + "/wrap", true).toBool());
560         selectionCB->setChecked(settings.value(session_key + "/selection", false).toBool());
561         act_selection_->setChecked(settings.value(session_key + "/selection", false).toBool());
562         minimized_ = settings.value(session_key + "/minimized", false).toBool();
563         // initialize hidings
564         minimizeClicked(false);
565 }
566
567
568 GuiSearch::GuiSearch(GuiView & parent, Qt::DockWidgetArea area, Qt::WindowFlags flags)
569         : DockView(parent, "findreplace", qt_("Search and Replace"), area, flags),
570           widget_(new GuiSearchWidget(this, parent))
571 {
572         setWidget(widget_);
573         widget_->setBufferView(bufferview());
574         setFocusProxy(widget_);
575
576         connect(widget_, SIGNAL(needTitleBarUpdate()), this, SLOT(updateTitle()));
577         connect(widget_, SIGNAL(needSizeUpdate()), this, SLOT(updateSize()));
578 }
579
580
581 void GuiSearch::mousePressEvent(QMouseEvent * event)
582 {
583         if (isFloating() && event->button() == Qt::LeftButton) {
584 #if QT_VERSION >= 0x060000
585                 dragPosition = event->globalPosition().toPoint() - frameGeometry().topLeft();
586 #else
587                 dragPosition = event->globalPos() - frameGeometry().topLeft();
588 #endif
589                 event->accept();
590         } else
591                 DockView::mousePressEvent(event);
592 }
593
594
595 void GuiSearch::mouseMoveEvent(QMouseEvent * event)
596 {
597         if (isFloating() && event->buttons() & Qt::LeftButton) {
598 #if QT_VERSION >= 0x060000
599                 move(event->globalPosition().toPoint() - dragPosition);
600 #else
601                 move(event->globalPos() - dragPosition);
602 #endif
603                 event->accept();
604         } else
605                 DockView::mouseMoveEvent(event);
606 }
607
608
609 void GuiSearch::mouseDoubleClickEvent(QMouseEvent * event)
610 {
611         if (event->button() == Qt::LeftButton)
612                 setFloating(!isFloating());
613         else
614                 DockView::mouseDoubleClickEvent(event);
615 }
616
617
618 void GuiSearch::onBufferViewChanged()
619 {
620         widget_->setEnabled(static_cast<bool>(bufferview()));
621         widget_->setBufferView(bufferview());
622 }
623
624
625 void GuiSearch::updateView()
626 {
627         updateTitle();
628         updateSize();
629 }
630
631
632 void GuiSearch::saveSession(QSettings & settings) const
633 {
634         Dialog::saveSession(settings);
635         widget_->saveSession(settings, sessionKey());
636 }
637
638
639 void GuiSearch::restoreSession()
640 {
641         DockView::restoreSession();
642         widget_->restoreSession(sessionKey());
643 }
644
645
646 void GuiSearch::updateTitle()
647 {
648         if (widget_->isMinimized()) {
649                 // remove title bar
650                 setTitleBarWidget(new QWidget());
651                 titleBarWidget()->hide();
652         } else if (titleBarWidget()) {
653                 // restore title bar
654                 setTitleBarWidget(nullptr);
655         }
656 }
657
658
659 void GuiSearch::updateSize()
660 {
661         widget_->setFixedHeight(widget_->sizeHint().height());
662         if (widget_->isMinimized())
663                 setFixedHeight(widget_->sizeHint().height());
664         else {
665                 // undo setFixedHeight
666                 setMaximumHeight(QWIDGETSIZE_MAX);
667                 setMinimumHeight(0);
668         }
669         update();
670 }
671
672
673 } // namespace frontend
674 } // namespace lyx
675
676
677 #include "moc_GuiSearch.cpp"