]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/kitemviews/kfileitemmodel.cpp
Add case sensitive sorting mode
[dolphin.git] / src / kitemviews / kfileitemmodel.cpp
index 98249dbd982d39ee796bd3bb4e6554a58a8725b6..8626f947d949bbf5b2d54b6753706882231c6c25 100644 (file)
 
 #include "kfileitemmodel.h"
 
-#include <KGlobalSettings>
+#include "dolphin_generalsettings.h"
+
 #include <KLocalizedString>
-#include <KStringHandler>
-#include <KDebug>
+#include "dolphindebug.h"
 
 #include "private/kfileitemmodelsortalgorithm.h"
 #include "private/kfileitemmodeldirlister.h"
@@ -41,7 +41,6 @@
 KFileItemModel::KFileItemModel(QObject* parent) :
     KItemModelBase("text", parent),
     m_dirLister(0),
-    m_naturalSorting(KGlobalSettings::naturalSorting()),
     m_sortDirsFirst(true),
     m_sortRole(NameRole),
     m_sortingProgressPercent(-1),
@@ -58,9 +57,10 @@ KFileItemModel::KFileItemModel(QObject* parent) :
     m_expandedDirs(),
     m_urlsToExpand()
 {
-    m_collator.setCaseSensitivity(Qt::CaseInsensitive);
     m_collator.setNumericMode(true);
 
+    loadSortingSettings();
+
     m_dirLister = new KFileItemModelDirLister(this);
     m_dirLister->setDelayedMimeTypes(true);
 
@@ -106,8 +106,7 @@ KFileItemModel::KFileItemModel(QObject* parent) :
     m_resortAllItemsTimer->setSingleShot(true);
     connect(m_resortAllItemsTimer, &QTimer::timeout, this, &KFileItemModel::resortAllItems);
 
-    connect(KGlobalSettings::self(), &KGlobalSettings::naturalSortingChanged,
-            this, &KFileItemModel::slotNaturalSortingChanged);
+    connect(GeneralSettings::self(), &GeneralSettings::sortingChoiceChanged, this, &KFileItemModel::slotSortingChoiceChanged);
 }
 
 KFileItemModel::~KFileItemModel()
@@ -339,7 +338,7 @@ QList<QPair<int, QVariant> > KFileItemModel::groups() const
         }
 
 #ifdef KFILEITEMMODEL_DEBUG
-        kDebug() << "[TIME] Calculating groups for" << count() << "items:" << timer.elapsed();
+        qCDebug(DolphinDebug) << "[TIME] Calculating groups for" << count() << "items:" << timer.elapsed();
 #endif
     }
 
@@ -408,9 +407,9 @@ int KFileItemModel::index(const QUrl& url) const
         if (m_items.count() != m_itemData.count() && printDebugInfo) {
             printDebugInfo = false;
 
-            kWarning() << "The model is in an inconsistent state.";
-            kWarning() << "m_items.count()    ==" << m_items.count();
-            kWarning() << "m_itemData.count() ==" << m_itemData.count();
+            qCWarning(DolphinDebug) << "The model is in an inconsistent state.";
+            qCWarning(DolphinDebug) << "m_items.count()    ==" << m_items.count();
+            qCWarning(DolphinDebug) << "m_itemData.count() ==" << m_itemData.count();
 
             // Check if there are multiple items with the same URL.
             QMultiHash<QUrl, int> indexesForUrl;
@@ -420,12 +419,12 @@ int KFileItemModel::index(const QUrl& url) const
 
             foreach (const QUrl& url, indexesForUrl.uniqueKeys()) {
                 if (indexesForUrl.count(url) > 1) {
-                    kWarning() << "Multiple items found with the URL" << url;
+                    qCWarning(DolphinDebug) << "Multiple items found with the URL" << url;
                     foreach (int index, indexesForUrl.values(url)) {
                         const ItemData* data = m_itemData.at(index);
-                        kWarning() << "index" << index << ":" << data->item;
+                        qCWarning(DolphinDebug) << "index" << index << ":" << data->item;
                         if (data->parent) {
-                            kWarning() << "parent" << data->parent->item;
+                            qCWarning(DolphinDebug) << "parent" << data->parent->item;
                         }
                     }
                 }
@@ -783,6 +782,27 @@ void KFileItemModel::onSortOrderChanged(Qt::SortOrder current, Qt::SortOrder pre
     resortAllItems();
 }
 
+void KFileItemModel::loadSortingSettings()
+{
+    using Choice = GeneralSettings::EnumSortingChoice;
+    switch (GeneralSettings::sortingChoice()) {
+    case Choice::NaturalSorting:
+        m_naturalSorting = true;
+        m_collator.setCaseSensitivity(Qt::CaseInsensitive);
+        break;
+    case Choice::CaseSensitiveSorting:
+        m_naturalSorting = false;
+        m_collator.setCaseSensitivity(Qt::CaseSensitive);
+        break;
+    case Choice::CaseInsensitiveSorting:
+        m_naturalSorting = false;
+        m_collator.setCaseSensitivity(Qt::CaseInsensitive);
+        break;
+    default:
+        Q_UNREACHABLE();
+    }
+}
+
 void KFileItemModel::resortAllItems()
 {
     m_resortAllItemsTimer->stop();
@@ -795,8 +815,8 @@ void KFileItemModel::resortAllItems()
 #ifdef KFILEITEMMODEL_DEBUG
     QElapsedTimer timer;
     timer.start();
-    kDebug() << "===========================================================";
-    kDebug() << "Resorting" << itemCount << "items";
+    qCDebug(DolphinDebug) << "===========================================================";
+    qCDebug(DolphinDebug) << "Resorting" << itemCount << "items";
 #endif
 
     // Remember the order of the current URLs so
@@ -858,7 +878,7 @@ void KFileItemModel::resortAllItems()
     }
 
 #ifdef KFILEITEMMODEL_DEBUG
-    kDebug() << "[TIME] Resorting of" << itemCount << "items:" << timer.elapsed();
+    qCDebug(DolphinDebug) << "[TIME] Resorting of" << itemCount << "items:" << timer.elapsed();
 #endif
 }
 
@@ -1013,7 +1033,7 @@ void KFileItemModel::slotRefreshItems(const QList<QPair<KFileItem, KFileItem> >&
 {
     Q_ASSERT(!items.isEmpty());
 #ifdef KFILEITEMMODEL_DEBUG
-    kDebug() << "Refreshing" << items.count() << "items";
+    qCDebug(DolphinDebug) << "Refreshing" << items.count() << "items";
 #endif
 
     // Get the indexes of all items that have been refreshed
@@ -1079,7 +1099,7 @@ void KFileItemModel::slotRefreshItems(const QList<QPair<KFileItem, KFileItem> >&
 void KFileItemModel::slotClear()
 {
 #ifdef KFILEITEMMODEL_DEBUG
-    kDebug() << "Clearing all items";
+    qCDebug(DolphinDebug) << "Clearing all items";
 #endif
 
     qDeleteAll(m_filteredItems.values());
@@ -1103,9 +1123,9 @@ void KFileItemModel::slotClear()
     m_expandedDirs.clear();
 }
 
-void KFileItemModel::slotNaturalSortingChanged()
+void KFileItemModel::slotSortingChoiceChanged()
 {
-    m_naturalSorting = KGlobalSettings::naturalSorting();
+    loadSortingSettings();
     resortAllItems();
 }
 
@@ -1126,8 +1146,8 @@ void KFileItemModel::insertItems(QList<ItemData*>& newItems)
 #ifdef KFILEITEMMODEL_DEBUG
     QElapsedTimer timer;
     timer.start();
-    kDebug() << "===========================================================";
-    kDebug() << "Inserting" << newItems.count() << "items";
+    qCDebug(DolphinDebug) << "===========================================================";
+    qCDebug(DolphinDebug) << "Inserting" << newItems.count() << "items";
 #endif
 
     m_groups.clear();
@@ -1144,7 +1164,7 @@ void KFileItemModel::insertItems(QList<ItemData*>& newItems)
     sort(newItems.begin(), newItems.end());
 
 #ifdef KFILEITEMMODEL_DEBUG
-    kDebug() << "[TIME] Sorting:" << timer.elapsed();
+    qCDebug(DolphinDebug) << "[TIME] Sorting:" << timer.elapsed();
 #endif
 
     KItemRangeList itemRanges;
@@ -1208,7 +1228,7 @@ void KFileItemModel::insertItems(QList<ItemData*>& newItems)
     emit itemsInserted(itemRanges);
 
 #ifdef KFILEITEMMODEL_DEBUG
-    kDebug() << "[TIME] Inserting of" << newItems.count() << "items:" << timer.elapsed();
+    qCDebug(DolphinDebug) << "[TIME] Inserting of" << newItems.count() << "items:" << timer.elapsed();
 #endif
 }
 
@@ -1933,13 +1953,19 @@ QList<QPair<int, QVariant> > KFileItemModel::dateRoleGroups() const
         const int daysDistance = modifiedDate.daysTo(currentDate);
 
         QString newGroupValue;
-        if (currentDate.year() == modifiedDate.year() && currentDate.month() == modifiedDate.month()) {
+        if (currentDate.year() == modifiedDate.year() &&
+            currentDate.month() == modifiedDate.month()) {
+
             switch (daysDistance / 7) {
             case 0:
                 switch (daysDistance) {
                 case 0:  newGroupValue = i18nc("@title:group Date", "Today"); break;
                 case 1:  newGroupValue = i18nc("@title:group Date", "Yesterday"); break;
-                default: newGroupValue = modifiedTime.toString(i18nc("@title:group The week day name: %A", "%A"));
+                default:
+                    newGroupValue = modifiedTime.toString(
+                        i18nc("@title:group Date: The week day name: dddd", "dddd"));
+                    newGroupValue = i18nc("Can be used to script translation of \"dddd\""
+                        "with context @title:group Date", "%1", newGroupValue);
                 }
                 break;
             case 1:
@@ -1960,22 +1986,60 @@ QList<QPair<int, QVariant> > KFileItemModel::dateRoleGroups() const
             }
         } else {
             const QDate lastMonthDate = currentDate.addMonths(-1);
-            if  (lastMonthDate.year() == modifiedDate.year() && lastMonthDate.month() == modifiedDate.month()) {
+            if  (lastMonthDate.year() == modifiedDate.year() &&
+                 lastMonthDate.month() == modifiedDate.month()) {
+
                 if (daysDistance == 1) {
-                    newGroupValue = modifiedTime.toString(i18nc("@title:group Date: %B is full month name in current locale, and %Y is full year number", "Yesterday (%B, %Y)"));
+                    newGroupValue = modifiedTime.toString(i18nc("@title:group Date: "
+                        "MMMM is full month name in current locale, and yyyy is "
+                        "full year number", "'Yesterday' (MMMM, yyyy)"));
+                    newGroupValue = i18nc("Can be used to script translation of "
+                        "\"'Yesterday' (MMMM, yyyy)\" with context @title:group Date",
+                        "%1", newGroupValue);
                 } else if (daysDistance <= 7) {
-                    newGroupValue = modifiedTime.toString(i18nc("@title:group The week day name: %A, %B is full month name in current locale, and %Y is full year number", "%A (%B, %Y)"));
+                    newGroupValue = modifiedTime.toString(i18nc("@title:group Date: "
+                        "The week day name: dddd, MMMM is full month name "
+                        "in current locale, and yyyy is full year number",
+                        "dddd (MMMM, yyyy)"));
+                    newGroupValue = i18nc("Can be used to script translation of "
+                        "\"dddd (MMMM, yyyy)\" with context @title:group Date",
+                        "%1", newGroupValue);
                 } else if (daysDistance <= 7 * 2) {
-                    newGroupValue = modifiedTime.toString(i18nc("@title:group Date: %B is full month name in current locale, and %Y is full year number", "One Week Ago (%B, %Y)"));
+                    newGroupValue = modifiedTime.toString(i18nc("@title:group Date: "
+                        "MMMM is full month name in current locale, and yyyy is "
+                        "full year number", "'One Week Ago' (MMMM, yyyy)"));
+                    newGroupValue = i18nc("Can be used to script translation of "
+                        "\"'One Week Ago' (MMMM, yyyy)\" with context @title:group Date",
+                        "%1", newGroupValue);
                 } else if (daysDistance <= 7 * 3) {
-                    newGroupValue = modifiedTime.toString(i18nc("@title:group Date: %B is full month name in current locale, and %Y is full year number", "Two Weeks Ago (%B, %Y)"));
+                    newGroupValue = modifiedTime.toString(i18nc("@title:group Date: "
+                        "MMMM is full month name in current locale, and yyyy is "
+                        "full year number", "'Two Weeks Ago' (MMMM, yyyy)"));
+                    newGroupValue = i18nc("Can be used to script translation of "
+                        "\"'Two Weeks Ago' (MMMM, yyyy)\" with context @title:group Date",
+                        "%1", newGroupValue);
                 } else if (daysDistance <= 7 * 4) {
-                    newGroupValue = modifiedTime.toString(i18nc("@title:group Date: %B is full month name in current locale, and %Y is full year number", "Three Weeks Ago (%B, %Y)"));
+                    newGroupValue = modifiedTime.toString(i18nc("@title:group Date: "
+                        "MMMM is full month name in current locale, and yyyy is "
+                        "full year number", "'Three Weeks Ago' (MMMM, yyyy)"));
+                    newGroupValue = i18nc("Can be used to script translation of "
+                        "\"'Three Weeks Ago' (MMMM, yyyy)\" with context @title:group Date",
+                        "%1", newGroupValue);
                 } else {
-                    newGroupValue = modifiedTime.toString(i18nc("@title:group Date: %B is full month name in current locale, and %Y is full year number", "Earlier on %B, %Y"));
+                    newGroupValue = modifiedTime.toString(i18nc("@title:group Date: "
+                        "MMMM is full month name in current locale, and yyyy is "
+                        "full year number", "'Earlier on' MMMM, yyyy"));
+                    newGroupValue = i18nc("Can be used to script translation of "
+                        "\"'Earlier on' MMMM, yyyy\" with context @title:group Date",
+                        "%1", newGroupValue);
                 }
             } else {
-                newGroupValue = modifiedTime.toString(i18nc("@title:group The month and year: %B is full month name in current locale, and %Y is full year number", "%B, %Y"));
+                newGroupValue = modifiedTime.toString(i18nc("@title:group "
+                    "The month and year: MMMM is full month name in current locale, "
+                    "and yyyy is full year number", "MMMM, yyyy"));
+                newGroupValue = i18nc("Can be used to script translation of "
+                    "\"MMMM, yyyy\" with context @title:group Date",
+                    "%1", newGroupValue);
             }
         }
 
@@ -2156,7 +2220,7 @@ const KFileItemModel::RoleInfoMap* KFileItemModel::rolesInfoMap(int& count)
         { "track",       TrackRole,       I18N_NOOP2_NOSTRIP("@label", "Track"),            I18N_NOOP2_NOSTRIP("@label", "Audio"),    true,  true  },
         { "path",        PathRole,        I18N_NOOP2_NOSTRIP("@label", "Path"),             I18N_NOOP2_NOSTRIP("@label", "Other"),    false, false },
         { "destination", DestinationRole, I18N_NOOP2_NOSTRIP("@label", "Link Destination"), I18N_NOOP2_NOSTRIP("@label", "Other"),    false, false },
-        { "copiedFrom",  CopiedFromRole,  I18N_NOOP2_NOSTRIP("@label", "Copied From"),      I18N_NOOP2_NOSTRIP("@label", "Other"),    true,  false },
+        { "originUrl",   OriginUrlRole,   I18N_NOOP2_NOSTRIP("@label", "Downloaded From"),  I18N_NOOP2_NOSTRIP("@label", "Other"),    true,  false },
         { "permissions", PermissionsRole, I18N_NOOP2_NOSTRIP("@label", "Permissions"),      I18N_NOOP2_NOSTRIP("@label", "Other"),    false, false },
         { "owner",       OwnerRole,       I18N_NOOP2_NOSTRIP("@label", "Owner"),            I18N_NOOP2_NOSTRIP("@label", "Other"),    false, false },
         { "group",       GroupRole,       I18N_NOOP2_NOSTRIP("@label", "User Group"),       I18N_NOOP2_NOSTRIP("@label", "Other"),    false, false },
@@ -2213,19 +2277,19 @@ bool KFileItemModel::isConsistent() const
         // Check if m_items and m_itemData are consistent.
         const KFileItem item = fileItem(i);
         if (item.isNull()) {
-            qWarning() << "Item" << i << "is null";
+            qCWarning(DolphinDebug) << "Item" << i << "is null";
             return false;
         }
 
         const int itemIndex = index(item);
         if (itemIndex != i) {
-            qWarning() << "Item" << i << "has a wrong index:" << itemIndex;
+            qCWarning(DolphinDebug) << "Item" << i << "has a wrong index:" << itemIndex;
             return false;
         }
 
         // Check if the items are sorted correctly.
         if (i > 0 && !lessThan(m_itemData.at(i - 1), m_itemData.at(i), m_collator)) {
-            qWarning() << "The order of items" << i - 1 << "and" << i << "is wrong:"
+            qCWarning(DolphinDebug) << "The order of items" << i - 1 << "and" << i << "is wrong:"
                 << fileItem(i - 1) << fileItem(i);
             return false;
         }
@@ -2235,13 +2299,13 @@ bool KFileItemModel::isConsistent() const
         const ItemData* parent = data->parent;
         if (parent) {
             if (expandedParentsCount(data) != expandedParentsCount(parent) + 1) {
-                qWarning() << "expandedParentsCount is inconsistent for parent" << parent->item << "and child" << data->item;
+                qCWarning(DolphinDebug) << "expandedParentsCount is inconsistent for parent" << parent->item << "and child" << data->item;
                 return false;
             }
 
             const int parentIndex = index(parent->item);
             if (parentIndex >= i) {
-                qWarning() << "Index" << parentIndex << "of parent" << parent->item << "is not smaller than index" << i << "of child" << data->item;
+                qCWarning(DolphinDebug) << "Index" << parentIndex << "of parent" << parent->item << "is not smaller than index" << i << "of child" << data->item;
                 return false;
             }
         }