31 #include <QKeySequence>
36 #include <ui_klfsearchbar.h>
38 #include "klfsearchbar_p.h"
138 str <<
"Pos("<<qPrintable(s);
141 if (!(desc = pos.
posdata->toDebug()).isEmpty())
142 str <<
" " << qPrintable(desc);
151 klfDbg(
"start from: base implementation, will return invalid. forward="<<forward) ;
159 pInterruptRequested = on;
236 bool equals(PosData *)
const {
return true; }
252 if (!fromPos.
valid())
260 p.
posdata =
new DummySearchPosData;
275 "target is not a valid KLFSearchable object !",
303 klfDbg(
"parent: "<<parent) ;
307 d =
new KLFSearchBarPrivate;
309 u =
new Ui::KLFSearchBar;
312 setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
314 u->txtSearch->installEventFilter(
this);
315 connect(
u->btnSearchClear, SIGNAL(clicked()),
this, SLOT(
clear()));
316 connect(
u->txtSearch, SIGNAL(textChanged(
const QString&)),
318 connect(
u->btnFindNext, SIGNAL(clicked()),
this, SLOT(
findNext()));
319 connect(
u->btnFindPrev, SIGNAL(clicked()),
this, SLOT(
findPrev()));
321 QPalette defaultpal =
u->txtSearch->palette();
322 u->txtSearch->setProperty(palettePropName(
Default).toLatin1(), QVariant::fromValue<QPalette>(defaultpal));
327 u->txtSearch->setProperty(palettePropName(
FocusOut).toLatin1(), QVariant::fromValue<QPalette>(pal0));
332 connect(
u->btnHide, SIGNAL(clicked()),
this, SLOT(hide()));
335 d->pResetTimeout = 10000;
336 connect(&d->pFocusOutResetTimer, SIGNAL(timeout()),
this, SLOT(
slotSearchReset()));
339 d->pWaitLabel->setWaitMovie(
":/pics/wait_anim.mng");
344 d->pAutoHide =
false;
346 d->pShowOverlayMode =
false;
351 d->pFocusOutText =
" "+tr(
"Hit Ctrl-F, Ctrl-S or / to start searching");
353 d->pSearchForward =
true;
355 d->pIsSearching =
false;
361 d->pIsFinding =
false;
362 d->pHasQueuedFind =
false;
363 d->pQueuedFindString =
QString();
364 d->pQueuedFindForward =
true;
366 klfDbg(
"pCurPos is "<<d->pCurPos<<
"; pLastPos is "<<d->pLastPos) ;
379 return u->txtSearch->text();
385 return p.
color(QPalette::Base);
390 return p.
color(QPalette::Base);
395 return u->btnHide->isVisible();
400 return u->lblSearch->isVisible();
410 return d->pResetTimeout;
427 pal1.
setColor(QPalette::Base, color);
428 pal1.
setColor(QPalette::Window, color);
429 pal1.
setColor(
u->txtSearch->backgroundRole(), color);
430 u->txtSearch->setProperty(palettePropName(
Found).toLatin1(), QVariant::fromValue<QPalette>(pal1));
436 pal2.
setColor(QPalette::Base, color);
437 pal2.
setColor(QPalette::Window, color);
438 pal2.
setColor(
u->txtSearch->backgroundRole(), color);
439 u->txtSearch->setProperty(palettePropName(
NotFound).toLatin1(), QVariant::fromValue<QPalette>(pal2));
449 u->lblSearch->setVisible(on);
461 d->pResetTimeout = ms;
466 #define DECLARE_SEARCH_SHORTCUT(shortcut, parent, slotmember) \
467 { QShortcut *s = new QShortcut(parent); s->setKey(QKeySequence(shortcut)); \
468 connect(s, SIGNAL(activated()), this, slotmember); }
489 "target is not a valid KLFPosSearchable object !",
496 u->txtSearch->setText(text);
506 return d->pShowOverlayMode;
510 return d->pShowOverlayRelativeGeometry;
514 return d->pFocusOutText;
528 static KLFSearchBarPrivate::HistBuffer::CurLastPosPair
531 if (hb.
size() <= offset) {
538 return esbs_get_last_pos(hb, offset+1);
540 return poslist.
last();
547 if (obj ==
u->txtSearch) {
548 if (ev->
type() == QEvent::FocusIn) {
549 klfDbg(
"focus-in event...") ;
552 }
else if (ev->
type() == QEvent::FocusOut) {
553 klfDbg(
"focus-out event...") ;
556 }
else if (ev->
type() == QEvent::KeyPress) {
557 klfDbg(
"key press event!") ;
559 if (ke->
key() == Qt::Key_Escape) {
567 if (ke->
key() == Qt::Key_Backspace) {
575 if ( ! d->esbs_histbuffer.size() ) {
580 KLFSearchBarPrivate::HistBuffer& histbuf = d->esbs_histbuffer.last();
581 if (histbuf.poslist.size() > 1) {
583 histbuf.poslist.pop_back();
584 const KLFSearchBarPrivate::HistBuffer::CurLastPosPair& pos = histbuf.poslist.last();
587 d->pCurPos = pos.cur;
588 d->pLastPos = pos.last;
591 target()->
searchPerformed(d->pSearchText, d->pCurPos.valid(), d->pCurPos);
596 d->esbs_histbuffer.pop_back();
598 if (!d->esbs_histbuffer.size()) {
603 d->pSearchText = d->esbs_histbuffer.last().str;
605 u->txtSearch->blockSignals(
true);
606 u->txtSearch->setText(d->pSearchText);
607 u->txtSearch->blockSignals(
false);
609 = d->esbs_histbuffer.last().poslist;
612 KLFSearchBarPrivate::HistBuffer::CurLastPosPair clpos = esbs_get_last_pos(d->esbs_histbuffer);
613 d->pCurPos = clpos.cur;
614 d->pLastPos = clpos.last;
619 d->pCurPos = d->pLastPos;
623 target()->
searchPerformed(d->pSearchText, d->pCurPos.valid(), d->pCurPos);
634 }
else if (ke->
key() == Qt::Key_Left || ke->
key() == Qt::Key_Right) {
637 }
else if (ke->
key() == Qt::Key_Home || ke->
key() == Qt::Key_End) {
640 }
else if (ke->
text().
size() && ke->
text()[0].isPrint()) {
647 klfDbg(
"key press, but not using e-s-b-s.");
653 return QFrame::eventFilter(obj, ev);
663 klfDbg(
"autohide="<<autohide) ;
664 d->pAutoHide = autohide;
671 klfDbg(
"setting show overlay mode to "<<overlayMode) ;
672 d->pShowOverlayMode = overlayMode;
673 setProperty(
"klfShowOverlayMode", QVariant::fromValue<bool>(d->pShowOverlayMode));
675 setProperty(
"klfTopLevelWidget", QVariant::fromValue<bool>(d->pShowOverlayMode));
677 adjustOverlayGeometry();
684 d->pShowOverlayRelativeGeometry = relativeGeometryPercent;
685 adjustOverlayGeometry();
688 int positionXPercent,
int positionYPercent)
691 QSize(widthPercent, heightPercent)));
692 adjustOverlayGeometry();
706 d->pSearchForward = forward;
709 klfDbgT(
"already are in focus state") ;
716 if (
u->txtSearch->text().isEmpty()) {
719 if (!d->pIsSearching) {
720 find(
u->txtSearch->text(), forward);
734 find(
string, d->pSearchForward);
740 klfDbgT(
"text="<<text<<
", forward="<<forward) ;
742 if (target() == NULL && text.
isEmpty())
748 klfDbg(
"find()ing already. queueing and requesting to stop previous find.");
750 d->pHasQueuedFind =
true;
751 d->pQueuedFindString = text;
752 d->pQueuedFindForward = forward;
757 (d->pUseEsbs && text.
mid(0, d->pSearchText.size()) != d->pSearchText) ) {
762 if (!d->pIsSearching) {
763 klfDbg(
"new search. find start from position.") ;
766 d->pLastPos = d->pCurPos;
767 klfDbg(
"Starting from d->pCurPos="<<d->pCurPos) ;
770 d->pIsSearching =
true;
771 d->pSearchText = text;
772 performFind(forward,
false);
777 void KLFSearchBar::performFind(
bool forward,
bool isfindnext)
786 KLFSearchBarPrivate::HistBuffer buf;
787 buf.str = d->pSearchText;
788 d->esbs_histbuffer << buf;
792 klfDbg(
"pSearchText="<<d->pSearchText<<
"; pCurPos="<<d->pCurPos<<
"; pLastPos="<<d->pLastPos) ;
797 d->pIsFinding =
true;
798 d->pWaitLabel->startWait();
800 klfDbg(
"pSearchText="<<d->pSearchText<<
"; target()->searchQueryString()="<<target()->searchQueryString()) ;
802 d->pWaitLabel->stopWait();
803 d->pIsFinding =
false;
805 if (!d->pIsSearching) {
812 if (target()->searchHasInterruptRequested()) {
814 if (d->pHasQueuedFind) {
815 QString s = d->pQueuedFindString;
816 bool f = d->pQueuedFindForward;
817 d->pHasQueuedFind =
false;
818 d->pQueuedFindString =
QString();
819 d->pQueuedFindForward =
true;
826 target()->
searchPerformed(d->pSearchText, d->pCurPos.valid(), d->pCurPos);
831 klfDbg(
"Are now at position pCurPos="<<d->pCurPos) ;
835 if (d->pCurPos.valid() ||
837 (d->esbs_histbuffer.last().poslist.isEmpty() ||
838 d->esbs_histbuffer.last().poslist.last().cur.valid())) {
839 d->esbs_histbuffer.last().poslist
840 << KLFSearchBarPrivate::HistBuffer::CurLastPosPair(d->pCurPos, d->pLastPos, forward);
851 klfDbg(
"finding already. Must wait, ignoring request.");
859 if (d->pSearchText.isEmpty()) {
860 klfDbg(
"called but not in search mode. recalling history="<<d->pLastSearchText) ;
866 find(
u->txtSearch->text(), forward);
872 d->pLastPos = d->pCurPos;
873 d->pLastSearchText = d->pSearchText;
874 performFind(forward,
true);
880 u->txtSearch->blockSignals(
true);
881 u->txtSearch->setText(
"");
882 u->txtSearch->blockSignals(
false);
886 if (target() != NULL) {
887 klfDbg(
"telling target to reinitialize search...") ;
905 d->pIsSearching =
false;
908 klfDbg(
"pCurPos="<<d->pCurPos) ;
910 if ( !
u->txtSearch->text().isEmpty() ) {
914 d->esbs_histbuffer.clear();
922 if (target() != NULL) {
923 klfDbg(
"telling target to abort search...") ;
935 void KLFSearchBar::adjustOverlayGeometry()
937 if (d->pShowOverlayMode) {
938 QWidget *pw = parentWidget();
941 QSize pws = pw->size();
943 QPoint relPos = d->pShowOverlayRelativeGeometry.topLeft();
944 QSize relSz = d->pShowOverlayRelativeGeometry.size();
950 klfDbg(
"Geometry is "<<gm) ;
953 setStyleSheet(styleSheet());
957 setWindowFlags(Qt::Tool);
959 setWindowOpacity(0.95);
968 if (d->pShowOverlayMode)
969 adjustOverlayGeometry();
976 u->txtSearch->setFocus();
984 if (d->pFocusOutResetTimer.isActive()) {
985 d->pFocusOutResetTimer.stop();
997 if (d->pResetTimeout == 0) {
1001 if (d->pResetTimeout > 0) {
1002 d->pFocusOutResetTimer.setInterval(d->pResetTimeout);
1003 d->pFocusOutResetTimer.setSingleShot(
true);
1004 d->pFocusOutResetTimer.start();
1012 klfDbgT(
"search reset after focus out.");
1026 QString KLFSearchBar::palettePropName(SearchState state)
const
1040 QString KLFSearchBar::statePropValue(SearchState state)
const
1054 klfDbg(
"state: "<<state) ;
1056 if (d->pState == state)
1066 klfDbg(
"Setting state: "<<statePropValue(s));
1067 u->txtSearch->setProperty(
"searchState", statePropValue(s));
1068 QPalette pal =
u->txtSearch->property(palettePropName(s).toLatin1()).value<
QPalette>();
1070 u->txtSearch->setStyleSheet(
u->txtSearch->styleSheet());
1071 u->txtSearch->setPalette(pal);
1072 u->txtSearch->update();
1081 bool resultfound = pos.
valid();
1086 emit
found(d->pSearchText, forward);
1087 emit
found(d->pSearchText, forward, pos);
1096 u->txtSearch->blockSignals(
true);
1097 u->txtSearch->setText(text);
1099 d->esbs_histbuffer.clear();
1100 u->txtSearch->blockSignals(
false);
1104 return QApplication::focusWidget() ==
u->txtSearch;
1110 if (
event->type() == QEvent::Polish)
1111 setMinimumSize(minimumSizeHint());
1113 if (
event->type() == QEvent::Show) {
1116 if (
event->type() == QEvent::Hide) {
1120 return QFrame::event(
event);