Bug 155986

Summary: Support wildcards such as /directory/K*pdf in the directory path field
Product: [Applications] dolphin Reporter: Tobias Burnus <burnus>
Component: generalAssignee: Peter Penz <peter.penz19>
Status: RESOLVED FIXED    
Severity: wishlist CC: finex, heavytull, net-account
Priority: NOR    
Version: 1.99   
Target Milestone: ---   
Platform: openSUSE   
OS: Linux   
Latest Commit: Version Fixed In: 4.8.0
Attachments: wildcard expressions in filterbar
Static initialisation of QRegExp in helper Class
corrected patch

Description Tobias Burnus 2008-01-17 12:11:26 UTC
Version:            (using KDE 4.0.0)
Installed from:    SuSE RPMs

Above the displayed files is a bar which allows one to type in the directory.

In Konquorer one can also add wildcards to restrict the shown files to a certain patterns, e.g. "directory/*.pdf".

This no longer works in Dolphin.
Comment 1 FiNeX 2008-01-17 21:21:51 UTC
In dolphin you can use the "filter bar" tool for filtering.
Comment 2 Frank Reininghaus 2010-01-31 22:01:42 UTC
*** Bug 225016 has been marked as a duplicate of this bug. ***
Comment 3 A JANARDHAN REDDY 2011-12-09 06:09:28 UTC
Created attachment 66531 [details]
wildcard expressions in filterbar

you can use *i*d*, it cann't be searched with filterbar without regulare expressions
Comment 4 Peter Penz 2011-12-09 07:58:46 UTC
Thanks for the patch Janardhan. I'm not sure whether we should integrate this for 4.8 already as I'm concerned about the performance: The instantiation of QRegExp is extremely timeconsuming and currently it is done when filtering each item.

One approach to fix this would be make the QRegExp static but I'd like to prevent this if possible. I'd prefer having a small helper class that contains:
- The QRegExp
- The nameFilter already "toLowered"

The helper class would be instantiated on-the-fly as soon as a filter is applied. So we'd replace the QString m_nameFilter member by something like:

KFileItemModelNameFilter* m_nameFilter;

The class should be located outside of kfileitemmodel.cpp as kfileitemmodelnamefilter_p.h + kfileitemmodelnamefilter.cpp

This is of course more work than the current patch but would allow us to tune the performance without cluttering KFileItemModel. If you'd like to improve it this way we could integrate this into 4.8 already. Please just e-mail me directly if there are open questions or if you have a better idea. If you don't have time I'll check this after 4.8...
Comment 5 Peter Penz 2011-12-09 08:00:17 UTC
*** Bug 181216 has been marked as a duplicate of this bug. ***
Comment 6 A JANARDHAN REDDY 2011-12-10 09:29:00 UTC
Created attachment 66584 [details]
Static initialisation of QRegExp in helper Class

Every time a new name_filter is set, the function pointer (matchNameFilter) is pointed to appropriate function,So each time it is not checked whether namefilter is regular expression or not. I have not checked whether new name filter is equal to old name filter because it's done in kfileitemmode.cpp .I have not removed QString m_namefilter, i think we can have some performance improvement by catching, 
e.g: if old name filter was 'hom' and new name filter is 'home' we need not
check which items from removed items should be showed again.
and similarly if old name filter was 'home' and new name filter is 'hom' we need not check which items from shown items should be removed.
We can utilize caching( may be later) when namefilter is not regular expression.
Comment 7 A JANARDHAN REDDY 2011-12-10 12:47:16 UTC
Created attachment 66587 [details]
corrected patch
Comment 8 A JANARDHAN REDDY 2011-12-10 13:06:13 UTC
Comment on attachment 66587 [details]
corrected patch

>diff --git a/dolphin/src/CMakeLists.txt b/dolphin/src/CMakeLists.txt
>index c5c02e1..3297bbf 100644
>--- a/dolphin/src/CMakeLists.txt
>+++ b/dolphin/src/CMakeLists.txt
>@@ -23,6 +23,7 @@ set(dolphinprivate_LIB_SRCS
>     kitemviews/kfileitemlistview.cpp
>     kitemviews/kfileitemlistwidget.cpp
>     kitemviews/kfileitemmodel.cpp
>+    kitemviews/kfileitemmodel_filter.cpp
>     kitemviews/kfileitemmodelrolesupdater.cpp
>     kitemviews/kitemlistcontainer.cpp
>     kitemviews/kitemlistcontroller.cpp
>diff --git a/dolphin/src/kitemviews/kfileitemmodel.cpp b/dolphin/src/kitemviews/kfileitemmodel.cpp
>index c0adce9..9ae7027 100644
>--- a/dolphin/src/kitemviews/kfileitemmodel.cpp
>+++ b/dolphin/src/kitemviews/kfileitemmodel.cpp
>@@ -479,10 +479,10 @@ void KFileItemModel::setExpanded(const QSet<KUrl>& urls)
> 
> void KFileItemModel::setNameFilter(const QString& nameFilter)
> {
>-    if (m_nameFilter != nameFilter) {
>+    if (m_nameFilter.filter() != nameFilter) {
>         dispatchPendingItemsToInsert();
> 
>-        m_nameFilter = nameFilter;
>+	m_nameFilter.setFilter(nameFilter);
> 
>         // Check which shown items from m_itemData must get
>         // hidden and hence moved to m_filteredItems.
>@@ -516,7 +516,7 @@ void KFileItemModel::setNameFilter(const QString& nameFilter)
> 
> QString KFileItemModel::nameFilter() const
> {
>-    return m_nameFilter;
>+    return m_nameFilter.filter();
> }
> 
> void KFileItemModel::onGroupedSortingChanged(bool current)
>@@ -648,7 +648,7 @@ void KFileItemModel::slotCanceled()
> 
> void KFileItemModel::slotNewItems(const KFileItemList& items)
> {
>-    if (m_nameFilter.isEmpty()) {
>+    if (m_nameFilter.filter().isEmpty()) {
>         m_pendingItemsToInsert.append(items);
>     } else {
>         // The name-filter is active. Hide filtered items
>@@ -1737,7 +1737,7 @@ bool KFileItemModel::matchesNameFilter(const KFileItem& item) const
> 
>     // TODO #2: If the user entered a '*' use a regular expression
>     const QString itemText = item.text().toLower();
>-    return itemText.contains(m_nameFilter.toLower());
>+    return m_nameFilter.matches(itemText);
> }
> 
> #include "kfileitemmodel.moc"
>diff --git a/dolphin/src/kitemviews/kfileitemmodel.h b/dolphin/src/kitemviews/kfileitemmodel.h
>index 5d0aa42..aeb5002 100644
>--- a/dolphin/src/kitemviews/kfileitemmodel.h
>+++ b/dolphin/src/kitemviews/kfileitemmodel.h
>@@ -24,6 +24,7 @@
> #include <KFileItemList>
> #include <KUrl>
> #include <kitemviews/kitemmodelbase.h>
>+#include <kitemviews/kfileitemmodel_filter.h>
> 
> #include <QHash>
> 
>@@ -292,7 +293,7 @@ private:
>     QList<ItemData*> m_itemData;
>     QHash<KUrl, int> m_items; // Allows O(1) access for KFileItemModel::index(const KFileItem& item)
> 
>-    QString m_nameFilter;
>+    kFileItemModelFilter m_nameFilter;
>     QSet<KFileItem> m_filteredItems; // Items that got hidden by KFileItemModel::setNameFilter()
> 
>     bool m_requestRole[RolesCount];
>diff --git a/dolphin/src/kitemviews/kfileitemmodel_filter.cpp b/dolphin/src/kitemviews/kfileitemmodel_filter.cpp
>new file mode 100644
>index 0000000..58490bd
>--- /dev/null
>+++ b/dolphin/src/kitemviews/kfileitemmodel_filter.cpp
>@@ -0,0 +1,38 @@
>+
>+#include "kfileitemmodel_filter.h"
>+
>+kFileItemModelFilter::kFileItemModelFilter()
>+{
>+   rx.setCaseSensitivity(Qt::CaseInsensitive);
>+   rx.setMinimal(false);
>+   rx.setPatternSyntax(QRegExp::WildcardUnix);
>+}
>+
>+void kFileItemModelFilter::setFilter(const QString& filter)
>+{
>+  if(filter.contains('*') || filter.contains('?') || filter.contains('[')) {
>+    isRegExp = true;
>+    rx.setPattern(filter);
>+    m_nameFilter = filter;
>+  } else {
>+    isRegExp = false;
>+    m_nameFilter = filter;
>+  }
>+}
>+
>+QString kFileItemModelFilter::filter() const
>+{
>+  return m_nameFilter;
>+}
>+
>+bool kFileItemModelFilter::matches(const QString& name) const
>+{
>+  if(isRegExp)
>+    return rx.exactMatch(name);
>+  else
>+    return name.contains(m_nameFilter);
>+}
>+
>+
>+
>+
>+
>diff --git a/dolphin/src/kitemviews/kfileitemmodel_filter.h b/dolphin/src/kitemviews/kfileitemmodel_filter.h
>new file mode 100644
>index 0000000..f4d91df
>--- /dev/null
>+++ b/dolphin/src/kitemviews/kfileitemmodel_filter.h
>@@ -0,0 +1,24 @@
>+#ifndef KFILEITEMMODELFILTER_H
>+#define KFILEITEMMODELFILTER_H
>+
>+#include <QString>
>+#include <QRegExp>
>+
>+class kFileItemModelFilter
>+{
>+    
>+  public:
>+    kFileItemModelFilter();
>+   
>+    void setFilter(const QString& filter);
>+    QString filter() const;
>+
>+    bool matches(const QString& name) const;
>+    
>+  private:
>+    QRegExp rx;
>+    QString m_nameFilter;
>+    bool isRegExp;
>+};
>+
>+#endif // KFILEITEMMODELFILTER_H
Comment 9 Peter Penz 2011-12-10 20:30:50 UTC
Git commit c1d4e8b294cbcd246c382829c0a4f6021d645546 by Peter Penz.
Committed on 10/12/2011 at 21:28.
Pushed by ppenz into branch 'master'.

Support wildcards for the filter

Thanks to Janardhan Reddy for the patch!

BUG: 155986
FIXED-IN: 4.8.0

M  +1    -0    dolphin/src/CMakeLists.txt
M  +8    -19   dolphin/src/kitemviews/kfileitemmodel.cpp
M  +2    -6    dolphin/src/kitemviews/kfileitemmodel.h
A  +74   -0    dolphin/src/kitemviews/kfileitemmodelfilter.cpp     [License: GPL (v2+)]
A  +73   -0    dolphin/src/kitemviews/kfileitemmodelfilter_p.h     [License: GPL (v2+)]

http://commits.kde.org/kde-baseapps/c1d4e8b294cbcd246c382829c0a4f6021d645546