1 /************************************************************************ 2 ** 3 ** Copyright (C) 2015-2019 Kevin B. Hendricks, Stratford Ontario Canada 4 ** Copyright (C) 2009-2011 Strahinja Markovic <strahinja.markovic@gmail.com> 5 ** 6 ** This file is part of Sigil. 7 ** 8 ** Sigil is free software: you can redistribute it and/or modify 9 ** it under the terms of the GNU General Public License as published by 10 ** the Free Software Foundation, either version 3 of the License, or 11 ** (at your option) any later version. 12 ** 13 ** Sigil is distributed in the hope that it will be useful, 14 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 15 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 ** GNU General Public License for more details. 17 ** 18 ** You should have received a copy of the GNU General Public License 19 ** along with Sigil. If not, see <http://www.gnu.org/licenses/>. 20 ** 21 *************************************************************************/ 22 23 #include "MainUI/OPFModelItem.h" 24 25 // Reimplementation of QStandardItem to support sorting alphanumerically AlphanumericItem()26AlphanumericItem::AlphanumericItem() : QStandardItem() 27 { 28 } 29 AlphanumericItem(const QIcon icon,const QString text)30AlphanumericItem::AlphanumericItem(const QIcon icon, const QString text) : QStandardItem(icon, text) 31 { 32 } 33 34 // Override standard sort operator to allow sorting alphanumerically case-sensitive operator <(const QStandardItem & item) const35bool AlphanumericItem::operator<(const QStandardItem &item) const 36 { 37 if (model()->sortRole() == READING_ORDER_ROLE) { 38 return data(READING_ORDER_ROLE).toInt() < item.data(READING_ORDER_ROLE).toInt(); 39 } else if (model()->sortRole() != ALPHANUMERIC_ORDER_ROLE) { 40 return text().compare(item.text()) < 0; 41 } 42 43 QString s1 = data(ALPHANUMERIC_ORDER_ROLE).toString(); 44 QString s2 = item.data(ALPHANUMERIC_ORDER_ROLE).toString(); 45 46 if (s1 == NULL || s2 == NULL) { 47 return false; 48 } 49 50 int len1 = s1.length(); 51 int len2 = s2.length(); 52 int marker1 = 0; 53 int marker2 = 0; 54 int result = 0; 55 56 // Loop through both strings with separate markers 57 while (marker1 < len1 && marker2 < len2) { 58 QChar ch1 = s1[marker1]; 59 QChar ch2 = s2[marker2]; 60 QString space1(s1); 61 QString space2(s2); 62 int loc1 = 0; 63 int loc2 = 0; 64 65 // Loop over first string at marker collecting consecutive digits (or non-digits) 66 do { 67 space1[loc1++] = ch1; 68 marker1++; 69 70 if (marker1 < len1) { 71 ch1 = s1[marker1]; 72 } else { 73 break; 74 } 75 } while (ch1.isDigit() == space1[0].isDigit()); 76 77 // Loop over second string at marker collecting consecutive digits (or non-digits) 78 do { 79 space2[loc2++] = ch2; 80 marker2++; 81 82 if (marker2 < len2) { 83 ch2 = s2[marker2]; 84 } else { 85 break; 86 } 87 } while (ch2.isDigit() == space2[0].isDigit()); 88 89 QString str1 = space1.left(loc1); 90 QString str2 = space2.left(loc2); 91 92 // If we collected numbers, compare them numerically 93 if (space1[0].isDigit() && space2[0].isDigit()) { 94 int n1 = str1.toInt(); 95 int n2 = str2.toInt(); 96 result = n1 - n2; 97 } else { 98 result = str1.compare(str2); 99 } 100 101 if (result != 0) { 102 return result < 0; 103 } 104 } 105 106 return len1 < len2; 107 } 108