Implemented the new KParts' listing filter extension, KParts::ListingFilterExtension.

REVIEW: 106289
(cherry picked from commit cb79ee6a88)
This commit is contained in:
Dawit Alemayehu 2012-09-03 17:53:03 -04:00
parent 0016f150ae
commit 055ad286aa
8 changed files with 232 additions and 39 deletions

View file

@ -61,7 +61,6 @@ DolphinPart::DolphinPart(QWidget* parentWidget, QObject* parent, const QVariantL
Q_UNUSED(args)
setComponentData(DolphinPartFactory::componentData(), false);
m_extension = new DolphinPartBrowserExtension(this);
new DolphinPartFileInfoExtension(this);
// make sure that other apps using this part find Dolphin's view-file-columns icons
KIconLoader::global()->addAppDir("dolphin");
@ -116,6 +115,11 @@ DolphinPart::DolphinPart(QWidget* parentWidget, QObject* parent, const QVariantL
connect(clipboard, SIGNAL(dataChanged()),
this, SLOT(updatePasteAction()));
// Create file info and listing filter extensions.
// NOTE: Listing filter needs to be instantiated after the creation of the view.
new DolphinPartFileInfoExtension(this);
new DolphinPartListingFilterExtension(this);
createActions();
m_actionHandler->updateViewActions();
slotSelectionChanged(KFileItemList()); // initially disable selection-dependent actions
@ -647,4 +651,59 @@ KFileItemList DolphinPartFileInfoExtension::queryFor(KParts::FileInfoExtension::
return list;
}
DolphinPartListingFilterExtension::DolphinPartListingFilterExtension (DolphinPart* part)
: KParts::ListingFilterExtension(part)
, m_part(part)
{
}
KParts::ListingFilterExtension::FilterModes DolphinPartListingFilterExtension::supportedFilterModes() const
{
return (KParts::ListingFilterExtension::MimeType |
KParts::ListingFilterExtension::SubString |
KParts::ListingFilterExtension::WildCard);
}
bool DolphinPartListingFilterExtension::supportsMultipleFilters (KParts::ListingFilterExtension::FilterMode mode) const
{
if (mode == KParts::ListingFilterExtension::MimeType)
return true;
return false;
}
QVariant DolphinPartListingFilterExtension::filter (KParts::ListingFilterExtension::FilterMode mode) const
{
QVariant result;
switch (mode) {
case KParts::ListingFilterExtension::MimeType:
result = m_part->view()->mimeTypeFilters();
break;
case KParts::ListingFilterExtension::SubString:
case KParts::ListingFilterExtension::WildCard:
result = m_part->view()->nameFilter();
break;
default:
break;
}
return result;
}
void DolphinPartListingFilterExtension::setFilter (KParts::ListingFilterExtension::FilterMode mode, const QVariant& filter)
{
switch (mode) {
case KParts::ListingFilterExtension::MimeType:
m_part->view()->setMimeTypeFilters(filter.toStringList());
break;
case KParts::ListingFilterExtension::SubString:
case KParts::ListingFilterExtension::WildCard:
m_part->view()->setNameFilter(filter.toString());
break;
default:
break;
}
}
#include "dolphinpart.moc"

View file

@ -23,6 +23,7 @@
#include <kparts/part.h>
#include <kparts/browserextension.h>
#include <kparts/fileinfoextension.h>
#include <kparts/listingextension.h>
#include <QItemSelectionModel>
@ -281,4 +282,19 @@ protected:
DolphinPart* part() const;
};
class DolphinPartListingFilterExtension : public KParts::ListingFilterExtension
{
Q_OBJECT
public:
DolphinPartListingFilterExtension (DolphinPart* part);
virtual FilterModes supportedFilterModes() const;
virtual bool supportsMultipleFilters (FilterMode mode) const;
virtual QVariant filter (FilterMode mode) const;
virtual void setFilter (FilterMode mode, const QVariant& filter);
private:
DolphinPart* m_part;
};
#endif /* DOLPHINPART_H */

View file

@ -508,40 +508,8 @@ void KFileItemModel::setNameFilter(const QString& nameFilter)
{
if (m_filter.pattern() != nameFilter) {
dispatchPendingItemsToInsert();
m_filter.setPattern(nameFilter);
// Check which shown items from m_itemData must get
// hidden and hence moved to m_filteredItems.
KFileItemList newFilteredItems;
foreach (ItemData* itemData, m_itemData) {
if (!m_filter.matches(itemData->item)) {
// Only filter non-expanded items as child items may never
// exist without a parent item
if (!itemData->values.value("isExpanded").toBool()) {
newFilteredItems.append(itemData->item);
m_filteredItems.insert(itemData->item);
}
}
}
removeItems(newFilteredItems);
// Check which hidden items from m_filteredItems should
// get visible again and hence removed from m_filteredItems.
KFileItemList newVisibleItems;
QMutableSetIterator<KFileItem> it(m_filteredItems);
while (it.hasNext()) {
const KFileItem item = it.next();
if (m_filter.matches(item)) {
newVisibleItems.append(item);
it.remove();
}
}
insertItems(newVisibleItems);
applyFilters();
}
}
@ -550,6 +518,56 @@ QString KFileItemModel::nameFilter() const
return m_filter.pattern();
}
void KFileItemModel::setMimeTypeFilters(const QStringList& filters)
{
if (m_filter.mimeTypes() != filters) {
dispatchPendingItemsToInsert();
m_filter.setMimeTypes(filters);
applyFilters();
}
}
QStringList KFileItemModel::mimeTypeFilters() const
{
return m_filter.mimeTypes();
}
void KFileItemModel::applyFilters()
{
// Check which shown items from m_itemData must get
// hidden and hence moved to m_filteredItems.
KFileItemList newFilteredItems;
foreach (ItemData* itemData, m_itemData) {
// Only filter non-expanded items as child items may never
// exist without a parent item
if (!itemData->values.value("isExpanded").toBool()) {
if (!m_filter.matches(itemData->item)) {
newFilteredItems.append(itemData->item);
m_filteredItems.insert(itemData->item);
}
}
}
removeItems(newFilteredItems);
// Check which hidden items from m_filteredItems should
// get visible again and hence removed from m_filteredItems.
KFileItemList newVisibleItems;
QMutableSetIterator<KFileItem> it(m_filteredItems);
while (it.hasNext()) {
const KFileItem item = it.next();
if (m_filter.matches(item)) {
newVisibleItems.append(item);
it.remove();
}
}
insertItems(newVisibleItems);
}
QList<KFileItemModel::RoleInfo> KFileItemModel::rolesInformation()
{
static QList<RoleInfo> rolesInfo;
@ -729,10 +747,10 @@ void KFileItemModel::slotNewItems(const KFileItemList& items)
}
}
if (m_filter.pattern().isEmpty()) {
if (!m_filter.hasSetFilters()) {
m_pendingItemsToInsert.append(items);
} else {
// The name-filter is active. Hide filtered items
// The name or type filter is active. Hide filtered items
// before inserting them into the model and remember
// the filtered items in m_filteredItems.
KFileItemList filteredItems;

View file

@ -179,6 +179,9 @@ public:
void setNameFilter(const QString& nameFilter);
QString nameFilter() const;
void setMimeTypeFilters(const QStringList& filters);
QStringList mimeTypeFilters() const;
struct RoleInfo
{ QByteArray role;
QString translation;
@ -388,6 +391,11 @@ private:
*/
void emitSortProgress(int resolvedCount);
/**
* Applies the filters set through @ref setNameFilter and @ref setMimeTypeFilters.
*/
void applyFilters();
/**
* Maps the QByteArray-roles to RoleTypes and provides translation- and
* group-contexts.

View file

@ -23,6 +23,7 @@
#include <KFileItem>
#include <QRegExp>
KFileItemModelFilter::KFileItemModelFilter() :
m_useRegExp(false),
m_regExp(0),
@ -61,7 +62,46 @@ QString KFileItemModelFilter::pattern() const
return m_pattern;
}
void KFileItemModelFilter::setMimeTypes(const QStringList& types)
{
m_mimeTypes = types;
}
QStringList KFileItemModelFilter::mimeTypes() const
{
return m_mimeTypes;
}
bool KFileItemModelFilter::hasSetFilters() const
{
return (!m_pattern.isEmpty() || !m_mimeTypes.isEmpty());
}
bool KFileItemModelFilter::matches(const KFileItem& item) const
{
const bool hasPatternFilter = !m_pattern.isEmpty();
const bool hasMimeTypesFilter = !m_mimeTypes.isEmpty();
// If no filter is set, return true.
if (!hasPatternFilter && !hasMimeTypesFilter) {
return true;
}
// If both filters are set, return true when both filters are matched
if (hasPatternFilter && hasMimeTypesFilter) {
return (matchesPattern(item) && matchesType(item));
}
// If only one filter is set, return true when that filter is matched
if (hasPatternFilter) {
return matchesPattern(item);
}
return matchesType(item);
}
bool KFileItemModelFilter::matchesPattern(const KFileItem& item) const
{
if (m_useRegExp) {
return m_regExp->exactMatch(item.text());
@ -69,3 +109,14 @@ bool KFileItemModelFilter::matches(const KFileItem& item) const
return item.text().toLower().contains(m_lowerCasePattern);
}
}
bool KFileItemModelFilter::matchesType(const KFileItem& item) const
{
foreach (const QString& mimeType, m_mimeTypes) {
if (item.mimetype() == mimeType) {
return true;
}
}
return m_mimeTypes.isEmpty();
}

View file

@ -22,7 +22,7 @@
#define KFILEITEMMODELFILTER_H
#include <libdolphin_export.h>
#include <QString>
#include <QStringList>
class KFileItem;
class QRegExp;
@ -51,19 +51,42 @@ public:
void setPattern(const QString& pattern);
QString pattern() const;
/**
* Set the list of mimetypes that are used for comparison with the
* item in KFileItemModelFilter::matchesMimeType.
*/
void setMimeTypes(const QStringList& types);
QStringList mimeTypes() const;
/**
* @return True if either the pattern or mimetype filters has been set.
*/
bool hasSetFilters() const;
/**
* @return True if the item matches with the pattern defined by
* KFileItemModelFilter::setPattern().
* @ref setPattern() or @ref setMimeTypes
*/
bool matches(const KFileItem& item) const;
private:
/**
* @return True if item matches pattern set by @ref setPattern.
*/
bool matchesPattern(const KFileItem& item) const;
/**
* @return True if item matches mimetypes set by @ref setMimeTypes.
*/
bool matchesType(const KFileItem& item) const;
bool m_useRegExp; // If true, m_regExp is used for filtering,
// otherwise m_lowerCaseFilter is used.
QRegExp* m_regExp;
QString m_lowerCasePattern; // Lowercase version of m_filter for
// faster comparison in matches().
QString m_pattern; // Property set by setFilter().
QString m_pattern; // Property set by setPattern().
QStringList m_mimeTypes; // Property set by setMimeTypes()
};
#endif

View file

@ -510,6 +510,16 @@ QString DolphinView::nameFilter() const
return m_model->nameFilter();
}
void DolphinView::setMimeTypeFilters(const QStringList& filters)
{
return m_model->setMimeTypeFilters(filters);
}
QStringList DolphinView::mimeTypeFilters() const
{
return m_model->mimeTypeFilters();
}
QString DolphinView::statusBarText() const
{
QString summary;

View file

@ -237,6 +237,14 @@ public:
void setNameFilter(const QString& nameFilter);
QString nameFilter() const;
/**
* Filters the currently shown items by \a filters. All items
* whose content-type matches those given by the list of filters
* will be shown.
*/
void setMimeTypeFilters(const QStringList& filters);
QStringList mimeTypeFilters() const;
/**
* Returns a textual representation of the state of the current
* folder or selected items, suitable for use in the status bar.