]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/kitemviews/kfileitemlistwidget.cpp
Overhaul main view accessibility
[dolphin.git] / src / kitemviews / kfileitemlistwidget.cpp
index 40b8ccf3717a4a10965cf8c361c8be7e743fb57a..3a7b37895a70879c6f450baf98eed4f1f27695c2 100644 (file)
@@ -1,33 +1,25 @@
-/***************************************************************************
- *   Copyright (C) 2011 by Peter Penz <peter.penz19@gmail.com>             *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
- ***************************************************************************/
+/*
+ * SPDX-FileCopyrightText: 2011 Peter Penz <peter.penz19@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
 
 #include "kfileitemlistwidget.h"
+#include "kfileitemlistview.h"
 #include "kfileitemmodel.h"
 #include "kitemlistview.h"
 
+#include "dolphin_contentdisplaysettings.h"
+
 #include <KFormat>
 #include <KLocalizedString>
 
+#include <QGraphicsScene>
+#include <QGraphicsView>
 #include <QMimeDatabase>
 
-KFileItemListWidgetInformant::KFileItemListWidgetInformant() :
-    KStandardItemListWidgetInformant()
+KFileItemListWidgetInformant::KFileItemListWidgetInformant()
+    KStandardItemListWidgetInformant()
 {
 }
 
@@ -35,66 +27,102 @@ KFileItemListWidgetInformant::~KFileItemListWidgetInformant()
 {
 }
 
-QString KFileItemListWidgetInformant::itemText(int index, const KItemListViewview) const
+QString KFileItemListWidgetInformant::itemText(int index, const KItemListView *view) const
 {
-    Q_ASSERT(qobject_cast<KFileItemModel*>(view->model()));
-    KFileItemModel* fileItemModel = static_cast<KFileItemModel*>(view->model());
+    Q_ASSERT(qobject_cast<KFileItemModel *>(view->model()));
+    KFileItemModel *fileItemModel = static_cast<KFileItemModel *>(view->model());
 
     const KFileItem item = fileItemModel->fileItem(index);
     return item.text();
 }
 
-bool KFileItemListWidgetInformant::itemIsLink(int index, const KItemListViewview) const
+bool KFileItemListWidgetInformant::itemIsLink(int index, const KItemListView *view) const
 {
-    Q_ASSERT(qobject_cast<KFileItemModel*>(view->model()));
-    KFileItemModel* fileItemModel = static_cast<KFileItemModel*>(view->model());
+    Q_ASSERT(qobject_cast<KFileItemModel *>(view->model()));
+    KFileItemModel *fileItemModel = static_cast<KFileItemModel *>(view->model());
 
     const KFileItem item = fileItemModel->fileItem(index);
     return item.isLink();
 }
 
-QString KFileItemListWidgetInformant::roleText(const QByteArray& role,
-                                               const QHash<QByteArray, QVariant>& values) const
+QString KFileItemListWidgetInformant::roleText(const QByteArray &role, const QHash<QByteArray, QVariant> &values, ForUsageAs forUsageAs) const
 {
     QString text;
     const QVariant roleValue = values.value(role);
+    QLocale local;
+    KFormat formatter(local);
 
     // Implementation note: In case if more roles require a custom handling
     // use a hash + switch for a linear runtime.
 
+    auto formatDate = [formatter, local, forUsageAs](const QDateTime &time) {
+        if (ContentDisplaySettings::useShortRelativeDates()) {
+            return formatter.formatRelativeDateTime(time,
+                                                    forUsageAs == KStandardItemListWidgetInformant::ForUsageAs::DisplayedText ? QLocale::ShortFormat
+                                                                                                                              : QLocale::LongFormat);
+        } else {
+            return local.toString(time, forUsageAs == KStandardItemListWidgetInformant::ForUsageAs::DisplayedText ? QLocale::ShortFormat : QLocale::LongFormat);
+        }
+    };
+
     if (role == "size") {
         if (values.value("isDir").toBool()) {
-            // The item represents a directory. Show the number of sub directories
-            // instead of the file size of the directory.
-            if (!roleValue.isNull()) {
-                const int count = roleValue.toInt();
-                if (count < 0) {
-                    text = i18nc("@item:intable", "Unknown");
-                } else {
+            if (!roleValue.isNull() && roleValue != -1) {
+                // The item represents a directory.
+                if (ContentDisplaySettings::directorySizeMode() == ContentDisplaySettings::EnumDirectorySizeMode::ContentCount
+                    || roleValue == -2 /* size is invalid */) {
+                    //  Show the number of sub directories instead of the file size of the directory.
+                    const int count = values.value("count").toInt();
                     text = i18ncp("@item:intable", "%1 item", "%1 items", count);
+                } else {
+                    // if we have directory size available
+                    const KIO::filesize_t size = roleValue.value<KIO::filesize_t>();
+                    text = formatter.formatByteSize(size);
                 }
             }
         } else {
             const KIO::filesize_t size = roleValue.value<KIO::filesize_t>();
-            text = KFormat().formatByteSize(size);
+            text = formatter.formatByteSize(size);
         }
     } else if (role == "modificationtime" || role == "creationtime" || role == "accesstime") {
-            bool ok;
-            const long long time = roleValue.toLongLong(&ok);
-            if (ok && time != -1) {
-                return QLocale().toString(QDateTime::fromSecsSinceEpoch(time), QLocale::ShortFormat);
-            }
+        bool ok;
+        const long long time = roleValue.toLongLong(&ok);
+        if (ok && time != -1) {
+            const QDateTime dateTime = QDateTime::fromSecsSinceEpoch(time);
+            text = formatDate(dateTime);
+        }
     } else if (role == "deletiontime" || role == "imageDateTime") {
         const QDateTime dateTime = roleValue.toDateTime();
-        text = QLocale().toString(dateTime, QLocale::ShortFormat);
+        if (dateTime.isValid()) {
+            text = formatDate(dateTime);
+        }
+    } else if (role == "dimensions") {
+        const auto dimensions = roleValue.toSize();
+        if (dimensions.isValid()) {
+            text = i18nc("width × height", "%1 × %2", dimensions.width(), dimensions.height());
+        }
+    } else if (role == "permissions") {
+        const auto permissions = roleValue.value<QVariantList>();
+
+        switch (ContentDisplaySettings::usePermissionsFormat()) {
+        case ContentDisplaySettings::EnumUsePermissionsFormat::SymbolicFormat:
+            text = permissions.at(0).toString();
+            break;
+        case ContentDisplaySettings::EnumUsePermissionsFormat::NumericFormat:
+            text = QString::number(permissions.at(1).toInt(), 8);
+            break;
+        case ContentDisplaySettings::EnumUsePermissionsFormat::CombinedFormat:
+            text = QLatin1String("%1 (%2)").arg(permissions.at(0).toString()).arg(permissions.at(1).toInt(), 0, 8);
+            break;
+        }
     } else {
-        text = KStandardItemListWidgetInformant::roleText(role, values);
+        text = KStandardItemListWidgetInformant::roleText(role, values, forUsageAs);
     }
 
     return text;
 }
 
-QFont KFileItemListWidgetInformant::customizedFontForLinks(const QFontbaseFont) const
+QFont KFileItemListWidgetInformant::customizedFontForLinks(const QFont &baseFont) const
 {
     // The customized font should be italic if the file is a symbolic link.
     QFont font(baseFont);
@@ -102,9 +130,8 @@ QFont KFileItemListWidgetInformant::customizedFontForLinks(const QFont& baseFont
     return font;
 }
 
-
-KFileItemListWidget::KFileItemListWidget(KItemListWidgetInformant* informant, QGraphicsItem* parent) :
-    KStandardItemListWidget(informant, parent)
+KFileItemListWidget::KFileItemListWidget(KItemListWidgetInformant *informant, QGraphicsItem *parent)
+    : KStandardItemListWidget(informant, parent)
 {
 }
 
@@ -112,14 +139,14 @@ KFileItemListWidget::~KFileItemListWidget()
 {
 }
 
-KItemListWidgetInformantKFileItemListWidget::createInformant()
+KItemListWidgetInformant *KFileItemListWidget::createInformant()
 {
     return new KFileItemListWidgetInformant();
 }
 
-bool KFileItemListWidget::isRoleRightAligned(const QByteArrayrole) const
+bool KFileItemListWidget::isRoleRightAligned(const QByteArray &role) const
 {
-    return role == "size";
+    return role == "size" || role == "permissions";
 }
 
 bool KFileItemListWidget::isHidden() const
@@ -127,7 +154,7 @@ bool KFileItemListWidget::isHidden() const
     return data().value("isHidden").toBool();
 }
 
-QFont KFileItemListWidget::customizedFont(const QFontbaseFont) const
+QFont KFileItemListWidget::customizedFont(const QFont &baseFont) const
 {
     // The customized font should be italic if the file is a symbolic link.
     QFont font(baseFont);
@@ -135,34 +162,91 @@ QFont KFileItemListWidget::customizedFont(const QFont& baseFont) const
     return font;
 }
 
-int KFileItemListWidget::selectionLength(const QStringtext) const
+int KFileItemListWidget::selectionLength(const QString &text) const
 {
-    // Select the text without MIME-type extension
-    int selectionLength = text.length();
-
     // If item is a directory, use the whole text length for
     // selection (ignore all points)
-    if(data().value("isDir").toBool()) {
-        return selectionLength;
+    if (data().value("isDir").toBool()) {
+        return numberOfUnicodeCharactersIn(text);
     }
 
+    int indexOfExtension = text.length();
+
     QMimeDatabase db;
     const QString extension = db.suffixForFileName(text);
     if (extension.isEmpty()) {
         // For an unknown extension just exclude the extension after
         // the last point. This does not work for multiple extensions like
         // *.tar.gz but usually this is anyhow a known extension.
-        selectionLength = text.lastIndexOf(QLatin1Char('.'));
+        indexOfExtension = text.lastIndexOf(QLatin1Char('.'));
 
         // If no point could be found, use whole text length for selection.
-        if (selectionLength < 1) {
-            selectionLength = text.length();
+        if (indexOfExtension < 1) {
+            indexOfExtension = text.length();
         }
 
     } else {
-        selectionLength -= extension.length() + 1;
+        indexOfExtension -= extension.length() + 1;
+    }
+
+    return numberOfUnicodeCharactersIn(text.left(indexOfExtension));
+}
+
+void KFileItemListWidget::hoverSequenceStarted()
+{
+    KFileItemListView *view = listView();
+
+    if (!view) {
+        return;
+    }
+
+    const QUrl itemUrl = data().value("url").toUrl();
+
+    view->setHoverSequenceState(itemUrl, 0);
+}
+
+void KFileItemListWidget::forceUpdate()
+{
+    updateAdditionalInfoTextColor();
+    // icon layout does not include the icons in the item selection rectangle
+    // so its icon does not need updating
+    if (listView()->itemLayout() != KStandardItemListView::ItemLayout::IconsLayout) {
+        invalidateIconCache();
     }
+    update();
+}
+
+void KFileItemListWidget::hoverSequenceIndexChanged(int sequenceIndex)
+{
+    KFileItemListView *view = listView();
+
+    if (!view) {
+        return;
+    }
+
+    const QUrl itemUrl = data().value("url").toUrl();
 
-    return selectionLength;
+    view->setHoverSequenceState(itemUrl, sequenceIndex);
+
+    // Force-update the displayed icon
+    invalidateIconCache();
+    update();
+}
+
+void KFileItemListWidget::hoverSequenceEnded()
+{
+    KFileItemListView *view = listView();
+
+    if (!view) {
+        return;
+    }
+
+    view->setHoverSequenceState(QUrl(), 0);
+}
+
+KFileItemListView *KFileItemListWidget::listView()
+{
+    return dynamic_cast<KFileItemListView *>(parentItem());
 }
 
+#include "moc_kfileitemlistwidget.cpp"