mirror of
https://invent.kde.org/system/dolphin
synced 2024-07-04 17:30:55 +00:00
Merge branch 'work/zakharafoniam/useful-groups' into 'master'
Separate criteria for grouping and sorting (like Explorer and Finder do) See merge request system/dolphin!785
This commit is contained in:
commit
825520fca3
|
@ -305,10 +305,13 @@ void DolphinContextMenu::addViewportContextMenu()
|
||||||
}
|
}
|
||||||
addSeparator();
|
addSeparator();
|
||||||
|
|
||||||
// Insert 'Sort By' and 'View Mode'
|
// Insert 'Sort By', 'Group By' and 'View Mode'
|
||||||
if (ContextMenuSettings::showSortBy()) {
|
if (ContextMenuSettings::showSortBy()) {
|
||||||
addAction(m_mainWindow->actionCollection()->action(QStringLiteral("sort")));
|
addAction(m_mainWindow->actionCollection()->action(QStringLiteral("sort")));
|
||||||
}
|
}
|
||||||
|
if (ContextMenuSettings::showGroupBy()) {
|
||||||
|
addAction(m_mainWindow->actionCollection()->action(QStringLiteral("group")));
|
||||||
|
}
|
||||||
if (ContextMenuSettings::showViewMode()) {
|
if (ContextMenuSettings::showViewMode()) {
|
||||||
addAction(m_mainWindow->actionCollection()->action(QStringLiteral("view_mode")));
|
addAction(m_mainWindow->actionCollection()->action(QStringLiteral("view_mode")));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1496,6 +1496,7 @@ void DolphinMainWindow::updateHamburgerMenu()
|
||||||
}
|
}
|
||||||
menu->addAction(ac->action(QStringLiteral("show_hidden_files")));
|
menu->addAction(ac->action(QStringLiteral("show_hidden_files")));
|
||||||
menu->addAction(ac->action(QStringLiteral("sort")));
|
menu->addAction(ac->action(QStringLiteral("sort")));
|
||||||
|
menu->addAction(ac->action(QStringLiteral("group")));
|
||||||
menu->addAction(ac->action(QStringLiteral("additional_info")));
|
menu->addAction(ac->action(QStringLiteral("additional_info")));
|
||||||
if (!GeneralSettings::showStatusBar() || !GeneralSettings::showZoomSlider()) {
|
if (!GeneralSettings::showStatusBar() || !GeneralSettings::showZoomSlider()) {
|
||||||
menu->addAction(ac->action(QStringLiteral("zoom")));
|
menu->addAction(ac->action(QStringLiteral("zoom")));
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
</Menu>
|
</Menu>
|
||||||
<Menu name="view"><text>&View</text>
|
<Menu name="view"><text>&View</text>
|
||||||
<Action name="sort" />
|
<Action name="sort" />
|
||||||
|
<Action name="group" />
|
||||||
<Action name="additional_info" />
|
<Action name="additional_info" />
|
||||||
<Action name="show_preview" />
|
<Action name="show_preview" />
|
||||||
<Action name="show_in_groups" />
|
<Action name="show_in_groups" />
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
<Action name="view_zoom_out"/>
|
<Action name="view_zoom_out"/>
|
||||||
<Separator/>
|
<Separator/>
|
||||||
<Action name="sort" />
|
<Action name="sort" />
|
||||||
|
<Action name="group" />
|
||||||
<Action name="view_mode" />
|
<Action name="view_mode" />
|
||||||
<Action name="additional_info" />
|
<Action name="additional_info" />
|
||||||
<Action name="show_preview" />
|
<Action name="show_preview" />
|
||||||
|
|
|
@ -452,8 +452,9 @@ void KFileItemListView::applyRolesToModel()
|
||||||
roles.insert("expandedParentsCount");
|
roles.insert("expandedParentsCount");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assure that the role that is used for sorting will be determined
|
// Assure that the roles used for sorting and grouping will be determined
|
||||||
roles.insert(fileItemModel->sortRole());
|
roles.insert(fileItemModel->sortRole());
|
||||||
|
roles.insert(fileItemModel->groupRole());
|
||||||
|
|
||||||
fileItemModel->setRoles(roles);
|
fileItemModel->setRoles(roles);
|
||||||
m_modelRolesUpdater->setRoles(roles);
|
m_modelRolesUpdater->setRoles(roles);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -196,6 +196,13 @@ public:
|
||||||
bool requiresIndexer;
|
bool requiresIndexer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Provides static information for a role that is supported
|
||||||
|
* by KFileItemModel. Some roles can only be determined if
|
||||||
|
* Baloo is enabled and/or the Baloo indexing is enabled.
|
||||||
|
*/
|
||||||
|
static RoleInfo roleInformation(const QByteArray &role);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Provides static information for all available roles that
|
* @return Provides static information for all available roles that
|
||||||
* are supported by KFileItemModel. Some roles can only be
|
* are supported by KFileItemModel. Some roles can only be
|
||||||
|
@ -204,6 +211,13 @@ public:
|
||||||
*/
|
*/
|
||||||
static QList<RoleInfo> rolesInformation();
|
static QList<RoleInfo> rolesInformation();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Provides static information for all available grouping
|
||||||
|
* behaviors supported by KFileItemModel but not directly
|
||||||
|
* mapped to roles of KFileItemModel.
|
||||||
|
*/
|
||||||
|
static QList<RoleInfo> extraGroupingInformation();
|
||||||
|
|
||||||
/** set to true to hide application/x-trash files */
|
/** set to true to hide application/x-trash files */
|
||||||
void setShowTrashMime(bool show);
|
void setShowTrashMime(bool show);
|
||||||
|
|
||||||
|
@ -287,11 +301,13 @@ protected:
|
||||||
void onGroupedSortingChanged(bool current) override;
|
void onGroupedSortingChanged(bool current) override;
|
||||||
void onSortRoleChanged(const QByteArray ¤t, const QByteArray &previous, bool resortItems = true) override;
|
void onSortRoleChanged(const QByteArray ¤t, const QByteArray &previous, bool resortItems = true) override;
|
||||||
void onSortOrderChanged(Qt::SortOrder current, Qt::SortOrder previous) override;
|
void onSortOrderChanged(Qt::SortOrder current, Qt::SortOrder previous) override;
|
||||||
|
void onGroupRoleChanged(const QByteArray ¤t, const QByteArray &previous, bool resortItems = true) override;
|
||||||
|
void onGroupOrderChanged(Qt::SortOrder current, Qt::SortOrder previous) override;
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
/**
|
/**
|
||||||
* Resorts all items dependent on the set sortRole(), sortOrder()
|
* Resorts all items dependent on the set sortRole(), sortOrder(),
|
||||||
* and foldersFirst() settings.
|
* groupRole(), groupOrder() and foldersFirst() settings.
|
||||||
*/
|
*/
|
||||||
void resortAllItems();
|
void resortAllItems();
|
||||||
|
|
||||||
|
@ -365,6 +381,15 @@ private:
|
||||||
ItemData *parent;
|
ItemData *parent;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ItemGroupInfo {
|
||||||
|
int comparable;
|
||||||
|
QString text;
|
||||||
|
|
||||||
|
bool operator==(const ItemGroupInfo &other) const;
|
||||||
|
bool operator!=(const ItemGroupInfo &other) const;
|
||||||
|
bool operator<(const ItemGroupInfo &other) const;
|
||||||
|
};
|
||||||
|
|
||||||
enum RemoveItemsBehavior { KeepItemData, DeleteItemData, DeleteItemDataIfUnfiltered };
|
enum RemoveItemsBehavior { KeepItemData, DeleteItemData, DeleteItemDataIfUnfiltered };
|
||||||
|
|
||||||
void insertItems(QList<ItemData *> &items);
|
void insertItems(QList<ItemData *> &items);
|
||||||
|
@ -378,6 +403,12 @@ private:
|
||||||
*/
|
*/
|
||||||
QList<ItemData *> createItemDataList(const QUrl &parentUrl, const KFileItemList &items) const;
|
QList<ItemData *> createItemDataList(const QUrl &parentUrl, const KFileItemList &items) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method for prepareItemsForSorting().
|
||||||
|
* For a set role, fills 'values' of ItemData non-lazily.
|
||||||
|
*/
|
||||||
|
void prepareItemsWithRole(QList<ItemData *> &itemDataList, RoleType roleType);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepares the items for sorting. Normally, the hash 'values' in ItemData is filled
|
* Prepares the items for sorting. Normally, the hash 'values' in ItemData is filled
|
||||||
* lazily to save time and memory, but for some sort roles, it is expected that the
|
* lazily to save time and memory, but for some sort roles, it is expected that the
|
||||||
|
@ -445,13 +476,29 @@ private:
|
||||||
*/
|
*/
|
||||||
int sortRoleCompare(const ItemData *a, const ItemData *b, const QCollator &collator) const;
|
int sortRoleCompare(const ItemData *a, const ItemData *b, const QCollator &collator) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method for lessThan() and expandedParentsCountCompare(): Compares
|
||||||
|
* the passed item-data using m_groupRole as criteria. Both items must
|
||||||
|
* have the same parent item, otherwise the comparison will be wrong.
|
||||||
|
*/
|
||||||
|
int groupRoleCompare(const ItemData *a, const ItemData *b, const QCollator &collator) const;
|
||||||
|
|
||||||
int stringCompare(const QString &a, const QString &b, const QCollator &collator) const;
|
int stringCompare(const QString &a, const QString &b, const QCollator &collator) const;
|
||||||
|
|
||||||
|
ItemGroupInfo nameRoleGroup(const ItemData *itemData, bool withString = true) const;
|
||||||
|
ItemGroupInfo sizeRoleGroup(const ItemData *itemData, bool withString = true) const;
|
||||||
|
ItemGroupInfo timeRoleGroup(const std::function<QDateTime(const ItemData *)> &fileTimeCb, const ItemData *itemData, bool withString = true) const;
|
||||||
|
ItemGroupInfo permissionRoleGroup(const ItemData *itemData, bool withString = true) const;
|
||||||
|
ItemGroupInfo ratingRoleGroup(const ItemData *itemData, bool withString = true) const;
|
||||||
|
ItemGroupInfo typeRoleGroup(const ItemData *itemData) const;
|
||||||
|
ItemGroupInfo genericStringRoleGroup(const QByteArray &role, const ItemData *itemData) const;
|
||||||
|
|
||||||
QList<QPair<int, QVariant>> nameRoleGroups() const;
|
QList<QPair<int, QVariant>> nameRoleGroups() const;
|
||||||
QList<QPair<int, QVariant>> sizeRoleGroups() const;
|
QList<QPair<int, QVariant>> sizeRoleGroups() const;
|
||||||
QList<QPair<int, QVariant>> timeRoleGroups(const std::function<QDateTime(const ItemData *)> &fileTimeCb) const;
|
QList<QPair<int, QVariant>> timeRoleGroups(const std::function<QDateTime(const ItemData *)> &fileTimeCb) const;
|
||||||
QList<QPair<int, QVariant>> permissionRoleGroups() const;
|
QList<QPair<int, QVariant>> permissionRoleGroups() const;
|
||||||
QList<QPair<int, QVariant>> ratingRoleGroups() const;
|
QList<QPair<int, QVariant>> ratingRoleGroups() const;
|
||||||
|
QList<QPair<int, QVariant>> typeRoleGroups() const;
|
||||||
QList<QPair<int, QVariant>> genericStringRoleGroups(const QByteArray &typeForRole) const;
|
QList<QPair<int, QVariant>> genericStringRoleGroups(const QByteArray &typeForRole) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -542,6 +589,10 @@ private:
|
||||||
bool m_sortHiddenLast;
|
bool m_sortHiddenLast;
|
||||||
|
|
||||||
RoleType m_sortRole;
|
RoleType m_sortRole;
|
||||||
|
RoleType m_groupRole;
|
||||||
|
QByteArray m_sortExtraInfo;
|
||||||
|
QByteArray m_groupExtraInfo;
|
||||||
|
|
||||||
int m_sortingProgressPercent; // Value of directorySortingProgress() signal
|
int m_sortingProgressPercent; // Value of directorySortingProgress() signal
|
||||||
QSet<QByteArray> m_roles;
|
QSet<QByteArray> m_roles;
|
||||||
|
|
||||||
|
@ -600,4 +651,14 @@ inline bool KFileItemModel::isChildItem(int index) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool KFileItemModel::ItemGroupInfo::operator==(const ItemGroupInfo &other) const
|
||||||
|
{
|
||||||
|
return comparable == other.comparable && text == other.text;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool KFileItemModel::ItemGroupInfo::operator!=(const ItemGroupInfo &other) const
|
||||||
|
{
|
||||||
|
return comparable != other.comparable || text != other.text;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -368,7 +368,7 @@ void KFileItemModelRolesUpdater::slotItemsInserted(const KItemRangeList &itemRan
|
||||||
timer.start();
|
timer.start();
|
||||||
|
|
||||||
// Determine the sort role synchronously for as many items as possible.
|
// Determine the sort role synchronously for as many items as possible.
|
||||||
if (m_resolvableRoles.contains(m_model->sortRole())) {
|
if (m_resolvableRoles.contains(m_model->sortRole()) || m_resolvableRoles.contains(m_model->groupRole())) {
|
||||||
int insertedCount = 0;
|
int insertedCount = 0;
|
||||||
for (const KItemRange &range : itemRanges) {
|
for (const KItemRange &range : itemRanges) {
|
||||||
const int lastIndex = insertedCount + range.index + range.count - 1;
|
const int lastIndex = insertedCount + range.index + range.count - 1;
|
||||||
|
@ -1218,13 +1218,13 @@ void KFileItemModelRolesUpdater::applySortRole(int index)
|
||||||
QHash<QByteArray, QVariant> data;
|
QHash<QByteArray, QVariant> data;
|
||||||
const KFileItem item = m_model->fileItem(index);
|
const KFileItem item = m_model->fileItem(index);
|
||||||
|
|
||||||
if (m_model->sortRole() == "type") {
|
if (m_model->sortRole() == "type" || m_model->groupRole() == "type") {
|
||||||
if (!item.isMimeTypeKnown()) {
|
if (!item.isMimeTypeKnown()) {
|
||||||
item.determineMimeType();
|
item.determineMimeType();
|
||||||
}
|
}
|
||||||
|
|
||||||
data.insert("type", item.mimeComment());
|
data.insert("type", item.mimeComment());
|
||||||
} else if (m_model->sortRole() == "size" && item.isLocalFile() && item.isDir()) {
|
} else if ((m_model->sortRole() == "size" || m_model->groupRole() == "size") && item.isLocalFile() && item.isDir()) {
|
||||||
startDirectorySizeCounting(item, index);
|
startDirectorySizeCounting(item, index);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -315,6 +315,8 @@ private:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolves the sort role of the item and applies it to the model.
|
* Resolves the sort role of the item and applies it to the model.
|
||||||
|
* Despite the name, this handles both sorting and grouping, as
|
||||||
|
* regrouping never happens without resorting at the same time.
|
||||||
*/
|
*/
|
||||||
void applySortRole(int index);
|
void applySortRole(int index);
|
||||||
|
|
||||||
|
|
|
@ -1481,6 +1481,26 @@ void KItemListView::slotSortRoleChanged(const QByteArray ¤t, const QByteAr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void KItemListView::slotGroupOrderChanged(Qt::SortOrder current, Qt::SortOrder previous)
|
||||||
|
{
|
||||||
|
Q_UNUSED(current)
|
||||||
|
Q_UNUSED(previous)
|
||||||
|
if (m_grouped) {
|
||||||
|
updateVisibleGroupHeaders();
|
||||||
|
doLayout(NoAnimation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void KItemListView::slotGroupRoleChanged(const QByteArray ¤t, const QByteArray &previous)
|
||||||
|
{
|
||||||
|
Q_UNUSED(current)
|
||||||
|
Q_UNUSED(previous)
|
||||||
|
if (m_grouped) {
|
||||||
|
updateVisibleGroupHeaders();
|
||||||
|
doLayout(NoAnimation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void KItemListView::slotCurrentChanged(int current, int previous)
|
void KItemListView::slotCurrentChanged(int current, int previous)
|
||||||
{
|
{
|
||||||
Q_UNUSED(previous)
|
Q_UNUSED(previous)
|
||||||
|
@ -1743,6 +1763,8 @@ void KItemListView::setModel(KItemModelBase *model)
|
||||||
disconnect(m_model, &KItemModelBase::groupedSortingChanged, this, &KItemListView::slotGroupedSortingChanged);
|
disconnect(m_model, &KItemModelBase::groupedSortingChanged, this, &KItemListView::slotGroupedSortingChanged);
|
||||||
disconnect(m_model, &KItemModelBase::sortOrderChanged, this, &KItemListView::slotSortOrderChanged);
|
disconnect(m_model, &KItemModelBase::sortOrderChanged, this, &KItemListView::slotSortOrderChanged);
|
||||||
disconnect(m_model, &KItemModelBase::sortRoleChanged, this, &KItemListView::slotSortRoleChanged);
|
disconnect(m_model, &KItemModelBase::sortRoleChanged, this, &KItemListView::slotSortRoleChanged);
|
||||||
|
disconnect(m_model, &KItemModelBase::groupOrderChanged, this, &KItemListView::slotGroupOrderChanged);
|
||||||
|
disconnect(m_model, &KItemModelBase::groupRoleChanged, this, &KItemListView::slotGroupRoleChanged);
|
||||||
|
|
||||||
m_sizeHintResolver->itemsRemoved(KItemRangeList() << KItemRange(0, m_model->count()));
|
m_sizeHintResolver->itemsRemoved(KItemRangeList() << KItemRange(0, m_model->count()));
|
||||||
}
|
}
|
||||||
|
@ -2185,7 +2207,7 @@ void KItemListView::updateGroupHeaderForWidget(KItemListWidget *widget)
|
||||||
const int groupIndex = groupIndexForItem(index);
|
const int groupIndex = groupIndexForItem(index);
|
||||||
Q_ASSERT(groupIndex >= 0);
|
Q_ASSERT(groupIndex >= 0);
|
||||||
groupHeader->setData(groups.at(groupIndex).second);
|
groupHeader->setData(groups.at(groupIndex).second);
|
||||||
groupHeader->setRole(model()->sortRole());
|
groupHeader->setRole(model()->groupRole());
|
||||||
groupHeader->setStyleOption(m_styleOption);
|
groupHeader->setStyleOption(m_styleOption);
|
||||||
groupHeader->setScrollOrientation(scrollOrientation());
|
groupHeader->setScrollOrientation(scrollOrientation());
|
||||||
groupHeader->setItemIndex(index);
|
groupHeader->setItemIndex(index);
|
||||||
|
|
|
@ -430,6 +430,8 @@ protected Q_SLOTS:
|
||||||
virtual void slotGroupedSortingChanged(bool current);
|
virtual void slotGroupedSortingChanged(bool current);
|
||||||
virtual void slotSortOrderChanged(Qt::SortOrder current, Qt::SortOrder previous);
|
virtual void slotSortOrderChanged(Qt::SortOrder current, Qt::SortOrder previous);
|
||||||
virtual void slotSortRoleChanged(const QByteArray ¤t, const QByteArray &previous);
|
virtual void slotSortRoleChanged(const QByteArray ¤t, const QByteArray &previous);
|
||||||
|
virtual void slotGroupOrderChanged(Qt::SortOrder current, Qt::SortOrder previous);
|
||||||
|
virtual void slotGroupRoleChanged(const QByteArray ¤t, const QByteArray &previous);
|
||||||
virtual void slotCurrentChanged(int current, int previous);
|
virtual void slotCurrentChanged(int current, int previous);
|
||||||
virtual void slotSelectionChanged(const KItemSet ¤t, const KItemSet &previous);
|
virtual void slotSelectionChanged(const KItemSet ¤t, const KItemSet &previous);
|
||||||
|
|
||||||
|
@ -552,8 +554,9 @@ private:
|
||||||
void recycleGroupHeaderForWidget(KItemListWidget *widget);
|
void recycleGroupHeaderForWidget(KItemListWidget *widget);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method for slotGroupedSortingChanged(), slotSortOrderChanged()
|
* Helper method for slotGroupedSortingChanged(), slotSortOrderChanged(),
|
||||||
* and slotSortRoleChanged(): Iterates through all visible items and updates
|
* slotSortRoleChanged(), slotGroupOrderChanged() and slotGroupRoleChanged():
|
||||||
|
* Iterates through all visible items and updates
|
||||||
* the group-header widgets.
|
* the group-header widgets.
|
||||||
*/
|
*/
|
||||||
void updateVisibleGroupHeaders();
|
void updateVisibleGroupHeaders();
|
||||||
|
|
|
@ -10,17 +10,21 @@
|
||||||
|
|
||||||
KItemModelBase::KItemModelBase(QObject *parent)
|
KItemModelBase::KItemModelBase(QObject *parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
, m_groupedSorting(false)
|
, m_groupedSorting(true)
|
||||||
, m_sortRole()
|
, m_sortRole()
|
||||||
, m_sortOrder(Qt::AscendingOrder)
|
, m_sortOrder(Qt::AscendingOrder)
|
||||||
|
, m_groupRole()
|
||||||
|
, m_groupOrder(Qt::AscendingOrder)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
KItemModelBase::KItemModelBase(const QByteArray &sortRole, QObject *parent)
|
KItemModelBase::KItemModelBase(const QByteArray &sortRole, const QByteArray &groupRole, QObject *parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
, m_groupedSorting(false)
|
, m_groupedSorting(true)
|
||||||
, m_sortRole(sortRole)
|
, m_sortRole(sortRole)
|
||||||
, m_sortOrder(Qt::AscendingOrder)
|
, m_sortOrder(Qt::AscendingOrder)
|
||||||
|
, m_groupRole(groupRole)
|
||||||
|
, m_groupOrder(Qt::AscendingOrder)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,6 +78,31 @@ void KItemModelBase::setSortOrder(Qt::SortOrder order)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void KItemModelBase::setGroupRole(const QByteArray &role, bool regroupItems)
|
||||||
|
{
|
||||||
|
if (role != m_groupRole) {
|
||||||
|
const QByteArray previous = m_groupRole;
|
||||||
|
m_groupRole = role;
|
||||||
|
onGroupRoleChanged(role, previous, regroupItems);
|
||||||
|
Q_EMIT groupRoleChanged(role, previous);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray KItemModelBase::groupRole() const
|
||||||
|
{
|
||||||
|
return m_groupRole;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KItemModelBase::setGroupOrder(Qt::SortOrder order)
|
||||||
|
{
|
||||||
|
if (order != m_groupOrder) {
|
||||||
|
const Qt::SortOrder previous = m_groupOrder;
|
||||||
|
m_groupOrder = order;
|
||||||
|
onGroupOrderChanged(order, previous);
|
||||||
|
Q_EMIT groupOrderChanged(order, previous);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QString KItemModelBase::roleDescription(const QByteArray &role) const
|
QString KItemModelBase::roleDescription(const QByteArray &role) const
|
||||||
{
|
{
|
||||||
return QString::fromLatin1(role);
|
return QString::fromLatin1(role);
|
||||||
|
@ -157,6 +186,19 @@ void KItemModelBase::onSortOrderChanged(Qt::SortOrder current, Qt::SortOrder pre
|
||||||
Q_UNUSED(previous)
|
Q_UNUSED(previous)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void KItemModelBase::onGroupRoleChanged(const QByteArray ¤t, const QByteArray &previous, bool resortItems)
|
||||||
|
{
|
||||||
|
Q_UNUSED(current)
|
||||||
|
Q_UNUSED(previous)
|
||||||
|
Q_UNUSED(resortItems)
|
||||||
|
}
|
||||||
|
|
||||||
|
void KItemModelBase::onGroupOrderChanged(Qt::SortOrder current, Qt::SortOrder previous)
|
||||||
|
{
|
||||||
|
Q_UNUSED(current)
|
||||||
|
Q_UNUSED(previous)
|
||||||
|
}
|
||||||
|
|
||||||
QUrl KItemModelBase::url(int index) const
|
QUrl KItemModelBase::url(int index) const
|
||||||
{
|
{
|
||||||
return data(index).value("url").toUrl();
|
return data(index).value("url").toUrl();
|
||||||
|
|
|
@ -41,7 +41,7 @@ class DOLPHIN_EXPORT KItemModelBase : public QObject
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit KItemModelBase(QObject *parent = nullptr);
|
explicit KItemModelBase(QObject *parent = nullptr);
|
||||||
explicit KItemModelBase(const QByteArray &sortRole, QObject *parent = nullptr);
|
explicit KItemModelBase(const QByteArray &sortRole, const QByteArray &groupRole, QObject *parent = nullptr);
|
||||||
~KItemModelBase() override;
|
~KItemModelBase() override;
|
||||||
|
|
||||||
/** @return The number of items. */
|
/** @return The number of items. */
|
||||||
|
@ -84,6 +84,23 @@ public:
|
||||||
void setSortOrder(Qt::SortOrder order);
|
void setSortOrder(Qt::SortOrder order);
|
||||||
Qt::SortOrder sortOrder() const;
|
Qt::SortOrder sortOrder() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the group-role to \a role. The method KItemModelBase::onGroupRoleChanged() will be
|
||||||
|
* called so that model-implementations can react on the group-role change. Afterwards the
|
||||||
|
* signal groupRoleChanged() will be emitted.
|
||||||
|
* The implementation should regroup only if \a regroupItems is true.
|
||||||
|
*/
|
||||||
|
void setGroupRole(const QByteArray &role, bool regroupItems = true);
|
||||||
|
QByteArray groupRole() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the group order to \a order. The method KItemModelBase::onGroupOrderChanged() will be
|
||||||
|
* called so that model-implementations can react on the group order change. Afterwards the
|
||||||
|
* signal groupOrderChanged() will be emitted.
|
||||||
|
*/
|
||||||
|
void setGroupOrder(Qt::SortOrder order);
|
||||||
|
Qt::SortOrder groupOrder() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Translated description for the \p role. The description is e.g. used
|
* @return Translated description for the \p role. The description is e.g. used
|
||||||
* for the header in KItemListView.
|
* for the header in KItemListView.
|
||||||
|
@ -247,6 +264,8 @@ Q_SIGNALS:
|
||||||
void groupedSortingChanged(bool current);
|
void groupedSortingChanged(bool current);
|
||||||
void sortRoleChanged(const QByteArray ¤t, const QByteArray &previous);
|
void sortRoleChanged(const QByteArray ¤t, const QByteArray &previous);
|
||||||
void sortOrderChanged(Qt::SortOrder current, Qt::SortOrder previous);
|
void sortOrderChanged(Qt::SortOrder current, Qt::SortOrder previous);
|
||||||
|
void groupRoleChanged(const QByteArray ¤t, const QByteArray &previous);
|
||||||
|
void groupOrderChanged(Qt::SortOrder current, Qt::SortOrder previous);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
|
@ -276,10 +295,33 @@ protected:
|
||||||
*/
|
*/
|
||||||
virtual void onSortOrderChanged(Qt::SortOrder current, Qt::SortOrder previous);
|
virtual void onSortOrderChanged(Qt::SortOrder current, Qt::SortOrder previous);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is invoked if the sort role has been changed by KItemModelBase::setSortRole(). Allows
|
||||||
|
* to react on the changed sort role before the signal sortRoleChanged() will be emitted.
|
||||||
|
* The implementation must assure that the items are sorted by the role given by \a current.
|
||||||
|
* Usually the most efficient way is to emit a
|
||||||
|
* itemsRemoved() signal for all items, reorder the items internally and to emit a
|
||||||
|
* itemsInserted() signal afterwards.
|
||||||
|
* The implementation should resort only if \a regroupItems is true.
|
||||||
|
*/
|
||||||
|
virtual void onGroupRoleChanged(const QByteArray ¤t, const QByteArray &previous, bool regroupItems = true);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is invoked if the sort order has been changed by KItemModelBase::setSortOrder(). Allows
|
||||||
|
* to react on the changed sort order before the signal sortOrderChanged() will be emitted.
|
||||||
|
* The implementation must assure that the items are sorted by the order given by \a current.
|
||||||
|
* Usually the most efficient way is to emit a
|
||||||
|
* itemsRemoved() signal for all items, reorder the items internally and to emit a
|
||||||
|
* itemsInserted() signal afterwards.
|
||||||
|
*/
|
||||||
|
virtual void onGroupOrderChanged(Qt::SortOrder current, Qt::SortOrder previous);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_groupedSorting;
|
bool m_groupedSorting;
|
||||||
QByteArray m_sortRole;
|
QByteArray m_sortRole;
|
||||||
Qt::SortOrder m_sortOrder;
|
Qt::SortOrder m_sortOrder;
|
||||||
|
QByteArray m_groupRole;
|
||||||
|
Qt::SortOrder m_groupOrder;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline Qt::SortOrder KItemModelBase::sortOrder() const
|
inline Qt::SortOrder KItemModelBase::sortOrder() const
|
||||||
|
@ -287,4 +329,9 @@ inline Qt::SortOrder KItemModelBase::sortOrder() const
|
||||||
return m_sortOrder;
|
return m_sortOrder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline Qt::SortOrder KItemModelBase::groupOrder() const
|
||||||
|
{
|
||||||
|
return m_groupOrder;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -24,6 +24,8 @@ ApplyViewPropsJob::ApplyViewPropsJob(const QUrl &dir, const ViewProperties &view
|
||||||
m_viewProps->setHiddenFilesShown(viewProps.hiddenFilesShown());
|
m_viewProps->setHiddenFilesShown(viewProps.hiddenFilesShown());
|
||||||
m_viewProps->setSortRole(viewProps.sortRole());
|
m_viewProps->setSortRole(viewProps.sortRole());
|
||||||
m_viewProps->setSortOrder(viewProps.sortOrder());
|
m_viewProps->setSortOrder(viewProps.sortOrder());
|
||||||
|
m_viewProps->setGroupRole(viewProps.groupRole());
|
||||||
|
m_viewProps->setGroupOrder(viewProps.groupOrder());
|
||||||
|
|
||||||
KIO::ListJob *listJob = KIO::listRecursive(dir, KIO::HideProgressInfo);
|
KIO::ListJob *listJob = KIO::listRecursive(dir, KIO::HideProgressInfo);
|
||||||
connect(listJob, &KIO::ListJob::entries, this, &ApplyViewPropsJob::slotEntries);
|
connect(listJob, &KIO::ListJob::entries, this, &ApplyViewPropsJob::slotEntries);
|
||||||
|
|
|
@ -110,6 +110,8 @@ bool ContextMenuSettingsPage::entryVisible(const QString &id)
|
||||||
return ContextMenuSettings::showAddToPlaces();
|
return ContextMenuSettings::showAddToPlaces();
|
||||||
} else if (id == "sort") {
|
} else if (id == "sort") {
|
||||||
return ContextMenuSettings::showSortBy();
|
return ContextMenuSettings::showSortBy();
|
||||||
|
} else if (id == "group") {
|
||||||
|
return ContextMenuSettings::showGroupBy();
|
||||||
} else if (id == "view_mode") {
|
} else if (id == "view_mode") {
|
||||||
return ContextMenuSettings::showViewMode();
|
return ContextMenuSettings::showViewMode();
|
||||||
} else if (id == "open_in_new_tab") {
|
} else if (id == "open_in_new_tab") {
|
||||||
|
@ -138,6 +140,8 @@ void ContextMenuSettingsPage::setEntryVisible(const QString &id, bool visible)
|
||||||
ContextMenuSettings::setShowAddToPlaces(visible);
|
ContextMenuSettings::setShowAddToPlaces(visible);
|
||||||
} else if (id == "sort") {
|
} else if (id == "sort") {
|
||||||
ContextMenuSettings::setShowSortBy(visible);
|
ContextMenuSettings::setShowSortBy(visible);
|
||||||
|
} else if (id == "group") {
|
||||||
|
ContextMenuSettings::setShowGroupBy(visible);
|
||||||
} else if (id == "view_mode") {
|
} else if (id == "view_mode") {
|
||||||
ContextMenuSettings::setShowViewMode(visible);
|
ContextMenuSettings::setShowViewMode(visible);
|
||||||
} else if (id == "open_in_new_tab") {
|
} else if (id == "open_in_new_tab") {
|
||||||
|
|
|
@ -18,6 +18,10 @@
|
||||||
<label>Show 'Sort By' in context menu.</label>
|
<label>Show 'Sort By' in context menu.</label>
|
||||||
<default>true</default>
|
<default>true</default>
|
||||||
</entry>
|
</entry>
|
||||||
|
<entry name="ShowGroupBy" type="Bool">
|
||||||
|
<label>Show 'Group By' in context menu.</label>
|
||||||
|
<default>true</default>
|
||||||
|
</entry>
|
||||||
<entry name="ShowViewMode" type="Bool">
|
<entry name="ShowViewMode" type="Bool">
|
||||||
<label>Show 'View Mode' in context menu.</label>
|
<label>Show 'View Mode' in context menu.</label>
|
||||||
<default>true</default>
|
<default>true</default>
|
||||||
|
|
|
@ -35,8 +35,8 @@
|
||||||
|
|
||||||
<entry name="GroupedSorting" type="Bool" >
|
<entry name="GroupedSorting" type="Bool" >
|
||||||
<label context="@label">Grouped Sorting</label>
|
<label context="@label">Grouped Sorting</label>
|
||||||
<whatsthis context="@info:whatsthis">When this option is enabled, the sorted items are categorized into groups.</whatsthis>
|
<whatsthis context="@info:whatsthis">When this option is enabled, the items are categorized into groups.</whatsthis>
|
||||||
<default>false</default>
|
<default>true</default>
|
||||||
</entry>
|
</entry>
|
||||||
|
|
||||||
<entry name="SortRole" type="String" >
|
<entry name="SortRole" type="String" >
|
||||||
|
@ -52,6 +52,19 @@
|
||||||
<max code="true">Qt::DescendingOrder</max>
|
<max code="true">Qt::DescendingOrder</max>
|
||||||
</entry>
|
</entry>
|
||||||
|
|
||||||
|
<entry name="GroupRole" type="String" >
|
||||||
|
<label context="@label">Group files by</label>
|
||||||
|
<whatsthis context="@info:whatsthis">This option defines which attribute (text, size, date, etc.) grouping is performed on.</whatsthis>
|
||||||
|
<default>none</default>
|
||||||
|
</entry>
|
||||||
|
|
||||||
|
<entry name="GroupOrder" type="Int" >
|
||||||
|
<label context="@label">Order in which to group files</label>
|
||||||
|
<default code="true">Qt::AscendingOrder</default>
|
||||||
|
<min code="true">Qt::AscendingOrder</min>
|
||||||
|
<max code="true">Qt::DescendingOrder</max>
|
||||||
|
</entry>
|
||||||
|
|
||||||
<entry name="SortFoldersFirst" type="Bool" >
|
<entry name="SortFoldersFirst" type="Bool" >
|
||||||
<label context="@label">Show folders first when sorting files and folders</label>
|
<label context="@label">Show folders first when sorting files and folders</label>
|
||||||
<default>true</default>
|
<default>true</default>
|
||||||
|
@ -84,5 +97,3 @@
|
||||||
</entry>
|
</entry>
|
||||||
</group>
|
</group>
|
||||||
</kcfg>
|
</kcfg>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,7 @@ DolphinSettingsDialog::DolphinSettingsDialog(const QUrl &url, QWidget *parent, K
|
||||||
actions,
|
actions,
|
||||||
{QStringLiteral("add_to_places"),
|
{QStringLiteral("add_to_places"),
|
||||||
QStringLiteral("sort"),
|
QStringLiteral("sort"),
|
||||||
|
QStringLiteral("group"),
|
||||||
QStringLiteral("view_mode"),
|
QStringLiteral("view_mode"),
|
||||||
QStringLiteral("open_in_new_tab"),
|
QStringLiteral("open_in_new_tab"),
|
||||||
QStringLiteral("open_in_new_window"),
|
QStringLiteral("open_in_new_window"),
|
||||||
|
|
|
@ -44,6 +44,8 @@ ViewPropertiesDialog::ViewPropertiesDialog(DolphinView *dolphinView)
|
||||||
, m_viewMode(nullptr)
|
, m_viewMode(nullptr)
|
||||||
, m_sortOrder(nullptr)
|
, m_sortOrder(nullptr)
|
||||||
, m_sorting(nullptr)
|
, m_sorting(nullptr)
|
||||||
|
, m_groupOrder(nullptr)
|
||||||
|
, m_grouping(nullptr)
|
||||||
, m_sortFoldersFirst(nullptr)
|
, m_sortFoldersFirst(nullptr)
|
||||||
, m_sortHiddenLast(nullptr)
|
, m_sortHiddenLast(nullptr)
|
||||||
, m_previewsShown(nullptr)
|
, m_previewsShown(nullptr)
|
||||||
|
@ -67,7 +69,7 @@ ViewPropertiesDialog::ViewPropertiesDialog(DolphinView *dolphinView)
|
||||||
// Otherwise the dialog won't resize when we collapse the KCollapsibleGroupBox.
|
// Otherwise the dialog won't resize when we collapse the KCollapsibleGroupBox.
|
||||||
layout->setSizeConstraint(QLayout::SetFixedSize);
|
layout->setSizeConstraint(QLayout::SetFixedSize);
|
||||||
|
|
||||||
// create 'Properties' group containing view mode, sorting, sort order and show hidden files
|
// create 'Properties' group containing view mode, sorting/grouping, sort/group order and show hidden files
|
||||||
m_viewMode = new QComboBox();
|
m_viewMode = new QComboBox();
|
||||||
m_viewMode->addItem(QIcon::fromTheme(QStringLiteral("view-list-icons")), i18nc("@item:inlistbox", "Icons"), DolphinView::IconsView);
|
m_viewMode->addItem(QIcon::fromTheme(QStringLiteral("view-list-icons")), i18nc("@item:inlistbox", "Icons"), DolphinView::IconsView);
|
||||||
m_viewMode->addItem(QIcon::fromTheme(QStringLiteral("view-list-details")), i18nc("@item:inlistbox", "Compact"), DolphinView::CompactView);
|
m_viewMode->addItem(QIcon::fromTheme(QStringLiteral("view-list-details")), i18nc("@item:inlistbox", "Compact"), DolphinView::CompactView);
|
||||||
|
@ -83,6 +85,16 @@ ViewPropertiesDialog::ViewPropertiesDialog(DolphinView *dolphinView)
|
||||||
m_sorting->addItem(info.translation, info.role);
|
m_sorting->addItem(info.translation, info.role);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_groupOrder = new QComboBox();
|
||||||
|
m_groupOrder->addItem(i18nc("@item:inlistbox Group", "Ascending"));
|
||||||
|
m_groupOrder->addItem(i18nc("@item:inlistbox Group", "Descending"));
|
||||||
|
|
||||||
|
m_grouping = new QComboBox();
|
||||||
|
const QList<KFileItemModel::RoleInfo> combinedGroupingInfo = rolesInfo + KFileItemModel::extraGroupingInformation();
|
||||||
|
for (const KFileItemModel::RoleInfo &info : combinedGroupingInfo) {
|
||||||
|
m_grouping->addItem(info.translation, info.role);
|
||||||
|
}
|
||||||
|
|
||||||
m_sortFoldersFirst = new QCheckBox(i18nc("@option:check", "Show folders first"));
|
m_sortFoldersFirst = new QCheckBox(i18nc("@option:check", "Show folders first"));
|
||||||
m_sortHiddenLast = new QCheckBox(i18nc("@option:check", "Show hidden files last"));
|
m_sortHiddenLast = new QCheckBox(i18nc("@option:check", "Show hidden files last"));
|
||||||
m_previewsShown = new QCheckBox(i18nc("@option:check", "Show preview"));
|
m_previewsShown = new QCheckBox(i18nc("@option:check", "Show preview"));
|
||||||
|
@ -139,8 +151,14 @@ ViewPropertiesDialog::ViewPropertiesDialog(DolphinView *dolphinView)
|
||||||
sortingLayout->addWidget(m_sortOrder);
|
sortingLayout->addWidget(m_sortOrder);
|
||||||
sortingLayout->addWidget(m_sorting);
|
sortingLayout->addWidget(m_sorting);
|
||||||
|
|
||||||
|
QHBoxLayout *groupingLayout = new QHBoxLayout();
|
||||||
|
groupingLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
groupingLayout->addWidget(m_groupOrder);
|
||||||
|
groupingLayout->addWidget(m_grouping);
|
||||||
|
|
||||||
layout->addRow(i18nc("@label:listbox", "View mode:"), m_viewMode);
|
layout->addRow(i18nc("@label:listbox", "View mode:"), m_viewMode);
|
||||||
layout->addRow(i18nc("@label:listbox", "Sorting:"), sortingLayout);
|
layout->addRow(i18nc("@label:listbox", "Sorting:"), sortingLayout);
|
||||||
|
layout->addRow(i18nc("@label:listbox", "Grouping:"), groupingLayout);
|
||||||
|
|
||||||
layout->addItem(new QSpacerItem(0, Dolphin::VERTICAL_SPACER_HEIGHT, QSizePolicy::Fixed, QSizePolicy::Fixed));
|
layout->addItem(new QSpacerItem(0, Dolphin::VERTICAL_SPACER_HEIGHT, QSizePolicy::Fixed, QSizePolicy::Fixed));
|
||||||
|
|
||||||
|
@ -153,6 +171,8 @@ ViewPropertiesDialog::ViewPropertiesDialog(DolphinView *dolphinView)
|
||||||
connect(m_viewMode, &QComboBox::currentIndexChanged, this, &ViewPropertiesDialog::slotViewModeChanged);
|
connect(m_viewMode, &QComboBox::currentIndexChanged, this, &ViewPropertiesDialog::slotViewModeChanged);
|
||||||
connect(m_sorting, &QComboBox::currentIndexChanged, this, &ViewPropertiesDialog::slotSortingChanged);
|
connect(m_sorting, &QComboBox::currentIndexChanged, this, &ViewPropertiesDialog::slotSortingChanged);
|
||||||
connect(m_sortOrder, &QComboBox::currentIndexChanged, this, &ViewPropertiesDialog::slotSortOrderChanged);
|
connect(m_sortOrder, &QComboBox::currentIndexChanged, this, &ViewPropertiesDialog::slotSortOrderChanged);
|
||||||
|
connect(m_grouping, &QComboBox::currentIndexChanged, this, &ViewPropertiesDialog::slotGroupingChanged);
|
||||||
|
connect(m_groupOrder, &QComboBox::currentIndexChanged, this, &ViewPropertiesDialog::slotGroupOrderChanged);
|
||||||
connect(m_sortFoldersFirst, &QCheckBox::clicked, this, &ViewPropertiesDialog::slotSortFoldersFirstChanged);
|
connect(m_sortFoldersFirst, &QCheckBox::clicked, this, &ViewPropertiesDialog::slotSortFoldersFirstChanged);
|
||||||
connect(m_sortHiddenLast, &QCheckBox::clicked, this, &ViewPropertiesDialog::slotSortHiddenLastChanged);
|
connect(m_sortHiddenLast, &QCheckBox::clicked, this, &ViewPropertiesDialog::slotSortHiddenLastChanged);
|
||||||
connect(m_previewsShown, &QCheckBox::clicked, this, &ViewPropertiesDialog::slotShowPreviewChanged);
|
connect(m_previewsShown, &QCheckBox::clicked, this, &ViewPropertiesDialog::slotShowPreviewChanged);
|
||||||
|
@ -259,6 +279,20 @@ void ViewPropertiesDialog::slotSortOrderChanged(int index)
|
||||||
markAsDirty(true);
|
markAsDirty(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ViewPropertiesDialog::slotGroupingChanged(int index)
|
||||||
|
{
|
||||||
|
const QByteArray role = m_grouping->itemData(index).toByteArray();
|
||||||
|
m_viewProps->setGroupRole(role);
|
||||||
|
markAsDirty(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewPropertiesDialog::slotGroupOrderChanged(int index)
|
||||||
|
{
|
||||||
|
const Qt::SortOrder groupOrder = (index == 0) ? Qt::AscendingOrder : Qt::DescendingOrder;
|
||||||
|
m_viewProps->setGroupOrder(groupOrder);
|
||||||
|
markAsDirty(true);
|
||||||
|
}
|
||||||
|
|
||||||
void ViewPropertiesDialog::slotGroupedSortingChanged()
|
void ViewPropertiesDialog::slotGroupedSortingChanged()
|
||||||
{
|
{
|
||||||
m_viewProps->setGroupedSorting(m_showInGroups->isChecked());
|
m_viewProps->setGroupedSorting(m_showInGroups->isChecked());
|
||||||
|
@ -377,6 +411,8 @@ void ViewPropertiesDialog::applyViewProperties()
|
||||||
m_dolphinView->setViewMode(m_viewProps->viewMode());
|
m_dolphinView->setViewMode(m_viewProps->viewMode());
|
||||||
m_dolphinView->setSortRole(m_viewProps->sortRole());
|
m_dolphinView->setSortRole(m_viewProps->sortRole());
|
||||||
m_dolphinView->setSortOrder(m_viewProps->sortOrder());
|
m_dolphinView->setSortOrder(m_viewProps->sortOrder());
|
||||||
|
m_dolphinView->setGroupRole(m_viewProps->groupRole());
|
||||||
|
m_dolphinView->setGroupOrder(m_viewProps->groupOrder());
|
||||||
m_dolphinView->setSortFoldersFirst(m_viewProps->sortFoldersFirst());
|
m_dolphinView->setSortFoldersFirst(m_viewProps->sortFoldersFirst());
|
||||||
m_dolphinView->setSortHiddenLast(m_viewProps->sortHiddenLast());
|
m_dolphinView->setSortHiddenLast(m_viewProps->sortHiddenLast());
|
||||||
m_dolphinView->setGroupedSorting(m_viewProps->groupedSorting());
|
m_dolphinView->setGroupedSorting(m_viewProps->groupedSorting());
|
||||||
|
@ -423,6 +459,20 @@ void ViewPropertiesDialog::loadSettings()
|
||||||
m_sortFoldersFirst->setChecked(m_viewProps->sortFoldersFirst());
|
m_sortFoldersFirst->setChecked(m_viewProps->sortFoldersFirst());
|
||||||
m_sortHiddenLast->setChecked(m_viewProps->sortHiddenLast());
|
m_sortHiddenLast->setChecked(m_viewProps->sortHiddenLast());
|
||||||
|
|
||||||
|
// Load group order and sorting
|
||||||
|
const int groupOrderIndex = (m_viewProps->groupOrder() == Qt::AscendingOrder) ? 0 : 1;
|
||||||
|
m_groupOrder->setCurrentIndex(groupOrderIndex);
|
||||||
|
|
||||||
|
const QList<KFileItemModel::RoleInfo> combinedGroupingInfo = rolesInfo + KFileItemModel::extraGroupingInformation();
|
||||||
|
int groupRoleIndex = 0;
|
||||||
|
for (int i = 0; i < combinedGroupingInfo.count(); ++i) {
|
||||||
|
if (combinedGroupingInfo[i].role == m_viewProps->groupRole()) {
|
||||||
|
groupRoleIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_grouping->setCurrentIndex(groupRoleIndex);
|
||||||
|
|
||||||
// Load show preview, show in groups and show hidden files settings
|
// Load show preview, show in groups and show hidden files settings
|
||||||
m_previewsShown->setChecked(m_viewProps->previewsShown());
|
m_previewsShown->setChecked(m_viewProps->previewsShown());
|
||||||
m_showInGroups->setChecked(m_viewProps->groupedSorting());
|
m_showInGroups->setChecked(m_viewProps->groupedSorting());
|
||||||
|
|
|
@ -44,6 +44,8 @@ private Q_SLOTS:
|
||||||
void slotViewModeChanged(int index);
|
void slotViewModeChanged(int index);
|
||||||
void slotSortingChanged(int index);
|
void slotSortingChanged(int index);
|
||||||
void slotSortOrderChanged(int index);
|
void slotSortOrderChanged(int index);
|
||||||
|
void slotGroupingChanged(int index);
|
||||||
|
void slotGroupOrderChanged(int index);
|
||||||
void slotGroupedSortingChanged();
|
void slotGroupedSortingChanged();
|
||||||
void slotSortFoldersFirstChanged();
|
void slotSortFoldersFirstChanged();
|
||||||
void slotSortHiddenLastChanged();
|
void slotSortHiddenLastChanged();
|
||||||
|
@ -67,6 +69,8 @@ private:
|
||||||
QComboBox *m_viewMode;
|
QComboBox *m_viewMode;
|
||||||
QComboBox *m_sortOrder;
|
QComboBox *m_sortOrder;
|
||||||
QComboBox *m_sorting;
|
QComboBox *m_sorting;
|
||||||
|
QComboBox *m_groupOrder;
|
||||||
|
QComboBox *m_grouping;
|
||||||
QCheckBox *m_sortFoldersFirst;
|
QCheckBox *m_sortFoldersFirst;
|
||||||
QCheckBox *m_sortHiddenLast;
|
QCheckBox *m_sortHiddenLast;
|
||||||
QCheckBox *m_previewsShown;
|
QCheckBox *m_previewsShown;
|
||||||
|
|
|
@ -164,7 +164,7 @@ void KFileItemModelTest::testDefaultSortRole()
|
||||||
|
|
||||||
void KFileItemModelTest::testDefaultGroupedSorting()
|
void KFileItemModelTest::testDefaultGroupedSorting()
|
||||||
{
|
{
|
||||||
QCOMPARE(m_model->groupedSorting(), false);
|
QCOMPARE(m_model->groupedSorting(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void KFileItemModelTest::testNewItems()
|
void KFileItemModelTest::testNewItems()
|
||||||
|
@ -2007,6 +2007,7 @@ void KFileItemModelTest::testNameRoleGroups()
|
||||||
m_testDir->createFiles({"b.txt", "c.txt", "d.txt", "e.txt"});
|
m_testDir->createFiles({"b.txt", "c.txt", "d.txt", "e.txt"});
|
||||||
|
|
||||||
m_model->setGroupedSorting(true);
|
m_model->setGroupedSorting(true);
|
||||||
|
m_model->setGroupRole("text");
|
||||||
m_model->loadDirectory(m_testDir->url());
|
m_model->loadDirectory(m_testDir->url());
|
||||||
QVERIFY(itemsInsertedSpy.wait());
|
QVERIFY(itemsInsertedSpy.wait());
|
||||||
QCOMPARE(itemsInModel(),
|
QCOMPARE(itemsInModel(),
|
||||||
|
@ -2093,6 +2094,8 @@ void KFileItemModelTest::testNameRoleGroupsWithExpandedItems()
|
||||||
m_testDir->createFiles({"a/b.txt", "a/c.txt", "d/e.txt", "d/f.txt"});
|
m_testDir->createFiles({"a/b.txt", "a/c.txt", "d/e.txt", "d/f.txt"});
|
||||||
|
|
||||||
m_model->setGroupedSorting(true);
|
m_model->setGroupedSorting(true);
|
||||||
|
m_model->setGroupRole("text");
|
||||||
|
|
||||||
m_model->loadDirectory(m_testDir->url());
|
m_model->loadDirectory(m_testDir->url());
|
||||||
QVERIFY(itemsInsertedSpy.wait());
|
QVERIFY(itemsInsertedSpy.wait());
|
||||||
QCOMPARE(itemsInModel(),
|
QCOMPARE(itemsInModel(),
|
||||||
|
@ -2102,6 +2105,7 @@ void KFileItemModelTest::testNameRoleGroupsWithExpandedItems()
|
||||||
QList<QPair<int, QVariant>> expectedGroups;
|
QList<QPair<int, QVariant>> expectedGroups;
|
||||||
expectedGroups << QPair<int, QVariant>(0, QLatin1String("A"));
|
expectedGroups << QPair<int, QVariant>(0, QLatin1String("A"));
|
||||||
expectedGroups << QPair<int, QVariant>(1, QLatin1String("D"));
|
expectedGroups << QPair<int, QVariant>(1, QLatin1String("D"));
|
||||||
|
|
||||||
QCOMPARE(m_model->groups(), expectedGroups);
|
QCOMPARE(m_model->groups(), expectedGroups);
|
||||||
|
|
||||||
// Verify that expanding "a" and "d" will not change the groups (except for the index of "D").
|
// Verify that expanding "a" and "d" will not change the groups (except for the index of "D").
|
||||||
|
|
|
@ -503,6 +503,42 @@ Qt::SortOrder DolphinView::sortOrder() const
|
||||||
return m_model->sortOrder();
|
return m_model->sortOrder();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DolphinView::setGroupRole(const QByteArray &role)
|
||||||
|
{
|
||||||
|
if (role != groupRole()) {
|
||||||
|
ViewProperties props(viewPropertiesUrl());
|
||||||
|
props.setGroupRole(role);
|
||||||
|
|
||||||
|
KItemModelBase *model = m_container->controller()->model();
|
||||||
|
model->setGroupRole(role);
|
||||||
|
|
||||||
|
Q_EMIT groupRoleChanged(role);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray DolphinView::groupRole() const
|
||||||
|
{
|
||||||
|
const KItemModelBase *model = m_container->controller()->model();
|
||||||
|
return model->groupRole();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DolphinView::setGroupOrder(Qt::SortOrder order)
|
||||||
|
{
|
||||||
|
if (groupOrder() != order) {
|
||||||
|
ViewProperties props(viewPropertiesUrl());
|
||||||
|
props.setGroupOrder(order);
|
||||||
|
|
||||||
|
m_model->setGroupOrder(order);
|
||||||
|
|
||||||
|
Q_EMIT groupOrderChanged(order);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::SortOrder DolphinView::groupOrder() const
|
||||||
|
{
|
||||||
|
return m_model->groupOrder();
|
||||||
|
}
|
||||||
|
|
||||||
void DolphinView::setSortFoldersFirst(bool foldersFirst)
|
void DolphinView::setSortFoldersFirst(bool foldersFirst)
|
||||||
{
|
{
|
||||||
if (sortFoldersFirst() != foldersFirst) {
|
if (sortFoldersFirst() != foldersFirst) {
|
||||||
|
@ -2114,6 +2150,18 @@ void DolphinView::applyViewProperties(const ViewProperties &props)
|
||||||
Q_EMIT sortOrderChanged(sortOrder);
|
Q_EMIT sortOrderChanged(sortOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const QByteArray groupRole = props.groupRole();
|
||||||
|
if (groupRole != m_model->groupRole()) {
|
||||||
|
m_model->setGroupRole(groupRole);
|
||||||
|
Q_EMIT groupRoleChanged(groupRole);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Qt::SortOrder groupOrder = props.groupOrder();
|
||||||
|
if (groupOrder != m_model->groupOrder()) {
|
||||||
|
m_model->setGroupOrder(groupOrder);
|
||||||
|
Q_EMIT groupOrderChanged(groupOrder);
|
||||||
|
}
|
||||||
|
|
||||||
const bool sortFoldersFirst = props.sortFoldersFirst();
|
const bool sortFoldersFirst = props.sortFoldersFirst();
|
||||||
if (sortFoldersFirst != m_model->sortDirectoriesFirst()) {
|
if (sortFoldersFirst != m_model->sortDirectoriesFirst()) {
|
||||||
m_model->setSortDirectoriesFirst(sortFoldersFirst);
|
m_model->setSortDirectoriesFirst(sortFoldersFirst);
|
||||||
|
|
|
@ -51,6 +51,8 @@ class QRegularExpression;
|
||||||
* - show hidden files
|
* - show hidden files
|
||||||
* - show previews
|
* - show previews
|
||||||
* - enable grouping
|
* - enable grouping
|
||||||
|
* - grouping order
|
||||||
|
* - grouping type
|
||||||
*/
|
*/
|
||||||
class DOLPHIN_EXPORT DolphinView : public QWidget
|
class DOLPHIN_EXPORT DolphinView : public QWidget
|
||||||
{
|
{
|
||||||
|
@ -219,6 +221,20 @@ public:
|
||||||
void setSortOrder(Qt::SortOrder order);
|
void setSortOrder(Qt::SortOrder order);
|
||||||
Qt::SortOrder sortOrder() const;
|
Qt::SortOrder sortOrder() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the view properties of the current URL to the
|
||||||
|
* grouping given by \a role.
|
||||||
|
*/
|
||||||
|
void setGroupRole(const QByteArray &role);
|
||||||
|
QByteArray groupRole() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the view properties of the current URL to the
|
||||||
|
* sort order given by \a order.
|
||||||
|
*/
|
||||||
|
void setGroupOrder(Qt::SortOrder order);
|
||||||
|
Qt::SortOrder groupOrder() const;
|
||||||
|
|
||||||
/** Sets a separate sorting with folders first (true) or a mixed sorting of files and folders (false). */
|
/** Sets a separate sorting with folders first (true) or a mixed sorting of files and folders (false). */
|
||||||
void setSortFoldersFirst(bool foldersFirst);
|
void setSortFoldersFirst(bool foldersFirst);
|
||||||
bool sortFoldersFirst() const;
|
bool sortFoldersFirst() const;
|
||||||
|
@ -522,6 +538,12 @@ Q_SIGNALS:
|
||||||
/** Is emitted if the sort order (ascending or descending) has been changed. */
|
/** Is emitted if the sort order (ascending or descending) has been changed. */
|
||||||
void sortOrderChanged(Qt::SortOrder order);
|
void sortOrderChanged(Qt::SortOrder order);
|
||||||
|
|
||||||
|
/** Is emitted if the grouping by name, size or date has been changed. */
|
||||||
|
void groupRoleChanged(const QByteArray &role);
|
||||||
|
|
||||||
|
/** Is emitted if the group order (ascending or descending) has been changed. */
|
||||||
|
void groupOrderChanged(Qt::SortOrder order);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is emitted if the sorting of files and folders (separate with folders
|
* Is emitted if the sorting of files and folders (separate with folders
|
||||||
* first or mixed) has been changed.
|
* first or mixed) has been changed.
|
||||||
|
|
|
@ -33,6 +33,7 @@ DolphinViewActionHandler::DolphinViewActionHandler(KActionCollection *collection
|
||||||
, m_actionCollection(collection)
|
, m_actionCollection(collection)
|
||||||
, m_currentView(nullptr)
|
, m_currentView(nullptr)
|
||||||
, m_sortByActions()
|
, m_sortByActions()
|
||||||
|
, m_groupByActions()
|
||||||
, m_visibleRoles()
|
, m_visibleRoles()
|
||||||
{
|
{
|
||||||
Q_ASSERT(m_actionCollection);
|
Q_ASSERT(m_actionCollection);
|
||||||
|
@ -58,6 +59,8 @@ void DolphinViewActionHandler::setCurrentView(DolphinView *view)
|
||||||
connect(view, &DolphinView::groupedSortingChanged, this, &DolphinViewActionHandler::slotGroupedSortingChanged);
|
connect(view, &DolphinView::groupedSortingChanged, this, &DolphinViewActionHandler::slotGroupedSortingChanged);
|
||||||
connect(view, &DolphinView::hiddenFilesShownChanged, this, &DolphinViewActionHandler::slotHiddenFilesShownChanged);
|
connect(view, &DolphinView::hiddenFilesShownChanged, this, &DolphinViewActionHandler::slotHiddenFilesShownChanged);
|
||||||
connect(view, &DolphinView::sortRoleChanged, this, &DolphinViewActionHandler::slotSortRoleChanged);
|
connect(view, &DolphinView::sortRoleChanged, this, &DolphinViewActionHandler::slotSortRoleChanged);
|
||||||
|
connect(view, &DolphinView::groupRoleChanged, this, &DolphinViewActionHandler::slotGroupRoleChanged);
|
||||||
|
connect(view, &DolphinView::groupOrderChanged, this, &DolphinViewActionHandler::slotGroupOrderChanged);
|
||||||
connect(view, &DolphinView::zoomLevelChanged, this, &DolphinViewActionHandler::slotZoomLevelChanged);
|
connect(view, &DolphinView::zoomLevelChanged, this, &DolphinViewActionHandler::slotZoomLevelChanged);
|
||||||
connect(view, &DolphinView::writeStateChanged, this, &DolphinViewActionHandler::slotWriteStateChanged);
|
connect(view, &DolphinView::writeStateChanged, this, &DolphinViewActionHandler::slotWriteStateChanged);
|
||||||
slotWriteStateChanged(view->isFolderWritable());
|
slotWriteStateChanged(view->isFolderWritable());
|
||||||
|
@ -275,27 +278,60 @@ void DolphinViewActionHandler::createActions(SelectionMode::ActionTextHelper *ac
|
||||||
|
|
||||||
sortByActionMenu->addSeparator();
|
sortByActionMenu->addSeparator();
|
||||||
|
|
||||||
QActionGroup *group = new QActionGroup(sortByActionMenu);
|
QActionGroup *groupForSort = new QActionGroup(sortByActionMenu);
|
||||||
group->setExclusive(true);
|
groupForSort->setExclusive(true);
|
||||||
|
|
||||||
KToggleAction *ascendingAction = m_actionCollection->add<KToggleAction>(QStringLiteral("ascending"));
|
KToggleAction *sortAscendingAction = m_actionCollection->add<KToggleAction>(QStringLiteral("sort_ascending"));
|
||||||
ascendingAction->setActionGroup(group);
|
sortAscendingAction->setActionGroup(groupForSort);
|
||||||
connect(ascendingAction, &QAction::triggered, this, [this] {
|
connect(sortAscendingAction, &QAction::triggered, this, [this] {
|
||||||
m_currentView->setSortOrder(Qt::AscendingOrder);
|
m_currentView->setSortOrder(Qt::AscendingOrder);
|
||||||
});
|
});
|
||||||
|
|
||||||
KToggleAction *descendingAction = m_actionCollection->add<KToggleAction>(QStringLiteral("descending"));
|
KToggleAction *sortDescendingAction = m_actionCollection->add<KToggleAction>(QStringLiteral("sort_descending"));
|
||||||
descendingAction->setActionGroup(group);
|
sortDescendingAction->setActionGroup(groupForSort);
|
||||||
connect(descendingAction, &QAction::triggered, this, [this] {
|
connect(sortDescendingAction, &QAction::triggered, this, [this] {
|
||||||
m_currentView->setSortOrder(Qt::DescendingOrder);
|
m_currentView->setSortOrder(Qt::DescendingOrder);
|
||||||
});
|
});
|
||||||
|
|
||||||
sortByActionMenu->addAction(ascendingAction);
|
sortByActionMenu->addAction(sortAscendingAction);
|
||||||
sortByActionMenu->addAction(descendingAction);
|
sortByActionMenu->addAction(sortDescendingAction);
|
||||||
sortByActionMenu->addSeparator();
|
sortByActionMenu->addSeparator();
|
||||||
sortByActionMenu->addAction(sortFoldersFirst);
|
sortByActionMenu->addAction(sortFoldersFirst);
|
||||||
sortByActionMenu->addAction(sortHiddenLast);
|
sortByActionMenu->addAction(sortHiddenLast);
|
||||||
|
|
||||||
|
// View -> Group By
|
||||||
|
QActionGroup *groupByActionGroup = createFileItemRolesActionGroup(QStringLiteral("group_by_"));
|
||||||
|
|
||||||
|
KActionMenu *groupByActionMenu = m_actionCollection->add<KActionMenu>(QStringLiteral("group"));
|
||||||
|
groupByActionMenu->setIcon(QIcon::fromTheme(QStringLiteral("view-group")));
|
||||||
|
groupByActionMenu->setText(i18nc("@action:inmenu View", "Group By"));
|
||||||
|
groupByActionMenu->setPopupMode(QToolButton::InstantPopup);
|
||||||
|
|
||||||
|
const auto groupByActionGroupActions = groupByActionGroup->actions();
|
||||||
|
for (QAction *action : groupByActionGroupActions) {
|
||||||
|
groupByActionMenu->addAction(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
groupByActionMenu->addSeparator();
|
||||||
|
|
||||||
|
QActionGroup *groupForGroup = new QActionGroup(groupByActionMenu);
|
||||||
|
groupForGroup->setExclusive(true);
|
||||||
|
|
||||||
|
KToggleAction *groupAscendingAction = m_actionCollection->add<KToggleAction>(QStringLiteral("group_ascending"));
|
||||||
|
groupAscendingAction->setActionGroup(groupForGroup);
|
||||||
|
connect(groupAscendingAction, &QAction::triggered, this, [this] {
|
||||||
|
m_currentView->setGroupOrder(Qt::AscendingOrder);
|
||||||
|
});
|
||||||
|
|
||||||
|
KToggleAction *groupDescendingAction = m_actionCollection->add<KToggleAction>(QStringLiteral("group_descending"));
|
||||||
|
groupDescendingAction->setActionGroup(groupForGroup);
|
||||||
|
connect(groupDescendingAction, &QAction::triggered, this, [this] {
|
||||||
|
m_currentView->setGroupOrder(Qt::DescendingOrder);
|
||||||
|
});
|
||||||
|
|
||||||
|
groupByActionMenu->addAction(groupAscendingAction);
|
||||||
|
groupByActionMenu->addAction(groupDescendingAction);
|
||||||
|
|
||||||
// View -> Additional Information
|
// View -> Additional Information
|
||||||
QActionGroup *visibleRolesGroup = createFileItemRolesActionGroup(QStringLiteral("show_"));
|
QActionGroup *visibleRolesGroup = createFileItemRolesActionGroup(QStringLiteral("show_"));
|
||||||
|
|
||||||
|
@ -344,12 +380,15 @@ void DolphinViewActionHandler::createActions(SelectionMode::ActionTextHelper *ac
|
||||||
QActionGroup *DolphinViewActionHandler::createFileItemRolesActionGroup(const QString &groupPrefix)
|
QActionGroup *DolphinViewActionHandler::createFileItemRolesActionGroup(const QString &groupPrefix)
|
||||||
{
|
{
|
||||||
const bool isSortGroup = (groupPrefix == QLatin1String("sort_by_"));
|
const bool isSortGroup = (groupPrefix == QLatin1String("sort_by_"));
|
||||||
Q_ASSERT(isSortGroup || groupPrefix == QLatin1String("show_"));
|
const bool isGroupGroup = (groupPrefix == QLatin1String("group_by_"));
|
||||||
|
Q_ASSERT(isSortGroup || isGroupGroup || groupPrefix == QLatin1String("show_"));
|
||||||
|
|
||||||
QActionGroup *rolesActionGroup = new QActionGroup(m_actionCollection);
|
QActionGroup *rolesActionGroup = new QActionGroup(m_actionCollection);
|
||||||
rolesActionGroup->setExclusive(isSortGroup);
|
rolesActionGroup->setExclusive(isSortGroup || isGroupGroup);
|
||||||
if (isSortGroup) {
|
if (isSortGroup) {
|
||||||
connect(rolesActionGroup, &QActionGroup::triggered, this, &DolphinViewActionHandler::slotSortTriggered);
|
connect(rolesActionGroup, &QActionGroup::triggered, this, &DolphinViewActionHandler::slotSortTriggered);
|
||||||
|
} else if (isGroupGroup) {
|
||||||
|
connect(rolesActionGroup, &QActionGroup::triggered, this, &DolphinViewActionHandler::slotGroupTriggered);
|
||||||
} else {
|
} else {
|
||||||
connect(rolesActionGroup, &QActionGroup::triggered, this, &DolphinViewActionHandler::toggleVisibleRole);
|
connect(rolesActionGroup, &QActionGroup::triggered, this, &DolphinViewActionHandler::toggleVisibleRole);
|
||||||
}
|
}
|
||||||
|
@ -364,9 +403,13 @@ QActionGroup *DolphinViewActionHandler::createFileItemRolesActionGroup(const QSt
|
||||||
indexingEnabled = config.fileIndexingEnabled();
|
indexingEnabled = config.fileIndexingEnabled();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const QList<KFileItemModel::RoleInfo> rolesInfo = KFileItemModel::rolesInformation();
|
QList<KFileItemModel::RoleInfo> rolesInfo = KFileItemModel::rolesInformation();
|
||||||
|
if (isGroupGroup) {
|
||||||
|
rolesInfo += KFileItemModel::extraGroupingInformation();
|
||||||
|
}
|
||||||
|
|
||||||
for (const KFileItemModel::RoleInfo &info : rolesInfo) {
|
for (const KFileItemModel::RoleInfo &info : rolesInfo) {
|
||||||
if (!isSortGroup && info.role == "text") {
|
if (!isSortGroup && !isGroupGroup && info.role == "text") {
|
||||||
// It should not be possible to hide the "text" role
|
// It should not be possible to hide the "text" role
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -384,9 +427,11 @@ QActionGroup *DolphinViewActionHandler::createFileItemRolesActionGroup(const QSt
|
||||||
groupMenu->setActionGroup(rolesActionGroup);
|
groupMenu->setActionGroup(rolesActionGroup);
|
||||||
|
|
||||||
groupMenuGroup = new QActionGroup(groupMenu);
|
groupMenuGroup = new QActionGroup(groupMenu);
|
||||||
groupMenuGroup->setExclusive(isSortGroup);
|
groupMenuGroup->setExclusive(isSortGroup || isGroupGroup);
|
||||||
if (isSortGroup) {
|
if (isSortGroup) {
|
||||||
connect(groupMenuGroup, &QActionGroup::triggered, this, &DolphinViewActionHandler::slotSortTriggered);
|
connect(groupMenuGroup, &QActionGroup::triggered, this, &DolphinViewActionHandler::slotSortTriggered);
|
||||||
|
} else if (isGroupGroup) {
|
||||||
|
connect(groupMenuGroup, &QActionGroup::triggered, this, &DolphinViewActionHandler::slotGroupTriggered);
|
||||||
} else {
|
} else {
|
||||||
connect(groupMenuGroup, &QActionGroup::triggered, this, &DolphinViewActionHandler::toggleVisibleRole);
|
connect(groupMenuGroup, &QActionGroup::triggered, this, &DolphinViewActionHandler::toggleVisibleRole);
|
||||||
}
|
}
|
||||||
|
@ -404,6 +449,8 @@ QActionGroup *DolphinViewActionHandler::createFileItemRolesActionGroup(const QSt
|
||||||
|
|
||||||
if (isSortGroup) {
|
if (isSortGroup) {
|
||||||
m_sortByActions.insert(info.role, action);
|
m_sortByActions.insert(info.role, action);
|
||||||
|
} else if (isGroupGroup) {
|
||||||
|
m_groupByActions.insert(info.role, action);
|
||||||
} else {
|
} else {
|
||||||
m_visibleRoles.insert(info.role, action);
|
m_visibleRoles.insert(info.role, action);
|
||||||
}
|
}
|
||||||
|
@ -508,6 +555,8 @@ void DolphinViewActionHandler::updateViewActions()
|
||||||
slotVisibleRolesChanged(m_currentView->visibleRoles(), QList<QByteArray>());
|
slotVisibleRolesChanged(m_currentView->visibleRoles(), QList<QByteArray>());
|
||||||
slotGroupedSortingChanged(m_currentView->groupedSorting());
|
slotGroupedSortingChanged(m_currentView->groupedSorting());
|
||||||
slotSortRoleChanged(m_currentView->sortRole());
|
slotSortRoleChanged(m_currentView->sortRole());
|
||||||
|
slotGroupRoleChanged(m_currentView->groupRole());
|
||||||
|
slotGroupOrderChanged(m_currentView->groupOrder());
|
||||||
slotZoomLevelChanged(m_currentView->zoomLevel(), -1);
|
slotZoomLevelChanged(m_currentView->zoomLevel(), -1);
|
||||||
|
|
||||||
// Updates the "show_hidden_files" action state and icon
|
// Updates the "show_hidden_files" action state and icon
|
||||||
|
@ -548,13 +597,22 @@ void DolphinViewActionHandler::toggleSortHiddenLast()
|
||||||
|
|
||||||
void DolphinViewActionHandler::slotSortOrderChanged(Qt::SortOrder order)
|
void DolphinViewActionHandler::slotSortOrderChanged(Qt::SortOrder order)
|
||||||
{
|
{
|
||||||
QAction *descending = m_actionCollection->action(QStringLiteral("descending"));
|
QAction *descending = m_actionCollection->action(QStringLiteral("sort_descending"));
|
||||||
QAction *ascending = m_actionCollection->action(QStringLiteral("ascending"));
|
QAction *ascending = m_actionCollection->action(QStringLiteral("sort_ascending"));
|
||||||
const bool sortDescending = (order == Qt::DescendingOrder);
|
const bool sortDescending = (order == Qt::DescendingOrder);
|
||||||
descending->setChecked(sortDescending);
|
descending->setChecked(sortDescending);
|
||||||
ascending->setChecked(!sortDescending);
|
ascending->setChecked(!sortDescending);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DolphinViewActionHandler::slotGroupOrderChanged(Qt::SortOrder order)
|
||||||
|
{
|
||||||
|
QAction *descending = m_actionCollection->action(QStringLiteral("group_descending"));
|
||||||
|
QAction *ascending = m_actionCollection->action(QStringLiteral("group_ascending"));
|
||||||
|
const bool groupDescending = (order == Qt::DescendingOrder);
|
||||||
|
descending->setChecked(groupDescending);
|
||||||
|
ascending->setChecked(!groupDescending);
|
||||||
|
}
|
||||||
|
|
||||||
void DolphinViewActionHandler::slotSortFoldersFirstChanged(bool foldersFirst)
|
void DolphinViewActionHandler::slotSortFoldersFirstChanged(bool foldersFirst)
|
||||||
{
|
{
|
||||||
m_actionCollection->action(QStringLiteral("folders_first"))->setChecked(foldersFirst);
|
m_actionCollection->action(QStringLiteral("folders_first"))->setChecked(foldersFirst);
|
||||||
|
@ -674,8 +732,8 @@ void DolphinViewActionHandler::slotSortRoleChanged(const QByteArray &role)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QAction *descending = m_actionCollection->action(QStringLiteral("descending"));
|
QAction *descending = m_actionCollection->action(QStringLiteral("sort_descending"));
|
||||||
QAction *ascending = m_actionCollection->action(QStringLiteral("ascending"));
|
QAction *ascending = m_actionCollection->action(QStringLiteral("sort_ascending"));
|
||||||
|
|
||||||
if (role == "text" || role == "type" || role == "extension" || role == "tags" || role == "comment") {
|
if (role == "text" || role == "type" || role == "extension" || role == "tags" || role == "comment") {
|
||||||
descending->setText(i18nc("Sort descending", "Z-A"));
|
descending->setText(i18nc("Sort descending", "Z-A"));
|
||||||
|
@ -697,6 +755,50 @@ void DolphinViewActionHandler::slotSortRoleChanged(const QByteArray &role)
|
||||||
slotSortOrderChanged(m_currentView->sortOrder());
|
slotSortOrderChanged(m_currentView->sortOrder());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DolphinViewActionHandler::slotGroupRoleChanged(const QByteArray &role)
|
||||||
|
{
|
||||||
|
KToggleAction *action = m_groupByActions.value(role);
|
||||||
|
if (action) {
|
||||||
|
action->setChecked(true);
|
||||||
|
|
||||||
|
if (!action->icon().isNull()) {
|
||||||
|
QAction *groupByMenu = m_actionCollection->action(QStringLiteral("group"));
|
||||||
|
groupByMenu->setIcon(action->icon());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QAction *descending = m_actionCollection->action(QStringLiteral("group_descending"));
|
||||||
|
QAction *ascending = m_actionCollection->action(QStringLiteral("group_ascending"));
|
||||||
|
|
||||||
|
if (role == "text" || role == "type" || role == "extension" || role == "tags" || role == "comment") {
|
||||||
|
descending->setText(i18nc("Group descending", "Z-A"));
|
||||||
|
ascending->setText(i18nc("Group ascending", "A-Z"));
|
||||||
|
} else if (role == "size") {
|
||||||
|
descending->setText(i18nc("Group descending", "Largest First"));
|
||||||
|
ascending->setText(i18nc("Group ascending", "Smallest First"));
|
||||||
|
} else if (role == "modificationtime" || role == "creationtime" || role == "accesstime") {
|
||||||
|
descending->setText(i18nc("Group descending", "Newest First"));
|
||||||
|
ascending->setText(i18nc("Group ascending", "Oldest First"));
|
||||||
|
} else if (role == "rating") {
|
||||||
|
descending->setText(i18nc("Group descending", "Highest First"));
|
||||||
|
ascending->setText(i18nc("Group ascending", "Lowest First"));
|
||||||
|
} else {
|
||||||
|
descending->setText(i18nc("Group descending", "Descending"));
|
||||||
|
ascending->setText(i18nc("Group ascending", "Ascending"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable group order selector if grouping behavior does not support it
|
||||||
|
if (role == "none" || role == "followSort") {
|
||||||
|
descending->setEnabled(false);
|
||||||
|
ascending->setEnabled(false);
|
||||||
|
} else {
|
||||||
|
descending->setEnabled(true);
|
||||||
|
ascending->setEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
slotGroupOrderChanged(m_currentView->groupOrder());
|
||||||
|
}
|
||||||
|
|
||||||
void DolphinViewActionHandler::slotZoomLevelChanged(int current, int previous)
|
void DolphinViewActionHandler::slotZoomLevelChanged(int current, int previous)
|
||||||
{
|
{
|
||||||
Q_UNUSED(previous)
|
Q_UNUSED(previous)
|
||||||
|
@ -738,6 +840,32 @@ void DolphinViewActionHandler::slotSortTriggered(QAction *action)
|
||||||
m_currentView->setSortRole(role);
|
m_currentView->setSortRole(role);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DolphinViewActionHandler::slotGroupTriggered(QAction *action)
|
||||||
|
{
|
||||||
|
// The radiobuttons of the "Group By"-menu are split between the main-menu
|
||||||
|
// and several sub-menus. Because of this they don't have a common
|
||||||
|
// action-group that assures an exclusive toggle-state between the main-menu
|
||||||
|
// actions and the sub-menu-actions. If an action gets checked, it must
|
||||||
|
// be assured that all other actions get unchecked, except the ascending/
|
||||||
|
// descending actions
|
||||||
|
for (QAction *groupAction : std::as_const(m_groupByActions)) {
|
||||||
|
KActionMenu *actionMenu = qobject_cast<KActionMenu *>(groupAction);
|
||||||
|
if (actionMenu) {
|
||||||
|
const auto actions = actionMenu->menu()->actions();
|
||||||
|
for (QAction *subAction : actions) {
|
||||||
|
subAction->setChecked(false);
|
||||||
|
}
|
||||||
|
} else if (groupAction->actionGroup()) {
|
||||||
|
groupAction->setChecked(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
action->setChecked(true);
|
||||||
|
|
||||||
|
// Apply the activated sort-role to the view
|
||||||
|
const QByteArray role = action->data().toByteArray();
|
||||||
|
m_currentView->setGroupRole(role);
|
||||||
|
}
|
||||||
|
|
||||||
void DolphinViewActionHandler::slotAdjustViewProperties()
|
void DolphinViewActionHandler::slotAdjustViewProperties()
|
||||||
{
|
{
|
||||||
Q_EMIT actionBeingHandled();
|
Q_EMIT actionBeingHandled();
|
||||||
|
|
|
@ -158,6 +158,16 @@ private Q_SLOTS:
|
||||||
*/
|
*/
|
||||||
void slotSortRoleChanged(const QByteArray &role);
|
void slotSortRoleChanged(const QByteArray &role);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the state of the 'Group Ascending/Descending' action.
|
||||||
|
*/
|
||||||
|
void slotGroupOrderChanged(Qt::SortOrder order);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the state of the 'Group by' actions.
|
||||||
|
*/
|
||||||
|
void slotGroupRoleChanged(const QByteArray &role);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the state of the 'Zoom In' and 'Zoom Out' actions.
|
* Updates the state of the 'Zoom In' and 'Zoom Out' actions.
|
||||||
*/
|
*/
|
||||||
|
@ -179,6 +189,11 @@ private Q_SLOTS:
|
||||||
*/
|
*/
|
||||||
void slotVisibleRolesChanged(const QList<QByteArray> ¤t, const QList<QByteArray> &previous);
|
void slotVisibleRolesChanged(const QList<QByteArray> ¤t, const QList<QByteArray> &previous);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes the grouping of the current view.
|
||||||
|
*/
|
||||||
|
void slotGroupTriggered(QAction *);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Switches between sorting by groups or not.
|
* Switches between sorting by groups or not.
|
||||||
*/
|
*/
|
||||||
|
@ -274,6 +289,7 @@ private:
|
||||||
DolphinView *m_currentView;
|
DolphinView *m_currentView;
|
||||||
|
|
||||||
QHash<QByteArray, KToggleAction *> m_sortByActions;
|
QHash<QByteArray, KToggleAction *> m_sortByActions;
|
||||||
|
QHash<QByteArray, KToggleAction *> m_groupByActions;
|
||||||
QHash<QByteArray, KToggleAction *> m_visibleRoles;
|
QHash<QByteArray, KToggleAction *> m_visibleRoles;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -253,6 +253,32 @@ Qt::SortOrder ViewProperties::sortOrder() const
|
||||||
return static_cast<Qt::SortOrder>(m_node->sortOrder());
|
return static_cast<Qt::SortOrder>(m_node->sortOrder());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ViewProperties::setGroupRole(const QByteArray &role)
|
||||||
|
{
|
||||||
|
if (m_node->groupRole() != role) {
|
||||||
|
m_node->setGroupRole(role);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray ViewProperties::groupRole() const
|
||||||
|
{
|
||||||
|
return m_node->groupRole().toLatin1();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewProperties::setGroupOrder(Qt::SortOrder groupOrder)
|
||||||
|
{
|
||||||
|
if (m_node->groupOrder() != groupOrder) {
|
||||||
|
m_node->setGroupOrder(groupOrder);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::SortOrder ViewProperties::groupOrder() const
|
||||||
|
{
|
||||||
|
return static_cast<Qt::SortOrder>(m_node->groupOrder());
|
||||||
|
}
|
||||||
|
|
||||||
void ViewProperties::setSortFoldersFirst(bool foldersFirst)
|
void ViewProperties::setSortFoldersFirst(bool foldersFirst)
|
||||||
{
|
{
|
||||||
if (m_node->sortFoldersFirst() != foldersFirst) {
|
if (m_node->sortFoldersFirst() != foldersFirst) {
|
||||||
|
@ -384,6 +410,8 @@ void ViewProperties::setDirProperties(const ViewProperties &props)
|
||||||
setGroupedSorting(props.groupedSorting());
|
setGroupedSorting(props.groupedSorting());
|
||||||
setSortRole(props.sortRole());
|
setSortRole(props.sortRole());
|
||||||
setSortOrder(props.sortOrder());
|
setSortOrder(props.sortOrder());
|
||||||
|
setGroupRole(props.groupRole());
|
||||||
|
setGroupOrder(props.groupOrder());
|
||||||
setSortFoldersFirst(props.sortFoldersFirst());
|
setSortFoldersFirst(props.sortFoldersFirst());
|
||||||
setSortHiddenLast(props.sortHiddenLast());
|
setSortHiddenLast(props.sortHiddenLast());
|
||||||
setVisibleRoles(props.visibleRoles());
|
setVisibleRoles(props.visibleRoles());
|
||||||
|
|
|
@ -59,6 +59,12 @@ public:
|
||||||
void setSortOrder(Qt::SortOrder sortOrder);
|
void setSortOrder(Qt::SortOrder sortOrder);
|
||||||
Qt::SortOrder sortOrder() const;
|
Qt::SortOrder sortOrder() const;
|
||||||
|
|
||||||
|
void setGroupRole(const QByteArray &role);
|
||||||
|
QByteArray groupRole() const;
|
||||||
|
|
||||||
|
void setGroupOrder(Qt::SortOrder groupOrder);
|
||||||
|
Qt::SortOrder groupOrder() const;
|
||||||
|
|
||||||
void setSortFoldersFirst(bool foldersFirst);
|
void setSortFoldersFirst(bool foldersFirst);
|
||||||
bool sortFoldersFirst() const;
|
bool sortFoldersFirst() const;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user