diff --git a/src/kitemviews/kfileitemmodel.h b/src/kitemviews/kfileitemmodel.h --- a/src/kitemviews/kfileitemmodel.h +++ b/src/kitemviews/kfileitemmodel.h @@ -93,6 +93,12 @@ void setSortDirectoriesFirst(bool dirsFirst); bool sortDirectoriesFirst() const; + /** + * Sets a separate sorting with hidden files and folders last (true) or not (false). + */ + void setSortHiddenLast(bool hiddenLast); + bool sortHiddenLast() const; + void setShowHiddenFiles(bool show); bool showHiddenFiles() const; @@ -470,6 +476,7 @@ QCollator m_collator; bool m_naturalSorting; bool m_sortDirsFirst; + bool m_sortHiddenLast; RoleType m_sortRole; int m_sortingProgressPercent; // Value of directorySortingProgress() signal diff --git a/src/kitemviews/kfileitemmodel.cpp b/src/kitemviews/kfileitemmodel.cpp --- a/src/kitemviews/kfileitemmodel.cpp +++ b/src/kitemviews/kfileitemmodel.cpp @@ -43,6 +43,7 @@ KItemModelBase("text", parent), m_dirLister(nullptr), m_sortDirsFirst(true), + m_sortHiddenLast(false), m_sortRole(NameRole), m_sortingProgressPercent(-1), m_roles(), @@ -216,6 +217,19 @@ return m_sortDirsFirst; } +void KFileItemModel::setSortHiddenLast(bool hiddenLast) +{ + if (hiddenLast != m_sortHiddenLast) { + m_sortHiddenLast = hiddenLast; + resortAllItems(); + } +} + +bool KFileItemModel::sortHiddenLast() const +{ + return m_sortHiddenLast; +} + void KFileItemModel::setShowHiddenFiles(bool show) { m_dirLister->setShowingDotFiles(show); @@ -1714,6 +1728,16 @@ } } + if (m_sortHiddenLast) { + const bool isHiddenA = a->item.isHidden(); + const bool isHiddenB = b->item.isHidden(); + if (isHiddenA && !isHiddenB) { + return false; + } else if (!isHiddenA && isHiddenB) { + return true; + } + } + if (m_sortDirsFirst || m_sortRole == SizeRole) { const bool isDirA = a->item.isDir(); const bool isDirB = b->item.isDir(); diff --git a/src/settings/dolphin_directoryviewpropertysettings.kcfg b/src/settings/dolphin_directoryviewpropertysettings.kcfg --- a/src/settings/dolphin_directoryviewpropertysettings.kcfg +++ b/src/settings/dolphin_directoryviewpropertysettings.kcfg @@ -57,6 +57,11 @@ true + + + false + + diff --git a/src/settings/viewpropertiesdialog.h b/src/settings/viewpropertiesdialog.h --- a/src/settings/viewpropertiesdialog.h +++ b/src/settings/viewpropertiesdialog.h @@ -59,6 +59,7 @@ void slotSortOrderChanged(int index); void slotGroupedSortingChanged(); void slotSortFoldersFirstChanged(); + void slotSortHiddenLastChanged(); void slotShowPreviewChanged(); void slotShowHiddenFilesChanged(); void slotItemChanged(QListWidgetItem *item); @@ -80,6 +81,7 @@ QComboBox* m_sortOrder; QComboBox* m_sorting; QCheckBox* m_sortFoldersFirst; + QCheckBox* m_sortHiddenLast; QCheckBox* m_previewsShown; QCheckBox* m_showInGroups; QCheckBox* m_showHiddenFiles; diff --git a/src/settings/viewpropertiesdialog.cpp b/src/settings/viewpropertiesdialog.cpp --- a/src/settings/viewpropertiesdialog.cpp +++ b/src/settings/viewpropertiesdialog.cpp @@ -57,6 +57,7 @@ m_sortOrder(nullptr), m_sorting(nullptr), m_sortFoldersFirst(nullptr), + m_sortHiddenLast(nullptr), m_previewsShown(nullptr), m_showInGroups(nullptr), m_showHiddenFiles(nullptr), @@ -96,6 +97,7 @@ } m_sortFoldersFirst = new QCheckBox(i18nc("@option:check", "Show folders first")); + m_sortHiddenLast = new QCheckBox(i18nc("@option:check", "Show hidden last")); m_previewsShown = new QCheckBox(i18nc("@option:check", "Show preview")); m_showInGroups = new QCheckBox(i18nc("@option:check", "Show in groups")); m_showHiddenFiles = new QCheckBox(i18nc("@option:check", "Show hidden files")); @@ -171,6 +173,8 @@ this, &ViewPropertiesDialog::slotSortOrderChanged); connect(m_sortFoldersFirst, &QCheckBox::clicked, this, &ViewPropertiesDialog::slotSortFoldersFirstChanged); + connect(m_sortHiddenLast, &QCheckBox::clicked, + this, &ViewPropertiesDialog::slotSortHiddenLastChanged); connect(m_previewsShown, &QCheckBox::clicked, this, &ViewPropertiesDialog::slotShowPreviewChanged); connect(m_showInGroups, &QCheckBox::clicked, @@ -298,6 +302,13 @@ markAsDirty(true); } +void ViewPropertiesDialog::slotSortHiddenLastChanged() +{ + const bool hiddenLast = m_sortHiddenLast->isChecked(); + m_viewProps->setSortHiddenLast(hiddenLast); + markAsDirty(true); +} + void ViewPropertiesDialog::slotShowPreviewChanged() { const bool show = m_previewsShown->isChecked(); @@ -399,6 +410,7 @@ m_dolphinView->setSortRole(m_viewProps->sortRole()); m_dolphinView->setSortOrder(m_viewProps->sortOrder()); m_dolphinView->setSortFoldersFirst(m_viewProps->sortFoldersFirst()); + m_dolphinView->setSortHiddenLast(m_viewProps->sortHiddenLast()); m_dolphinView->setGroupedSorting(m_viewProps->groupedSorting()); m_dolphinView->setVisibleRoles(m_viewProps->visibleRoles()); m_dolphinView->setPreviewsShown(m_viewProps->previewsShown()); diff --git a/src/views/dolphinview.h b/src/views/dolphinview.h --- a/src/views/dolphinview.h +++ b/src/views/dolphinview.h @@ -211,6 +211,10 @@ void setSortFoldersFirst(bool foldersFirst); bool sortFoldersFirst() const; + /** Sets a separate sorting with hidden files and folders last (true) or not (false). */ + void setSortHiddenLast(bool hiddenLast); + bool sortHiddenLast() const; + /** Sets the additional information which should be shown for the items. */ void setVisibleRoles(const QList& roles); @@ -453,6 +457,11 @@ */ void sortFoldersFirstChanged(bool foldersFirst); + /** + * Is emitted if the sorting of hidden files has been changed. + */ + void sortHiddenLastChanged(bool hiddenLast); + /** Is emitted if the additional information shown for this view has been changed. */ void visibleRolesChanged(const QList& current, const QList& previous); @@ -645,6 +654,12 @@ */ void updateSortFoldersFirst(bool foldersFirst); + /** + * Updates the view properties of the current URL to the + * sorting of hidden files given by \a hiddenLast. + */ + void updateSortHiddenLast(bool hiddenLast); + /** * Indicates in the status bar that the delete operation * of the job \a job has been finished. diff --git a/src/views/dolphinview.cpp b/src/views/dolphinview.cpp --- a/src/views/dolphinview.cpp +++ b/src/views/dolphinview.cpp @@ -435,6 +435,18 @@ return m_model->sortDirectoriesFirst(); } +void DolphinView::setSortHiddenLast(bool hiddenLast) +{ + if (sortHiddenLast() != hiddenLast) { + updateSortHiddenLast(hiddenLast); + } +} + +bool DolphinView::sortHiddenLast() const +{ + return m_model->sortHiddenLast(); +} + void DolphinView::setVisibleRoles(const QList& roles) { const QList previousRoles = roles; @@ -1255,6 +1267,16 @@ emit sortFoldersFirstChanged(foldersFirst); } +void DolphinView::updateSortHiddenLast(bool hiddenLast) +{ + ViewProperties props(viewPropertiesUrl()); + props.setSortHiddenLast(hiddenLast); + + m_model->setSortHiddenLast(hiddenLast); + + emit sortHiddenLastChanged(hiddenLast); +} + QPair DolphinView::pasteInfo() const { const QMimeData *mimeData = QApplication::clipboard()->mimeData(); @@ -1786,6 +1808,12 @@ emit sortFoldersFirstChanged(sortFoldersFirst); } + const bool sortHiddenLast = props.sortHiddenLast(); + if (sortHiddenLast != m_model->sortHiddenLast()) { + m_model->setSortHiddenLast(sortHiddenLast); + emit sortHiddenLastChanged(sortHiddenLast); + } + const QList visibleRoles = props.visibleRoles(); if (visibleRoles != m_visibleRoles) { const QList previousVisibleRoles = m_visibleRoles; diff --git a/src/views/dolphinviewactionhandler.h b/src/views/dolphinviewactionhandler.h --- a/src/views/dolphinviewactionhandler.h +++ b/src/views/dolphinviewactionhandler.h @@ -148,6 +148,14 @@ */ void slotSortFoldersFirstChanged(bool foldersFirst); + /** Switches between showing hidden files last or not. */ + void toggleSortHiddenLast(); + + /** + * Updates the state of the 'Sort Hidden Last' action. + */ + void slotSortHiddenLastChanged(bool hiddenLast); + /** * Updates the state of the 'Sort by' actions. */ diff --git a/src/views/dolphinviewactionhandler.cpp b/src/views/dolphinviewactionhandler.cpp --- a/src/views/dolphinviewactionhandler.cpp +++ b/src/views/dolphinviewactionhandler.cpp @@ -67,6 +67,8 @@ this, &DolphinViewActionHandler::slotSortOrderChanged); connect(view, &DolphinView::sortFoldersFirstChanged, this, &DolphinViewActionHandler::slotSortFoldersFirstChanged); + connect(view, &DolphinView::sortHiddenLastChanged, + this, &DolphinViewActionHandler::slotSortHiddenLastChanged); connect(view, &DolphinView::visibleRolesChanged, this, &DolphinViewActionHandler::slotVisibleRolesChanged); connect(view, &DolphinView::groupedSortingChanged, @@ -222,6 +224,10 @@ sortFoldersFirst->setText(i18nc("@action:inmenu Sort", "Folders First")); connect(sortFoldersFirst, &KToggleAction::triggered, this, &DolphinViewActionHandler::toggleSortFoldersFirst); + KToggleAction* sortHiddenLast = m_actionCollection->add(QStringLiteral("hidden_last")); + sortHiddenLast->setText(i18nc("@action:inmenu Sort", "Hidden Last")); + connect(sortHiddenLast, &KToggleAction::triggered, this, &DolphinViewActionHandler::toggleSortHiddenLast); + // View -> Sort By QActionGroup* sortByActionGroup = createFileItemRolesActionGroup(QStringLiteral("sort_by_")); @@ -255,6 +261,7 @@ sortByActionMenu->addAction(descendingAction); sortByActionMenu->addSeparator(); sortByActionMenu->addAction(sortFoldersFirst); + sortByActionMenu->addAction(sortHiddenLast); // View -> Additional Information QActionGroup* visibleRolesGroup = createFileItemRolesActionGroup(QStringLiteral("show_")); @@ -448,6 +455,7 @@ slotSortOrderChanged(m_currentView->sortOrder()); slotSortFoldersFirstChanged(m_currentView->sortFoldersFirst()); + slotSortHiddenLastChanged(m_currentView->sortHiddenLast()); slotVisibleRolesChanged(m_currentView->visibleRoles(), QList()); slotGroupedSortingChanged(m_currentView->groupedSorting()); slotSortRoleChanged(m_currentView->sortRole()); @@ -483,6 +491,12 @@ m_currentView->setSortFoldersFirst(!sortFirst); } +void DolphinViewActionHandler::toggleSortHiddenLast() +{ + const bool sortHiddenLast = m_currentView->sortHiddenLast(); + m_currentView->setSortHiddenLast(!sortHiddenLast); +} + void DolphinViewActionHandler::slotSortOrderChanged(Qt::SortOrder order) { QAction* descending = m_actionCollection->action(QStringLiteral("descending")); @@ -497,6 +511,11 @@ m_actionCollection->action(QStringLiteral("folders_first"))->setChecked(foldersFirst); } +void DolphinViewActionHandler::slotSortHiddenLastChanged(bool hiddenLast) +{ + m_actionCollection->action(QStringLiteral("hidden_last"))->setChecked(hiddenLast); +} + void DolphinViewActionHandler::toggleVisibleRole(QAction* action) { emit actionBeingHandled(); diff --git a/src/views/viewproperties.h b/src/views/viewproperties.h --- a/src/views/viewproperties.h +++ b/src/views/viewproperties.h @@ -75,6 +75,9 @@ void setSortFoldersFirst(bool foldersFirst); bool sortFoldersFirst() const; + void setSortHiddenLast(bool hiddenLast); + bool sortHiddenLast() const; + /** * Sets the additional information for the current set view-mode. * Note that the additional-info property is the only property where diff --git a/src/views/viewproperties.cpp b/src/views/viewproperties.cpp --- a/src/views/viewproperties.cpp +++ b/src/views/viewproperties.cpp @@ -258,6 +258,20 @@ return m_node->sortFoldersFirst(); } + +void ViewProperties::setSortHiddenLast(bool hiddenLast) +{ + if (m_node->sortHiddenLast() != hiddenLast) { + m_node->setSortHiddenLast(hiddenLast); + update(); + } +} + +bool ViewProperties::sortHiddenLast() const +{ + return m_node->sortHiddenLast(); +} + void ViewProperties::setVisibleRoles(const QList& roles) { if (roles == visibleRoles()) { @@ -366,6 +380,7 @@ setSortRole(props.sortRole()); setSortOrder(props.sortOrder()); setSortFoldersFirst(props.sortFoldersFirst()); + setSortHiddenLast(props.sortHiddenLast()); setVisibleRoles(props.visibleRoles()); setHeaderColumnWidths(props.headerColumnWidths()); m_node->setVersion(props.m_node->version());