File indexing completed on 2024-05-12 16:43:59

0001 /*
0002     SPDX-FileCopyrightText: 2006-2018 Thomas Baumgart <tbaumgart@kde.org>
0003     SPDX-FileCopyrightText: 2017-2018 Łukasz Wojniłowicz <lukasz.wojnilowicz@gmail.com>
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "itemptrvector.h"
0008 
0009 // ----------------------------------------------------------------------------
0010 // QT Includes
0011 
0012 #include <QDate>
0013 
0014 // ----------------------------------------------------------------------------
0015 // KDE Includes
0016 
0017 // ----------------------------------------------------------------------------
0018 // Project Includes
0019 
0020 #include "register.h"
0021 #include "registeritem.h"
0022 #include "mymoneymoney.h"
0023 #include "widgetenums.h"
0024 
0025 using namespace eWidgets;
0026 using namespace KMyMoneyRegister;
0027 
0028 void ItemPtrVector::sort()
0029 {
0030     if (count() > 0) {
0031         // get rid of 0 pointers in the list
0032         KMyMoneyRegister::ItemPtrVector::iterator it_l;
0033         RegisterItem *item;
0034         for (it_l = begin(); it_l != end(); ++it_l) {
0035             if (*it_l == 0) {
0036                 item = last();
0037                 *it_l = item;
0038                 pop_back();
0039                 --it_l;
0040             }
0041         }
0042 
0043         std::sort(begin(), end(), item_cmp);
0044     }
0045 }
0046 
0047 bool ItemPtrVector::item_cmp(RegisterItem* i1, RegisterItem* i2)
0048 {
0049     const QList<SortField>& sortOrder = i1->getParent()->sortOrder();
0050     QList<SortField>::const_iterator it;
0051     auto rc = 0;
0052     bool ok1, ok2;
0053     qulonglong n1, n2;
0054 
0055     for (it = sortOrder.begin(); it != sortOrder.end(); ++it) {
0056         SortField sortField = static_cast<SortField>(*it);
0057         switch (qAbs(static_cast<int>(sortField))) {
0058         case (int)SortField::PostDate:
0059             rc = i2->sortPostDate().daysTo(i1->sortPostDate());
0060             break;
0061 
0062         case (int)SortField::EntryDate:
0063             rc = i2->sortEntryDate().daysTo(i1->sortEntryDate());
0064             break;
0065 
0066         case (int)SortField::Payee:
0067             rc = QString::localeAwareCompare(i1->sortPayee(), i2->sortPayee());
0068             break;
0069 
0070         case (int)SortField::Value:
0071             if (i1->sortValue() == i2->sortValue())
0072                 rc = 0;
0073             else if (i1->sortValue() < i2->sortValue())
0074                 rc = -1;
0075             else
0076                 rc = 1;
0077             break;
0078 
0079         case (int)SortField::NoSort:
0080             // convert both values to numbers
0081             n1 = i1->sortNumber().toULongLong(&ok1);
0082             n2 = i2->sortNumber().toULongLong(&ok2);
0083             // the following four cases exist:
0084             // a) both are converted correct
0085             //    compare them directly
0086             // b) n1 is numeric, n2 is not
0087             //    numbers come first, so return -1
0088             // c) n1 is not numeric, n2 is
0089             //    numbers come first, so return 1
0090             // d) both are non numbers
0091             //    compare using localeAwareCompare
0092             if (ok1 && ok2) { // case a)
0093                 rc = (n1 > n2) ? 1 : ((n1 == n2) ? 0 : -1);
0094             } else if (ok1 && !ok2) {
0095                 rc = -1;
0096             } else if (!ok1 && ok2) {
0097                 rc = 1;
0098             } else
0099                 rc = QString::localeAwareCompare(i1->sortNumber(), i2->sortNumber());
0100             break;
0101 
0102         case (int)SortField::EntryOrder:
0103             rc = qstrcmp(i1->sortEntryOrder().toLatin1(), i2->sortEntryOrder().toLatin1());
0104             break;
0105 
0106         case (int)SortField::Type:
0107             rc = (int)i1->sortType() - (int)i2->sortType();
0108             break;
0109 
0110         case (int)SortField::Category:
0111             rc = QString::localeAwareCompare(i1->sortCategory(), i2->sortCategory());
0112             break;
0113 
0114         case (int)SortField::ReconcileState:
0115             rc = static_cast<int>(i1->sortReconcileState()) - static_cast<int>(i2->sortReconcileState());
0116             break;
0117 
0118         case (int)SortField::Security:
0119             rc = QString::localeAwareCompare(i1->sortSecurity(), i2->sortSecurity());
0120             break;
0121 
0122         default:
0123             qDebug("Invalid sort key %d", (int)*it);
0124             break;
0125         }
0126 
0127         // take care of group markers, but only first sort item
0128         if ((rc == 0) && (it == sortOrder.begin())) {
0129             rc = i1->sortSamePostDate() - i2->sortSamePostDate();
0130             if (rc) {
0131                 return rc < 0;
0132             }
0133         }
0134 
0135         // the items differ for this sort key so we can return a result
0136         if (rc != 0) {
0137             return ((int)*it < 0) ? rc >= 0 : rc < 0;
0138         }
0139     }
0140 
0141     if (rc == 0) {
0142         rc = qstrcmp(i1->sortEntryOrder().toLatin1(), i2->sortEntryOrder().toLatin1());
0143     }
0144 
0145     return rc < 0;
0146 }