diff --git a/src/kitemviews/kfileitemlistwidget.cpp b/src/kitemviews/kfileitemlistwidget.cpp index 8002af5972..d9644bef5f 100644 --- a/src/kitemviews/kfileitemlistwidget.cpp +++ b/src/kitemviews/kfileitemlistwidget.cpp @@ -98,6 +98,20 @@ QString KFileItemListWidgetInformant::roleText(const QByteArray &role, const QHa if (dimensions.isValid()) { text = i18nc("width × height", "%1 × %2", dimensions.width(), dimensions.height()); } + } else if (role == "permissions") { + const auto permissions = roleValue.value(); + + switch (DetailsModeSettings::usePermissionsFormat()) { + case DetailsModeSettings::EnumUsePermissionsFormat::SymbolicFormat: + text = permissions.at(0).toString(); + break; + case DetailsModeSettings::EnumUsePermissionsFormat::NumericFormat: + text = QString::number(permissions.at(1).toInt(), 8); + break; + case DetailsModeSettings::EnumUsePermissionsFormat::CombinedFormat: + text = QString("%1 (%2)").arg(permissions.at(0).toString()).arg(permissions.at(1).toInt(), 0, 8); + break; + } } else { text = KStandardItemListWidgetInformant::roleText(role, values); } @@ -129,7 +143,7 @@ KItemListWidgetInformant *KFileItemListWidget::createInformant() bool KFileItemListWidget::isRoleRightAligned(const QByteArray &role) const { - return role == "size"; + return role == "size" || role == "permissions"; } bool KFileItemListWidget::isHidden() const diff --git a/src/kitemviews/kfileitemmodel.cpp b/src/kitemviews/kfileitemmodel.cpp index 14de9697ba..7cbca68b04 100644 --- a/src/kitemviews/kfileitemmodel.cpp +++ b/src/kitemviews/kfileitemmodel.cpp @@ -784,9 +784,8 @@ void KFileItemModel::applyFilters() // If this is a child of an expanded folder, we must make sure that its whole parental chain will also be shown. // We will go up through its parental chain until we either: - // 1 - reach the "root item" of the current view, i.e the currently opened folder on Dolphin. Their children have their ItemData::parent set to nullptr. - // or - // 2 - we reach an unfiltered parent or a previously discovered ancestor. + // 1 - reach the "root item" of the current view, i.e the currently opened folder on Dolphin. Their children have their ItemData::parent set to + // nullptr. or 2 - we reach an unfiltered parent or a previously discovered ancestor. for (ItemData *parent = it.value()->parent; parent && !ancestorsOfNewVisibleItems.contains(parent->item) && m_filteredItems.contains(parent->item); parent = parent->parent) { // We wish we could remove this parent from m_filteredItems right now, but we are iterating over it @@ -863,6 +862,11 @@ QList KFileItemModel::rolesInformation() } info.requiresBaloo = map[i].requiresBaloo; info.requiresIndexer = map[i].requiresIndexer; + if (!map[i].tooltipTranslation.isEmpty()) { + info.tooltip = map[i].tooltipTranslation.toString(); + } else { + info.tooltip = QString(); + } rolesInfo.append(info); } } @@ -1852,7 +1856,7 @@ QHash KFileItemModel::retrieveData(const KFileItem &item, } if (m_requestRole[PermissionsRole]) { - data.insert(sharedValue("permissions"), item.permissionsString()); + data.insert(sharedValue("permissions"), QVariantList() << item.permissionsString() << item.permissions()); } if (m_requestRole[OwnerRole]) { @@ -2671,46 +2675,48 @@ void KFileItemModel::emitSortProgress(int resolvedCount) const KFileItemModel::RoleInfoMap *KFileItemModel::rolesInfoMap(int &count) { static const RoleInfoMap rolesInfoMap[] = { - // | role | roleType | role translation | group translation | requires Baloo | requires indexer - { nullptr, NoRole, KLazyLocalizedString(), KLazyLocalizedString(), false, false }, - { "text", NameRole, kli18nc("@label", "Name"), KLazyLocalizedString(), false, false }, - { "size", SizeRole, kli18nc("@label", "Size"), KLazyLocalizedString(), false, false }, - { "modificationtime", ModificationTimeRole, kli18nc("@label", "Modified"), KLazyLocalizedString(), false, false }, - { "creationtime", CreationTimeRole, kli18nc("@label", "Created"), KLazyLocalizedString(), false, false }, - { "accesstime", AccessTimeRole, kli18nc("@label", "Accessed"), KLazyLocalizedString(), false, false }, - { "type", TypeRole, kli18nc("@label", "Type"), KLazyLocalizedString(), false, false }, - { "rating", RatingRole, kli18nc("@label", "Rating"), KLazyLocalizedString(), true, false }, - { "tags", TagsRole, kli18nc("@label", "Tags"), KLazyLocalizedString(), true, false }, - { "comment", CommentRole, kli18nc("@label", "Comment"), KLazyLocalizedString(), true, false }, - { "title", TitleRole, kli18nc("@label", "Title"), kli18nc("@label", "Document"), true, true }, - { "author", AuthorRole, kli18nc("@label", "Author"), kli18nc("@label", "Document"), true, true }, - { "publisher", PublisherRole, kli18nc("@label", "Publisher"), kli18nc("@label", "Document"), true, true }, - { "pageCount", PageCountRole, kli18nc("@label", "Page Count"), kli18nc("@label", "Document"), true, true }, - { "wordCount", WordCountRole, kli18nc("@label", "Word Count"), kli18nc("@label", "Document"), true, true }, - { "lineCount", LineCountRole, kli18nc("@label", "Line Count"), kli18nc("@label", "Document"), true, true }, - { "imageDateTime", ImageDateTimeRole, kli18nc("@label", "Date Photographed"), kli18nc("@label", "Image"), true, true }, - { "dimensions", DimensionsRole, kli18nc("@label width x height", "Dimensions"), kli18nc("@label", "Image"), true, true }, - { "width", WidthRole, kli18nc("@label", "Width"), kli18nc("@label", "Image"), true, true }, - { "height", HeightRole, kli18nc("@label", "Height"), kli18nc("@label", "Image"), true, true }, - { "orientation", OrientationRole, kli18nc("@label", "Orientation"), kli18nc("@label", "Image"), true, true }, - { "artist", ArtistRole, kli18nc("@label", "Artist"), kli18nc("@label", "Audio"), true, true }, - { "genre", GenreRole, kli18nc("@label", "Genre"), kli18nc("@label", "Audio"), true, true }, - { "album", AlbumRole, kli18nc("@label", "Album"), kli18nc("@label", "Audio"), true, true }, - { "duration", DurationRole, kli18nc("@label", "Duration"), kli18nc("@label", "Audio"), true, true }, - { "bitrate", BitrateRole, kli18nc("@label", "Bitrate"), kli18nc("@label", "Audio"), true, true }, - { "track", TrackRole, kli18nc("@label", "Track"), kli18nc("@label", "Audio"), true, true }, - { "releaseYear", ReleaseYearRole, kli18nc("@label", "Release Year"), kli18nc("@label", "Audio"), true, true }, - { "aspectRatio", AspectRatioRole, kli18nc("@label", "Aspect Ratio"), kli18nc("@label", "Video"), true, true }, - { "frameRate", FrameRateRole, kli18nc("@label", "Frame Rate"), kli18nc("@label", "Video"), true, true }, - { "path", PathRole, kli18nc("@label", "Path"), kli18nc("@label", "Other"), false, false }, - { "extension", ExtensionRole, kli18nc("@label", "File Extension"), kli18nc("@label", "Other"), false, false }, - { "deletiontime", DeletionTimeRole, kli18nc("@label", "Deletion Time"), kli18nc("@label", "Other"), false, false }, - { "destination", DestinationRole, kli18nc("@label", "Link Destination"), kli18nc("@label", "Other"), false, false }, - { "originUrl", OriginUrlRole, kli18nc("@label", "Downloaded From"), kli18nc("@label", "Other"), true, false }, - { "permissions", PermissionsRole, kli18nc("@label", "Permissions"), kli18nc("@label", "Other"), false, false }, - { "owner", OwnerRole, kli18nc("@label", "Owner"), kli18nc("@label", "Other"), false, false }, - { "group", GroupRole, kli18nc("@label", "User Group"), kli18nc("@label", "Other"), false, false }, + // clang-format off + // | role | roleType | role translation | group translation | requires Baloo | requires indexer + { nullptr, NoRole, KLazyLocalizedString(), KLazyLocalizedString(), KLazyLocalizedString(), false, false }, + { "text", NameRole, kli18nc("@label", "Name"), KLazyLocalizedString(), KLazyLocalizedString(), false, false }, + { "size", SizeRole, kli18nc("@label", "Size"), KLazyLocalizedString(), KLazyLocalizedString(), false, false }, + { "modificationtime", ModificationTimeRole, kli18nc("@label", "Modified"), KLazyLocalizedString(), kli18nc("@tooltip", "The date format can be selected in settings."), false, false }, + { "creationtime", CreationTimeRole, kli18nc("@label", "Created"), KLazyLocalizedString(), kli18nc("@tooltip", "The date format can be selected in settings."), false, false }, + { "accesstime", AccessTimeRole, kli18nc("@label", "Accessed"), KLazyLocalizedString(), kli18nc("@tooltip", "The date format can be selected in settings."), false, false }, + { "type", TypeRole, kli18nc("@label", "Type"), KLazyLocalizedString(), KLazyLocalizedString(), false, false }, + { "rating", RatingRole, kli18nc("@label", "Rating"), KLazyLocalizedString(), KLazyLocalizedString(), true, false }, + { "tags", TagsRole, kli18nc("@label", "Tags"), KLazyLocalizedString(), KLazyLocalizedString(), true, false }, + { "comment", CommentRole, kli18nc("@label", "Comment"), KLazyLocalizedString(), KLazyLocalizedString(), true, false }, + { "title", TitleRole, kli18nc("@label", "Title"), kli18nc("@label", "Document"), KLazyLocalizedString(), true, true }, + { "author", AuthorRole, kli18nc("@label", "Author"), kli18nc("@label", "Document"), KLazyLocalizedString(), true, true }, + { "publisher", PublisherRole, kli18nc("@label", "Publisher"), kli18nc("@label", "Document"), KLazyLocalizedString(), true, true }, + { "pageCount", PageCountRole, kli18nc("@label", "Page Count"), kli18nc("@label", "Document"), KLazyLocalizedString(), true, true }, + { "wordCount", WordCountRole, kli18nc("@label", "Word Count"), kli18nc("@label", "Document"), KLazyLocalizedString(), true, true }, + { "lineCount", LineCountRole, kli18nc("@label", "Line Count"), kli18nc("@label", "Document"), KLazyLocalizedString(), true, true }, + { "imageDateTime", ImageDateTimeRole, kli18nc("@label", "Date Photographed"), kli18nc("@label", "Image"), KLazyLocalizedString(), true, true }, + { "dimensions", DimensionsRole, kli18nc("@label width x height", "Dimensions"), kli18nc("@label", "Image"), KLazyLocalizedString(), true, true }, + { "width", WidthRole, kli18nc("@label", "Width"), kli18nc("@label", "Image"), KLazyLocalizedString(), true, true }, + { "height", HeightRole, kli18nc("@label", "Height"), kli18nc("@label", "Image"), KLazyLocalizedString(), true, true }, + { "orientation", OrientationRole, kli18nc("@label", "Orientation"), kli18nc("@label", "Image"), KLazyLocalizedString(), true, true }, + { "artist", ArtistRole, kli18nc("@label", "Artist"), kli18nc("@label", "Audio"), KLazyLocalizedString(), true, true }, + { "genre", GenreRole, kli18nc("@label", "Genre"), kli18nc("@label", "Audio"), KLazyLocalizedString(), true, true }, + { "album", AlbumRole, kli18nc("@label", "Album"), kli18nc("@label", "Audio"), KLazyLocalizedString(), true, true }, + { "duration", DurationRole, kli18nc("@label", "Duration"), kli18nc("@label", "Audio"), KLazyLocalizedString(), true, true }, + { "bitrate", BitrateRole, kli18nc("@label", "Bitrate"), kli18nc("@label", "Audio"), KLazyLocalizedString(), true, true }, + { "track", TrackRole, kli18nc("@label", "Track"), kli18nc("@label", "Audio"), KLazyLocalizedString(), true, true }, + { "releaseYear", ReleaseYearRole, kli18nc("@label", "Release Year"), kli18nc("@label", "Audio"), KLazyLocalizedString(), true, true }, + { "aspectRatio", AspectRatioRole, kli18nc("@label", "Aspect Ratio"), kli18nc("@label", "Video"), KLazyLocalizedString(), true, true }, + { "frameRate", FrameRateRole, kli18nc("@label", "Frame Rate"), kli18nc("@label", "Video"), KLazyLocalizedString(), true, true }, + { "path", PathRole, kli18nc("@label", "Path"), kli18nc("@label", "Other"), KLazyLocalizedString(), false, false }, + { "extension", ExtensionRole, kli18nc("@label", "File Extension"), kli18nc("@label", "Other"), KLazyLocalizedString(), false, false }, + { "deletiontime", DeletionTimeRole, kli18nc("@label", "Deletion Time"), kli18nc("@label", "Other"), KLazyLocalizedString(), false, false }, + { "destination", DestinationRole, kli18nc("@label", "Link Destination"), kli18nc("@label", "Other"), KLazyLocalizedString(), false, false }, + { "originUrl", OriginUrlRole, kli18nc("@label", "Downloaded From"), kli18nc("@label", "Other"), KLazyLocalizedString(), true, false }, + { "permissions", PermissionsRole, kli18nc("@label", "Permissions"), kli18nc("@label", "Other"), kli18nc("@tooltip", "The permission format can be changed in settings. Options are Textual, Numeric (Octal) or Combined formats"), false, false }, + { "owner", OwnerRole, kli18nc("@label", "Owner"), kli18nc("@label", "Other"), KLazyLocalizedString(), false, false }, + { "group", GroupRole, kli18nc("@label", "User Group"), kli18nc("@label", "Other"), KLazyLocalizedString(), false, false }, }; + // clang-format on count = sizeof(rolesInfoMap) / sizeof(RoleInfoMap); return rolesInfoMap; diff --git a/src/kitemviews/kfileitemmodel.h b/src/kitemviews/kfileitemmodel.h index 7c4b8ec8f6..afcd633b04 100644 --- a/src/kitemviews/kfileitemmodel.h +++ b/src/kitemviews/kfileitemmodel.h @@ -186,6 +186,7 @@ public: QByteArray role; QString translation; QString group; + QString tooltip; bool requiresBaloo; bool requiresIndexer; }; @@ -481,6 +482,7 @@ private: const RoleType roleType; const KLazyLocalizedString roleTranslation; const KLazyLocalizedString groupTranslation; + const KLazyLocalizedString tooltipTranslation; const bool requiresBaloo; const bool requiresIndexer; }; diff --git a/src/settings/dolphin_detailsmodesettings.kcfg b/src/settings/dolphin_detailsmodesettings.kcfg index aad59743c7..9efdebe711 100644 --- a/src/settings/dolphin_detailsmodesettings.kcfg +++ b/src/settings/dolphin_detailsmodesettings.kcfg @@ -51,5 +51,14 @@ true + + + + + + + + 0 + diff --git a/src/settings/viewmodes/viewsettingstab.cpp b/src/settings/viewmodes/viewsettingstab.cpp index bc465c02f7..1d4c5f5d59 100644 --- a/src/settings/viewmodes/viewsettingstab.cpp +++ b/src/settings/viewmodes/viewsettingstab.cpp @@ -38,6 +38,9 @@ ViewSettingsTab::ViewSettingsTab(Mode mode, QWidget *parent) , m_recursiveDirectorySizeLimit(nullptr) , m_useRelatetiveDates(nullptr) , m_useShortDates(nullptr) + , m_useSymbolicPermissions(nullptr) + , m_useNumericPermissions(nullptr) + , m_useCombinedPermissions(nullptr) { QFormLayout *topLayout = new QFormLayout(this); @@ -151,6 +154,20 @@ ViewSettingsTab::ViewSettingsTab(Mode mode, QWidget *parent) topLayout->addRow(i18nc("@title:group", "Date style:"), m_useRelatetiveDates); topLayout->addRow(QString(), m_useShortDates); + m_useSymbolicPermissions = new QRadioButton(i18nc("option:radio as symbolic style ", "Symbolic (e.g. 'drwxr-xr-x')")); + + m_useNumericPermissions = new QRadioButton(i18nc("option:radio as numeric style", "Numeric (Octal) (e.g. '755')")); + + m_useCombinedPermissions = new QRadioButton(i18nc("option:radio as combined style", "Combined (e.g. 'drwxr-xr-x (755)')")); + + topLayout->addRow(i18nc("@title:group", "Permissions style:"), m_useSymbolicPermissions); + topLayout->addRow(QString(), m_useNumericPermissions); + topLayout->addRow(QString(), m_useCombinedPermissions); + + QButtonGroup *permissionsFormatGroup = new QButtonGroup(this); + permissionsFormatGroup->addButton(m_useSymbolicPermissions); + permissionsFormatGroup->addButton(m_useNumericPermissions); + permissionsFormatGroup->addButton(m_useCombinedPermissions); break; } @@ -180,6 +197,9 @@ ViewSettingsTab::ViewSettingsTab(Mode mode, QWidget *parent) #endif connect(m_useRelatetiveDates, &QRadioButton::toggled, this, &ViewSettingsTab::changed); connect(m_useShortDates, &QRadioButton::toggled, this, &ViewSettingsTab::changed); + connect(m_useSymbolicPermissions, &QRadioButton::toggled, this, &ViewSettingsTab::changed); + connect(m_useNumericPermissions, &QRadioButton::toggled, this, &ViewSettingsTab::changed); + connect(m_useCombinedPermissions, &QRadioButton::toggled, this, &ViewSettingsTab::changed); break; default: break; @@ -226,6 +246,14 @@ void ViewSettingsTab::applySettings() DetailsModeSettings::setRecursiveDirectorySizeLimit(m_recursiveDirectorySizeLimit->value()); #endif DetailsModeSettings::setUseShortRelativeDates(m_useRelatetiveDates->isChecked()); + + if (m_useSymbolicPermissions->isChecked()) { + DetailsModeSettings::setUsePermissionsFormat(DetailsModeSettings::EnumUsePermissionsFormat::SymbolicFormat); + } else if (m_useNumericPermissions->isChecked()) { + DetailsModeSettings::setUsePermissionsFormat(DetailsModeSettings::EnumUsePermissionsFormat::NumericFormat); + } else if (m_useCombinedPermissions->isChecked()) { + DetailsModeSettings::setUsePermissionsFormat(DetailsModeSettings::EnumUsePermissionsFormat::CombinedFormat); + } break; default: break; @@ -278,6 +306,9 @@ void ViewSettingsTab::loadSettings() #endif m_useRelatetiveDates->setChecked(DetailsModeSettings::useShortRelativeDates()); m_useShortDates->setChecked(!DetailsModeSettings::useShortRelativeDates()); + m_useSymbolicPermissions->setChecked(DetailsModeSettings::usePermissionsFormat() == DetailsModeSettings::EnumUsePermissionsFormat::SymbolicFormat); + m_useNumericPermissions->setChecked(DetailsModeSettings::usePermissionsFormat() == DetailsModeSettings::EnumUsePermissionsFormat::NumericFormat); + m_useCombinedPermissions->setChecked(DetailsModeSettings::usePermissionsFormat() == DetailsModeSettings::EnumUsePermissionsFormat::CombinedFormat); break; default: break; diff --git a/src/settings/viewmodes/viewsettingstab.h b/src/settings/viewmodes/viewsettingstab.h index 88bdd944b9..b59fb399ee 100644 --- a/src/settings/viewmodes/viewsettingstab.h +++ b/src/settings/viewmodes/viewsettingstab.h @@ -60,6 +60,9 @@ private: QSpinBox *m_recursiveDirectorySizeLimit; QRadioButton *m_useRelatetiveDates; QRadioButton *m_useShortDates; + QRadioButton *m_useSymbolicPermissions; + QRadioButton *m_useNumericPermissions; + QRadioButton *m_useCombinedPermissions; }; #endif diff --git a/src/views/dolphinview.cpp b/src/views/dolphinview.cpp index 1f61bcbf2a..18d2137e36 100644 --- a/src/views/dolphinview.cpp +++ b/src/views/dolphinview.cpp @@ -1167,6 +1167,7 @@ void DolphinView::slotHeaderContextMenuRequested(const QPointF &pos) action->setCheckable(true); action->setChecked(visibleRolesSet.contains(info.role)); action->setData(info.role); + action->setToolTip(info.tooltip); const bool enable = (!info.requiresBaloo && !info.requiresIndexer) || (info.requiresBaloo) || (info.requiresIndexer && indexingEnabled); action->setEnabled(enable); @@ -1776,7 +1777,7 @@ void DolphinView::slotDeleteFileFinished(KJob *job) void DolphinView::selectNextItem() { if (m_active && m_selectNextItem) { - KItemListSelectionManager* selectionManager = m_container->controller()->selectionManager(); + KItemListSelectionManager *selectionManager = m_container->controller()->selectionManager(); if (selectedItems().isEmpty()) { Q_ASSERT_X(false, "DolphinView", "Selecting the next item failed."); return; @@ -1921,7 +1922,7 @@ void DolphinView::slotRoleEditingFinished(int index, const QByteArray &role, con newUrl.setPath(newUrl.path() + KIO::encodeFileName(newName)); #ifndef Q_OS_WIN - //Confirm hiding file/directory by renaming inline + // Confirm hiding file/directory by renaming inline if (!hiddenFilesShown() && newName.startsWith(QLatin1Char('.')) && !oldItem.name().startsWith(QLatin1Char('.'))) { KGuiItem yesGuiItem(i18nc("@action:button", "Rename and Hide"), QStringLiteral("view-hidden"));