From 322e17081f8c59029ce7e77054ea5d139187801d Mon Sep 17 00:00:00 2001 From: Jean-Francois Dockes Date: Tue, 11 Aug 2020 18:30:51 +0200 Subject: [PATCH] GUI filename search: arrange for directories to be sorted first by default --- src/qtgui/rclmain_w.cpp | 31 +++++++++++++++++++++++++++++++ src/qtgui/rclmain_w.h | 1 + src/qtgui/ssearch_w.cpp | 5 +++-- src/qtgui/ssearch_w.h | 3 ++- src/rcldb/rclquery.cpp | 27 +++++++++++++++++++-------- 5 files changed, 56 insertions(+), 11 deletions(-) diff --git a/src/qtgui/rclmain_w.cpp b/src/qtgui/rclmain_w.cpp index 3c1356b5..218d8fe2 100644 --- a/src/qtgui/rclmain_w.cpp +++ b/src/qtgui/rclmain_w.cpp @@ -296,6 +296,8 @@ void RclMain::init() connect(sSearch, SIGNAL(startSearch(std::shared_ptr, bool)), this, SLOT(startSearch(std::shared_ptr, bool))); + connect(sSearch, SIGNAL(searchTypeChanged(int)), + this, SLOT(onSearchTypeChanged(int))); connect(sSearch, SIGNAL(setDescription(QString)), this, SLOT(onSetDescription(QString))); connect(sSearch, SIGNAL(clearSearch()), @@ -690,6 +692,21 @@ void RclMain::fileExit() qApp->exit(0); } +// Reset sort order when search type changes. +void RclMain::onSearchTypeChanged(int stp) +{ + SSearch::SSearchType tp = (SSearch::SSearchType)stp; + switch (tp) { + case SSearch::SST_FNM: + m_sortspec.desc = false; + m_sortspec.field = "mtype"; + break; + default: + m_sortspec.reset(); + break; + }; +} + // Start a db query and set the reslist docsource void RclMain::startSearch(std::shared_ptr sdata, bool issimple) { @@ -735,6 +752,14 @@ void RclMain::startSearch(std::shared_ptr sdata, bool issimple) src->setAbstractParams(prefs.queryBuildAbstract, prefs.queryReplaceAbstract); m_source = std::shared_ptr(src); + + // If this is a file name search sort by mtype so that directories + // come first (see the rclquery sort key generator) + if (sSearch->searchTypCMB->currentIndex() == SSearch::SST_FNM && + m_sortspec.field.empty()) { + m_sortspec.field = "mtype"; + m_sortspec.desc = false; + } m_source->setSortSpec(m_sortspec); m_source->setFiltSpec(m_filtspec); @@ -840,6 +865,12 @@ void RclMain::onSortCtlChanged() } else { prefs.sortActive = prefs.sortDesc = false; prefs.sortField = ""; + // If this is a file name search sort by mtype so that directories + // come first (see the rclquery sort key generator) + if (sSearch->searchTypCMB->currentIndex() == SSearch::SST_FNM) { + m_sortspec.field = "mtype"; + m_sortspec.desc = false; + } } if (m_source) m_source->setSortSpec(m_sortspec); diff --git a/src/qtgui/rclmain_w.h b/src/qtgui/rclmain_w.h index 61867250..a103476d 100644 --- a/src/qtgui/rclmain_w.h +++ b/src/qtgui/rclmain_w.h @@ -138,6 +138,7 @@ public slots: virtual void previewPrevInTab(Preview *, int sid, int docnum); virtual void previewExposed(Preview *, int sid, int docnum); virtual void resetSearch(); + virtual void onSearchTypeChanged(int); virtual void eraseDocHistory(); virtual void eraseSearchHistory(); virtual void exportSimpleSearchHistory(); diff --git a/src/qtgui/ssearch_w.cpp b/src/qtgui/ssearch_w.cpp index 49290aea..12fa1e43 100644 --- a/src/qtgui/ssearch_w.cpp +++ b/src/qtgui/ssearch_w.cpp @@ -170,7 +170,7 @@ void SSearch::init() connect(clearqPB, SIGNAL(clicked()), queryText, SLOT(clear())); connect(searchPB, SIGNAL(clicked()), this, SLOT(startSimpleSearch())); connect(searchTypCMB, SIGNAL(activated(int)), this, - SLOT(searchTypeChanged(int))); + SLOT(onSearchTypeChanged(int))); m_completermodel = new RclCompleterModel(this); m_completer = new QCompleter(m_completermodel, this); @@ -355,7 +355,7 @@ void SSearch::searchTextChanged(const QString& text) } } -void SSearch::searchTypeChanged(int typ) +void SSearch::onSearchTypeChanged(int typ) { LOGDEB1("Search type now " << typ << "\n"); // Adjust context help @@ -416,6 +416,7 @@ void SSearch::searchTypeChanged(int typ) default: queryText->setToolTip(tr("Enter search terms here.")); } + emit searchTypeChanged((int)typ); } void SSearch::startSimpleSearch() diff --git a/src/qtgui/ssearch_w.h b/src/qtgui/ssearch_w.h index afe53e56..71abb126 100644 --- a/src/qtgui/ssearch_w.h +++ b/src/qtgui/ssearch_w.h @@ -86,7 +86,7 @@ public: virtual bool eventFilter(QObject *target, QEvent *event); public slots: - virtual void searchTypeChanged(int); + virtual void onSearchTypeChanged(int); virtual void setSearchString(const QString& text); virtual void startSimpleSearch(); virtual void addTerm(QString); @@ -105,6 +105,7 @@ private slots: virtual void onCompleterShown(); signals: + void searchTypeChanged(int); void startSearch(std::shared_ptr, bool); void setDescription(QString); void clearSearch(); diff --git a/src/rcldb/rclquery.cpp b/src/rcldb/rclquery.cpp index 4f5eecd3..83476d86 100644 --- a/src/rcldb/rclquery.cpp +++ b/src/rcldb/rclquery.cpp @@ -71,12 +71,14 @@ class QSorter : public Xapian::KeyMaker public: QSorter(const string& f) : m_fld(docfToDatf(f) + "=") { - m_ismtime = !m_fld.compare("dmtime="); - if (m_ismtime) - m_issize = false; - else - m_issize = !m_fld.compare("fbytes=") || !m_fld.compare("dbytes=") || - !m_fld.compare("pcbytes="); + if (m_fld == "dmtime=") { + m_ismtime = true; + } else if (m_fld == "fbytes=" || m_fld == "dbytes=" || + m_fld == "pcbytes=") { + m_issize = true; + } else if (m_fld == "mtype=") { + m_ismtype = true; + } } virtual std::string operator()(const Xapian::Document& xdoc) const { @@ -111,6 +113,14 @@ public: // Left zeropad values for appropriate numeric sorting leftzeropad(term, 12); return term; + } else if (m_ismtype) { + // Arrange for directories to always sort first + if (term == "inode/directory" || + term == "application/x-fsdirectory") { + term.insert(0, 1, ' '); + } + // No further processing needed for mtype + return term; } // Process data for better sorting. We should actually do the @@ -136,8 +146,9 @@ public: private: string m_fld; - bool m_ismtime; - bool m_issize; + bool m_ismtime{false}; + bool m_issize{false}; + bool m_ismtype{false}; }; Query::Query(Db *db)