diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f201f692c..c4083fd61 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -511,7 +511,7 @@ set(HEADERS widgets/tracksliderpopup.h widgets/tracksliderslider.h widgets/loginstatewidget.h - widgets/qsearchfield.h + widgets/searchfield.h widgets/ratingwidget.h widgets/forcescrollperpixel.h widgets/resizabletextedit.h @@ -639,7 +639,7 @@ option(USE_INSTALL_PREFIX "Look for data in CMAKE_INSTALL_PREFIX" ON) if(NOT APPLE) set(NOT_APPLE ON) - optional_source(NOT_APPLE SOURCES widgets/qsearchfield_qt.cpp core/qtsystemtrayicon.cpp HEADERS core/qtsystemtrayicon.h) + optional_source(NOT_APPLE SOURCES widgets/searchfield_qt.cpp widgets/searchfield_qt_private.cpp core/qtsystemtrayicon.cpp HEADERS core/qtsystemtrayicon.h widgets/searchfield_qt_private.h) endif() if(HAVE_GLOBALSHORTCUTS) @@ -857,7 +857,7 @@ optional_source(APPLE core/macsystemtrayicon.mm core/macfslistener.mm osd/osdmac.mm - widgets/qsearchfield_mac.mm + widgets/searchfield_mac.mm engine/macosdevicefinder.cpp globalshortcuts/globalshortcutsbackend-macos.mm globalshortcuts/globalshortcutgrabber.mm diff --git a/src/collection/collectionfilterwidget.cpp b/src/collection/collectionfilterwidget.cpp index bcec1b005..3a9ab596e 100644 --- a/src/collection/collectionfilterwidget.cpp +++ b/src/collection/collectionfilterwidget.cpp @@ -57,7 +57,7 @@ #include "collectionfilterwidget.h" #include "groupbydialog.h" #include "ui_collectionfilterwidget.h" -#include "widgets/qsearchfield.h" +#include "widgets/searchfield.h" #include "settings/collectionsettingspage.h" #include "settings/appearancesettingspage.h" @@ -84,7 +84,7 @@ CollectionFilterWidget::CollectionFilterWidget(QWidget *parent) ui_->search_field->setToolTip(FilterParser::ToolTip()); - QObject::connect(ui_->search_field, &QSearchField::returnPressed, this, &CollectionFilterWidget::ReturnPressed); + QObject::connect(ui_->search_field, &SearchField::returnPressed, this, &CollectionFilterWidget::ReturnPressed); QObject::connect(timer_filter_delay_, &QTimer::timeout, this, &CollectionFilterWidget::FilterDelayTimeout); timer_filter_delay_->setInterval(kFilterDelay); @@ -127,7 +127,7 @@ CollectionFilterWidget::CollectionFilterWidget(QWidget *parent) collection_menu_->addSeparator(); ui_->options->setMenu(collection_menu_); - QObject::connect(ui_->search_field, &QSearchField::textChanged, this, &CollectionFilterWidget::FilterTextChanged); + QObject::connect(ui_->search_field, &SearchField::textChanged, this, &CollectionFilterWidget::FilterTextChanged); QObject::connect(ui_->options, &QToolButton::clicked, ui_->options, &QToolButton::showMenu); ReloadSettings(); diff --git a/src/collection/collectionfilterwidget.ui b/src/collection/collectionfilterwidget.ui index c9c437fdf..951b9db79 100644 --- a/src/collection/collectionfilterwidget.ui +++ b/src/collection/collectionfilterwidget.ui @@ -30,7 +30,7 @@ 0 - + Enter search terms here @@ -123,9 +123,9 @@ - QSearchField + SearchField QWidget -
widgets/qsearchfield.h
+
widgets/searchfield.h
diff --git a/src/covermanager/albumcovermanager.cpp b/src/covermanager/albumcovermanager.cpp index 964e3065a..3bb13f1ee 100644 --- a/src/covermanager/albumcovermanager.cpp +++ b/src/covermanager/albumcovermanager.cpp @@ -74,7 +74,7 @@ #include "utilities/mimeutils.h" #include "utilities/screenutils.h" #include "widgets/forcescrollperpixel.h" -#include "widgets/qsearchfield.h" +#include "widgets/searchfield.h" #include "collection/collectionbackend.h" #include "collection/collectionquery.h" #include "playlist/songmimedata.h" @@ -206,7 +206,7 @@ void AlbumCoverManager::Init() { // Connections QObject::connect(ui_->artists, &QListWidget::currentItemChanged, this, &AlbumCoverManager::ArtistChanged); - QObject::connect(ui_->filter, &QSearchField::textChanged, this, &AlbumCoverManager::UpdateFilter); + QObject::connect(ui_->filter, &SearchField::textChanged, this, &AlbumCoverManager::UpdateFilter); QObject::connect(filter_group, &QActionGroup::triggered, this, &AlbumCoverManager::UpdateFilter); QObject::connect(ui_->view, &QToolButton::clicked, ui_->view, &QToolButton::showMenu); QObject::connect(ui_->button_fetch, &QPushButton::clicked, this, &AlbumCoverManager::FetchAlbumCovers); diff --git a/src/covermanager/albumcovermanager.ui b/src/covermanager/albumcovermanager.ui index 7f22d4de7..8b8b72685 100644 --- a/src/covermanager/albumcovermanager.ui +++ b/src/covermanager/albumcovermanager.ui @@ -79,7 +79,7 @@ 0 - + Enter search terms here @@ -281,9 +281,9 @@ - QSearchField + SearchField QWidget -
widgets/qsearchfield.h
+
widgets/searchfield.h
AlbumCoverManagerList diff --git a/src/covermanager/albumcoversearcher.cpp b/src/covermanager/albumcoversearcher.cpp index 71c8fbd2a..2efa00682 100644 --- a/src/covermanager/albumcoversearcher.cpp +++ b/src/covermanager/albumcoversearcher.cpp @@ -54,7 +54,7 @@ #include "widgets/busyindicator.h" #include "widgets/forcescrollperpixel.h" #include "widgets/groupediconview.h" -#include "widgets/qsearchfield.h" +#include "widgets/searchfield.h" #include "albumcoversearcher.h" #include "albumcoverfetcher.h" #include "albumcoverloader.h" diff --git a/src/covermanager/albumcoversearcher.ui b/src/covermanager/albumcoversearcher.ui index aabc60c93..d5e83efd6 100644 --- a/src/covermanager/albumcoversearcher.ui +++ b/src/covermanager/albumcoversearcher.ui @@ -17,7 +17,7 @@ - + Artist @@ -27,7 +27,7 @@ - + Album @@ -81,9 +81,9 @@ - QSearchField + SearchField QWidget -
widgets/qsearchfield.h
+
widgets/searchfield.h
BusyIndicator diff --git a/src/playlist/playlistcontainer.cpp b/src/playlist/playlistcontainer.cpp index f497a081d..f4b62bd2d 100644 --- a/src/playlist/playlistcontainer.cpp +++ b/src/playlist/playlistcontainer.cpp @@ -58,7 +58,7 @@ #include "playlistfilter.h" #include "playlistparsers/playlistparser.h" #include "ui_playlistcontainer.h" -#include "widgets/qsearchfield.h" +#include "widgets/searchfield.h" #include "settings/appearancesettingspage.h" namespace { @@ -123,7 +123,7 @@ PlaylistContainer::PlaylistContainer(QWidget *parent) QObject::connect(filter_timer_, &QTimer::timeout, this, &PlaylistContainer::UpdateFilter); // Replace playlist search filter with native search box. - QObject::connect(ui_->search_field, &QSearchField::textChanged, this, &PlaylistContainer::MaybeUpdateFilter); + QObject::connect(ui_->search_field, &SearchField::textChanged, this, &PlaylistContainer::MaybeUpdateFilter); QObject::connect(ui_->playlist, &PlaylistView::FocusOnFilterSignal, this, &PlaylistContainer::FocusOnFilter); ui_->search_field->installEventFilter(this); diff --git a/src/playlist/playlistcontainer.ui b/src/playlist/playlistcontainer.ui index 89263ef74..bee4b8979 100644 --- a/src/playlist/playlistcontainer.ui +++ b/src/playlist/playlistcontainer.ui @@ -143,7 +143,7 @@
- +
@@ -186,9 +186,9 @@
- QSearchField + SearchField QWidget -
widgets/qsearchfield.h
+
widgets/searchfield.h
PlaylistView diff --git a/src/streaming/streamingsearchview.cpp b/src/streaming/streamingsearchview.cpp index 9945aceaf..43c4359ad 100644 --- a/src/streaming/streamingsearchview.cpp +++ b/src/streaming/streamingsearchview.cpp @@ -192,7 +192,7 @@ void StreamingSearchView::Init(Application *app, StreamingServicePtr service) { QObject::connect(group_by_actions_, &QActionGroup::triggered, this, &StreamingSearchView::GroupByClicked); QObject::connect(group_by_actions_, &QActionGroup::triggered, this, &StreamingSearchView::GroupByClicked); - QObject::connect(ui_->search, &QSearchField::textChanged, this, &StreamingSearchView::TextEdited); + QObject::connect(ui_->search, &SearchField::textChanged, this, &StreamingSearchView::TextEdited); QObject::connect(ui_->results, &AutoExpandingTreeView::AddToPlaylistSignal, this, &StreamingSearchView::AddToPlaylist); QObject::connect(ui_->results, &AutoExpandingTreeView::FocusOnFilterSignal, this, &StreamingSearchView::FocusOnFilter); diff --git a/src/streaming/streamingsearchview.ui b/src/streaming/streamingsearchview.ui index c0a78f4b6..32361a2d7 100644 --- a/src/streaming/streamingsearchview.ui +++ b/src/streaming/streamingsearchview.ui @@ -40,7 +40,7 @@ - + @@ -297,9 +297,9 @@ - QSearchField + SearchField QWidget -
widgets/qsearchfield.h
+
widgets/searchfield.h
AutoExpandingTreeView diff --git a/src/widgets/qsearchfield.h b/src/widgets/qsearchfield.h deleted file mode 100644 index 74d0dd11b..000000000 --- a/src/widgets/qsearchfield.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef QSEARCHFIELD_H -#define QSEARCHFIELD_H - -#include -#include -#include - -class QSearchFieldPrivate; -class QSearchField : public QWidget { - Q_OBJECT - - Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged USER true) - Q_PROPERTY(QString placeholderText READ placeholderText WRITE setPlaceholderText) - - public: - explicit QSearchField(QWidget *parent); - - void setIconSize(const int iconsize); - - QString text() const; - QString placeholderText() const; - -#ifndef Q_OS_MACOS - bool hasFocus() const; -#endif - void setFocus(Qt::FocusReason); - - public Q_SLOTS: - void setText(const QString &new_text); - void setPlaceholderText(const QString &text); - void clear(); - void selectAll(); - void setFocus(); - - Q_SIGNALS: - void textChanged(const QString &text); - void editingFinished(); - void returnPressed(); - - protected: - void resizeEvent(QResizeEvent*) override; - bool eventFilter(QObject*, QEvent*) override; - - private: - friend class QSearchFieldPrivate; - QPointer pimpl; -}; - -#endif // QSEARCHFIELD_H diff --git a/src/widgets/searchfield.h b/src/widgets/searchfield.h new file mode 100644 index 000000000..4b00f4f87 --- /dev/null +++ b/src/widgets/searchfield.h @@ -0,0 +1,74 @@ +/* +Copyright (C) 2011 by Mike McQuaid +Copyright (C) 2018-2024 by Jonas Kvinge + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#ifndef SEARCHFIELD_H +#define SEARCHFIELD_H + +#include +#include +#include + +class QResizeEvent; +class SearchFieldPrivate; + +class SearchField : public QWidget { + Q_OBJECT + + Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged USER true) + Q_PROPERTY(QString placeholderText READ placeholderText WRITE setPlaceholderText) + + public: + explicit SearchField(QWidget *parent); + + void setIconSize(const int iconsize); + + QString text() const; + QString placeholderText() const; + +#ifndef Q_OS_MACOS + bool hasFocus() const; +#endif + void setFocus(Qt::FocusReason); + + public Q_SLOTS: + void setText(const QString &new_text); + void setPlaceholderText(const QString &text); + void clear(); + void selectAll(); + void setFocus(); + + Q_SIGNALS: + void textChanged(const QString &text); + void editingFinished(); + void returnPressed(); + + protected: + void resizeEvent(QResizeEvent*) override; + bool eventFilter(QObject *o, QEvent *e) override; + + private: + friend class SearchFieldPrivate; + SearchFieldPrivate *pimpl; +}; + +#endif // SEARCHFIELD_H diff --git a/src/widgets/qsearchfield_mac.mm b/src/widgets/searchfield_mac.mm similarity index 80% rename from src/widgets/qsearchfield_mac.mm rename to src/widgets/searchfield_mac.mm index 03572d9bd..c21ea5577 100644 --- a/src/widgets/qsearchfield_mac.mm +++ b/src/widgets/searchfield_mac.mm @@ -1,6 +1,6 @@ /* Copyright (C) 2011 by Mike McQuaid -Copyright (C) 2018-2021 by Jonas Kvinge +Copyright (C) 2018-2024 by Jonas Kvinge Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -21,89 +21,111 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include "qsearchfield.h" -#include "qocoa_mac.h" - #import "Foundation/NSAutoreleasePool.h" #import "Foundation/NSNotification.h" #import "AppKit/NSSearchField.h" #include +#include +#include #include #include -#include -#include -#include +#include +#include #include -class QSearchFieldPrivate : public QObject { -public: - QSearchFieldPrivate(QSearchField *qSearchField, NSSearchField *nsSearchField) +#include "searchfield.h" +#include "qocoa_mac.h" + +class SearchFieldPrivate : public QObject { + + public: + + explicit SearchFieldPrivate(SearchField *qSearchField, NSSearchField *nsSearchField) : QObject(qSearchField), qSearchField(qSearchField), nsSearchField(nsSearchField) {} void textDidChange(const QString &text) { - if (qSearchField) emit qSearchField->textChanged(text); + + if (qSearchField) { + emit qSearchField->textChanged(text); + } + } void textDidEndEditing() { - if (qSearchField) - emit qSearchField->editingFinished(); + + if (qSearchField) { + Q_EMIT qSearchField->editingFinished(); } + } + void returnPressed() { + if (qSearchField) { - emit qSearchField->returnPressed(); + Q_EMIT qSearchField->returnPressed(); QKeyEvent *event = new QKeyEvent(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier); QApplication::postEvent(qSearchField, event); } + } void keyDownPressed() { + if (qSearchField) { QKeyEvent *event = new QKeyEvent(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier); QApplication::postEvent(qSearchField, event); } + } void keyUpPressed() { + if (qSearchField) { QKeyEvent *event = new QKeyEvent(QEvent::KeyPress, Qt::Key_Up, Qt::NoModifier); QApplication::postEvent(qSearchField, event); } + } - QPointer qSearchField; + QPointer qSearchField; NSSearchField *nsSearchField; - }; -@interface QSearchFieldDelegate : NSObject { +@interface SearchFieldDelegate : NSObject { @public - QPointer pimpl; + QPointer pimpl; } -(void)controlTextDidChange:(NSNotification*)notification; -(void)controlTextDidEndEditing:(NSNotification*)notification; @end -@implementation QSearchFieldDelegate +@implementation SearchFieldDelegate -(void)controlTextDidChange:(NSNotification*)notification { + Q_ASSERT(pimpl); + if (pimpl) pimpl->textDidChange(toQString([[notification object] stringValue])); + } -(void)controlTextDidEndEditing:(NSNotification*)notification { + Q_UNUSED(notification); // No Q_ASSERT here as it is called on destruction. if (!pimpl) return; pimpl->textDidEndEditing(); if ([[[notification userInfo] objectForKey:@"NSTextMovement"] intValue] == NSReturnTextMovement) pimpl->returnPressed(); + } -(BOOL)control: (NSControl*)control textView: (NSTextView*)textView doCommandBySelector: (SEL)commandSelector { + Q_UNUSED(control); Q_UNUSED(textView); Q_ASSERT(pimpl); + if (!pimpl) return NO; if (commandSelector == @selector(moveDown:)) { pimpl->keyDownPressed(); @@ -113,7 +135,9 @@ public: pimpl->keyUpPressed(); return YES; } + return NO; + } @end @@ -124,6 +148,7 @@ public: @implementation QocoaSearchField -(BOOL)performKeyEquivalent:(NSEvent*)event { + // First, check if we have the focus. // If no, it probably means this event isn't for us. NSResponder *firstResponder = [[NSApp keyWindow] firstResponder]; @@ -151,15 +176,16 @@ public: } return NO; + } @end -QSearchField::QSearchField(QWidget *parent) : QWidget(parent) { +SearchField::SearchField(QWidget *parent) : QWidget(parent) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSSearchField *search = [[QocoaSearchField alloc] init]; - QSearchFieldDelegate *delegate = [[QSearchFieldDelegate alloc] init]; - pimpl = delegate->pimpl = new QSearchFieldPrivate(this, search); + SearchFieldDelegate *delegate = [[SearchFieldDelegate alloc] init]; + pimpl = delegate->pimpl = new SearchFieldPrivate(this, search); [search setDelegate:static_cast>(delegate)]; setAttribute(Qt::WA_NativeWindow); @@ -174,12 +200,14 @@ QSearchField::QSearchField(QWidget *parent) : QWidget(parent) { } -void QSearchField::setIconSize(const int iconsize) { +void SearchField::setIconSize(const int iconsize) { Q_UNUSED(iconsize); } -void QSearchField::setText(const QString &text) { +void SearchField::setText(const QString &text) { + Q_ASSERT(pimpl); + if (!pimpl) return; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; @@ -188,51 +216,72 @@ void QSearchField::setText(const QString &text) { [pimpl->nsSearchField selectText:pimpl->nsSearchField]; [[pimpl->nsSearchField currentEditor] setSelectedRange:NSMakeRange([[pimpl->nsSearchField stringValue] length], 0)]; } + [pool drain]; + } -void QSearchField::setPlaceholderText(const QString &text) { +void SearchField::setPlaceholderText(const QString &text) { + Q_ASSERT(pimpl); + if (!pimpl) return; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; [[pimpl->nsSearchField cell] setPlaceholderString:fromQString(text)]; + [pool drain]; + } -void QSearchField::clear() { +void SearchField::clear() { + Q_ASSERT(pimpl); + if (!pimpl) return; + [pimpl->nsSearchField setStringValue:@""]; - emit textChanged(QString()); + + Q_EMIT textChanged(QString()); + } -void QSearchField::selectAll() { +void SearchField::selectAll() { + Q_ASSERT(pimpl); + if (!pimpl) return; [pimpl->nsSearchField performSelector:@selector(selectText:)]; + } -QString QSearchField::text() const { +QString SearchField::text() const { + Q_ASSERT(pimpl); + if (!pimpl) return QString(); return toQString([pimpl->nsSearchField stringValue]); + } -QString QSearchField::placeholderText() const { +QString SearchField::placeholderText() const { + Q_ASSERT(pimpl); + return toQString([[pimpl->nsSearchField cell] placeholderString]); + } -void QSearchField::setFocus(Qt::FocusReason) {} +void SearchField::setFocus(Qt::FocusReason) {} -void QSearchField::setFocus() { +void SearchField::setFocus() { setFocus(Qt::OtherFocusReason); } -void QSearchField::resizeEvent(QResizeEvent *resizeEvent) { +void SearchField::resizeEvent(QResizeEvent *resizeEvent) { QWidget::resizeEvent(resizeEvent); } -bool QSearchField::eventFilter(QObject *o, QEvent *e) { +bool SearchField::eventFilter(QObject *o, QEvent *e) { return QWidget::eventFilter(o, e); } diff --git a/src/widgets/qsearchfield_qt.cpp b/src/widgets/searchfield_qt.cpp similarity index 70% rename from src/widgets/qsearchfield_qt.cpp rename to src/widgets/searchfield_qt.cpp index 426b2d3c8..291c3075e 100644 --- a/src/widgets/qsearchfield_qt.cpp +++ b/src/widgets/searchfield_qt.cpp @@ -1,6 +1,6 @@ /* Copyright (C) 2011 by Mike McQuaid -Copyright (C) 2018-2021 by Jonas Kvinge +Copyright (C) 2018-2024 by Jonas Kvinge Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -21,55 +21,30 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include "qsearchfield.h" +#include "searchfield.h" +#include "searchfield_qt_private.h" -#include -#include #include #include #include #include -#include #include #include +#include #include #include -#include #include #include #include "core/iconloader.h" -class QSearchFieldPrivate : public QObject { // clazy:exclude=missing-qobject-macro - - public: - QSearchFieldPrivate(QSearchField *searchField, QLineEdit *lineedit, QPushButton *clearbutton) - : QObject(searchField), lineedit_(lineedit), clearbutton_(clearbutton) {} - - int lineEditFrameWidth() const { - return lineedit_->style()->pixelMetric(QStyle::PM_DefaultFrameWidth); - } - - int clearButtonPaddedWidth() const { - return clearbutton_->width() + lineEditFrameWidth() * 2; - } - - int clearButtonPaddedHeight() const { - return clearbutton_->height() + lineEditFrameWidth() * 2; - } - - QPointer lineedit_; - QPointer clearbutton_; - -}; - -QSearchField::QSearchField(QWidget *parent) : QWidget(parent) { +SearchField::SearchField(QWidget *parent) : QWidget(parent) { QLineEdit *lineEdit = new QLineEdit(this); - QObject::connect(lineEdit, &QLineEdit::textChanged, this, &QSearchField::textChanged); - QObject::connect(lineEdit, &QLineEdit::editingFinished, this, &QSearchField::editingFinished); - QObject::connect(lineEdit, &QLineEdit::returnPressed, this, &QSearchField::returnPressed); - QObject::connect(lineEdit, &QLineEdit::textChanged, this, &QSearchField::setText); + QObject::connect(lineEdit, &QLineEdit::textChanged, this, &SearchField::textChanged); + QObject::connect(lineEdit, &QLineEdit::editingFinished, this, &SearchField::editingFinished); + QObject::connect(lineEdit, &QLineEdit::returnPressed, this, &SearchField::returnPressed); + QObject::connect(lineEdit, &QLineEdit::textChanged, this, &SearchField::setText); QPushButton *clearbutton = new QPushButton(this); QIcon clearIcon(IconLoader::Load(QStringLiteral("edit-clear-locationbar-ltr"))); @@ -79,9 +54,9 @@ QSearchField::QSearchField(QWidget *parent) : QWidget(parent) { clearbutton->setStyleSheet(QStringLiteral("border: none; padding: 2px;")); clearbutton->resize(clearbutton->sizeHint()); - QObject::connect(clearbutton, &QPushButton::clicked, this, &QSearchField::clear); + QObject::connect(clearbutton, &QPushButton::clicked, this, &SearchField::clear); - pimpl = new QSearchFieldPrivate(this, lineEdit, clearbutton); + pimpl = new SearchFieldPrivate(this, lineEdit, clearbutton); const int frame_width = lineEdit->style()->pixelMetric(QStyle::PM_DefaultFrameWidth); @@ -98,7 +73,7 @@ QSearchField::QSearchField(QWidget *parent) : QWidget(parent) { } -void QSearchField::setIconSize(const int iconsize) { +void SearchField::setIconSize(const int iconsize) { pimpl->clearbutton_->setIconSize(QSize(iconsize, iconsize)); pimpl->clearbutton_->resize(pimpl->clearbutton_->sizeHint()); @@ -111,7 +86,7 @@ void QSearchField::setIconSize(const int iconsize) { } -void QSearchField::setText(const QString &new_text) { +void SearchField::setText(const QString &new_text) { Q_ASSERT(pimpl && pimpl->clearbutton_ && pimpl->lineedit_); if (!(pimpl && pimpl->clearbutton_ && pimpl->lineedit_)) return; @@ -119,7 +94,7 @@ void QSearchField::setText(const QString &new_text) { } -void QSearchField::setPlaceholderText(const QString &text) { +void SearchField::setPlaceholderText(const QString &text) { Q_ASSERT(pimpl && pimpl->lineedit_); if (!(pimpl && pimpl->lineedit_)) return; @@ -127,25 +102,25 @@ void QSearchField::setPlaceholderText(const QString &text) { } -QString QSearchField::placeholderText() const { +QString SearchField::placeholderText() const { return pimpl->lineedit_->placeholderText(); } -bool QSearchField::hasFocus() const { +bool SearchField::hasFocus() const { Q_ASSERT(pimpl && pimpl->lineedit_); return pimpl && pimpl->lineedit_ && pimpl->lineedit_->hasFocus(); } -void QSearchField::setFocus(Qt::FocusReason reason) { +void SearchField::setFocus(Qt::FocusReason reason) { Q_ASSERT(pimpl && pimpl->lineedit_); if (pimpl && pimpl->lineedit_) pimpl->lineedit_->setFocus(reason); } -void QSearchField::setFocus() { +void SearchField::setFocus() { setFocus(Qt::OtherFocusReason); } -void QSearchField::clear() { +void SearchField::clear() { Q_ASSERT(pimpl && pimpl->lineedit_); @@ -154,7 +129,7 @@ void QSearchField::clear() { } -void QSearchField::selectAll() { +void SearchField::selectAll() { Q_ASSERT(pimpl && pimpl->lineedit_); @@ -163,7 +138,7 @@ void QSearchField::selectAll() { } -QString QSearchField::text() const { +QString SearchField::text() const { Q_ASSERT(pimpl && pimpl->lineedit_); @@ -172,7 +147,7 @@ QString QSearchField::text() const { } -void QSearchField::resizeEvent(QResizeEvent *resizeEvent) { +void SearchField::resizeEvent(QResizeEvent *resizeEvent) { Q_ASSERT(pimpl && pimpl->clearbutton_ && pimpl->lineedit_); if (!(pimpl && pimpl->clearbutton_ && pimpl->lineedit_)) return; @@ -184,10 +159,10 @@ void QSearchField::resizeEvent(QResizeEvent *resizeEvent) { } -bool QSearchField::eventFilter(QObject *o, QEvent *e) { +bool SearchField::eventFilter(QObject *o, QEvent *e) { if (pimpl && pimpl->lineedit_ && o == pimpl->lineedit_) { - // Forward some lineEdit events to QSearchField (only those we need for + // Forward some lineEdit events to SearchField (only those we need for // now, but some might be added later if needed) switch (e->type()) { case QEvent::FocusIn: @@ -198,6 +173,7 @@ bool QSearchField::eventFilter(QObject *o, QEvent *e) { break; } } + return QWidget::eventFilter(o, e); } diff --git a/src/widgets/searchfield_qt_private.cpp b/src/widgets/searchfield_qt_private.cpp new file mode 100644 index 000000000..4ae0b2f8f --- /dev/null +++ b/src/widgets/searchfield_qt_private.cpp @@ -0,0 +1,44 @@ +/* +Copyright (C) 2011 by Mike McQuaid +Copyright (C) 2018-2024 by Jonas Kvinge + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#include +#include +#include + +#include "searchfield_qt_private.h" +#include "searchfield.h" + +SearchFieldPrivate::SearchFieldPrivate(SearchField *searchField, QLineEdit *lineedit, QPushButton *clearbutton) + : QObject(searchField), lineedit_(lineedit), clearbutton_(clearbutton) {} + +int SearchFieldPrivate::lineEditFrameWidth() const { + return lineedit_->style()->pixelMetric(QStyle::PM_DefaultFrameWidth); +} + +int SearchFieldPrivate::clearButtonPaddedWidth() const { + return clearbutton_->width() + lineEditFrameWidth() * 2; +} + +int SearchFieldPrivate::clearButtonPaddedHeight() const { + return clearbutton_->height() + lineEditFrameWidth() * 2; +} diff --git a/src/widgets/searchfield_qt_private.h b/src/widgets/searchfield_qt_private.h new file mode 100644 index 000000000..d90f7491d --- /dev/null +++ b/src/widgets/searchfield_qt_private.h @@ -0,0 +1,48 @@ +/* +Copyright (C) 2011 by Mike McQuaid +Copyright (C) 2018-2024 by Jonas Kvinge + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#ifndef SEARCHFIELD_QT_PRIVATE_H +#define SEARCHFIELD_QT_PRIVATE_H + +#include +#include + +class QLineEdit; +class QPushButton; +class SearchField; + +class SearchFieldPrivate : public QObject { + Q_OBJECT + + public: + explicit SearchFieldPrivate(SearchField *searchField, QLineEdit *lineedit, QPushButton *clearbutton); + + int lineEditFrameWidth() const; + int clearButtonPaddedWidth() const; + int clearButtonPaddedHeight() const; + + QPointer lineedit_; + QPointer clearbutton_; +}; + +#endif // QSEARCHFIELD_QT_PRIVATE_H