File indexing completed on 2024-05-19 05:08:37
0001 /* 0002 SPDX-FileCopyrightText: 2009-2011 Laurent Montel <montel@kde.org> 0003 SPDX-FileCopyrightText: 2017 Łukasz Wojniłowicz <lukasz.wojnilowicz@gmail.com> 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "transactionsortoption.h" 0008 0009 // ---------------------------------------------------------------------------- 0010 // QT Includes 0011 0012 #include <QIcon> 0013 0014 // ---------------------------------------------------------------------------- 0015 // KDE Includes 0016 #include <KLazyLocalizedString> 0017 0018 // ---------------------------------------------------------------------------- 0019 // Project Includes 0020 0021 #include "icons/icons.h" 0022 #include "widgetenums.h" 0023 0024 #include "ui_transactionsortoption.h" 0025 0026 using namespace eWidgets; 0027 using namespace Icons; 0028 0029 /* 0030 * IMPORTANT: Keep this in sync with SortField enum in widgetenums.h 0031 * Don't touch the order of this list because it will break 0032 * the sorting in existing data files 0033 */ 0034 static constexpr KLazyLocalizedString sortOrderText[] = { 0035 kli18nc("Unknown sort order", "Unknown"), 0036 kli18n("Post date"), 0037 kli18n("Date entered"), 0038 kli18n("Payee"), 0039 kli18n("Amount"), 0040 kli18n("Number"), 0041 kli18n("Entry order"), 0042 kli18n("Type"), 0043 kli18n("Category"), 0044 kli18n("Reconcile state"), 0045 kli18n("Security"), 0046 kli18n("Reconciliation date"), 0047 // add new values above this comment line 0048 }; 0049 0050 TransactionSortOption::TransactionSortOption(QWidget* parent) 0051 : QWidget(parent) 0052 , ui(new Ui::TransactionSortOption) 0053 { 0054 ui->setupUi(this); 0055 0056 ui->m_addButton->setIcon(Icons::get(Icon::ArrowRight)); 0057 ui->m_removeButton->setIcon(Icons::get(Icon::ArrowLeft)); 0058 ui->m_upButton->setIcon(Icons::get(Icon::ArrowUp)); 0059 ui->m_downButton->setIcon(Icons::get(Icon::ArrowDown)); 0060 0061 // don't allow sorting of the selected entries 0062 ui->m_selectedList->setSortingEnabled(false); 0063 0064 connect(ui->m_addButton, &QPushButton::pressed, this, &TransactionSortOption::slotAddItem); 0065 connect(ui->m_removeButton, &QPushButton::pressed, this, &TransactionSortOption::slotRemoveItem); 0066 connect(ui->m_upButton, &QPushButton::pressed, this, &TransactionSortOption::slotUpItem); 0067 connect(ui->m_downButton, &QPushButton::pressed, this, &TransactionSortOption::slotDownItem); 0068 0069 connect(ui->m_availableList, &QListWidget::currentItemChanged, this, &TransactionSortOption::slotUpdateButtons); 0070 connect(ui->m_selectedList, &QListWidget::currentItemChanged, this, &TransactionSortOption::slotUpdateButtons); 0071 connect(ui->m_selectedList, &QListWidget::doubleClicked, this, &TransactionSortOption::slotToggleDirection); 0072 0073 setSettings(QString()); 0074 } 0075 0076 TransactionSortOption::~TransactionSortOption() 0077 { 0078 delete ui; 0079 } 0080 0081 /** 0082 * Setup the two lists according to the elements found in @a list. 0083 * If an item is negative, it will show up in the available list, 0084 * if positive, it shows up in the selected list. 0085 * 0086 * Special care is taken about the two values @a EntryDateSort and 0087 * @a EntryOrderSort. These two entries cannot (should not) exist 0088 * alone. Inside this widget, only the @a EntryOrderSort is used. 0089 * 0090 * setSettings() takes care of hiding the @a EntryDateSort item and if 0091 * it exists in @p settings without @a EntryOrderSort being present, it 0092 * will add @a EntryOrderSort. 0093 */ 0094 void TransactionSortOption::setSettings(const QString& settings) 0095 { 0096 ui->m_availableList->clear(); 0097 ui->m_availableList->setCurrentItem(0); 0098 ui->m_selectedList->clear(); 0099 ui->m_selectedList->setCurrentItem(0); 0100 0101 QStringList list = settings.split(',', Qt::SkipEmptyParts); 0102 QMap<int, bool> selectedMap; 0103 0104 // fill selected list 0105 QStringList::const_iterator it_s; 0106 QListWidgetItem* last = 0; 0107 for (it_s = list.constBegin(); it_s != list.constEnd(); ++it_s) { 0108 int val = (*it_s).toInt(); 0109 selectedMap[abs(val)] = true; 0110 last = addEntry(ui->m_selectedList, last, val); 0111 } 0112 0113 // fill available list 0114 for (int i = static_cast<int>(SortField::PostDate); i < static_cast<int>(SortField::MaxFields); ++i) { 0115 // Only add those, that are not present in the list of selected items 0116 if (selectedMap.find(i) == selectedMap.end()) { 0117 int val = i; 0118 if (i == static_cast<int>(SortField::Value)) 0119 val = -val; 0120 addEntry(ui->m_availableList, 0, val); 0121 } 0122 } 0123 0124 // update the current item on the lists 0125 QListWidgetItem* p; 0126 if ((p = ui->m_availableList->item(0)) != 0) { 0127 ui->m_availableList->setCurrentItem(p); 0128 } 0129 if ((p = ui->m_selectedList->item(0)) != 0) { 0130 ui->m_selectedList->setCurrentItem(p); 0131 } 0132 0133 slotUpdateButtons(); 0134 } 0135 0136 QListWidgetItem* TransactionSortOption::addEntry(QListWidget* p, QListWidgetItem* after, int idx) 0137 { 0138 auto txt = sortOrderToText(static_cast<SortField>(abs(idx))); 0139 if (txt.isEmpty()) 0140 txt = "Unknown"; // i18n should be handled in sortOptionToText() 0141 0142 int row = p->row(after) + 1; 0143 p->insertItem(row, txt); 0144 auto item = p->item(row); 0145 int direction = (idx >= 0) ? 1 : -1; 0146 item->setData(Qt::UserRole, QVariant(direction)); 0147 setDirectionIcon(item); 0148 return item; 0149 } 0150 0151 void TransactionSortOption::slotToggleDirection() 0152 { 0153 const auto item = ui->m_selectedList->currentItem(); 0154 if (item) { 0155 int direction = item->data(Qt::UserRole).toInt() * (-1); 0156 item->setData(Qt::UserRole, QVariant(direction)); 0157 setDirectionIcon(item); 0158 Q_EMIT settingsChanged(settings()); 0159 } 0160 } 0161 0162 void TransactionSortOption::setDirectionIcon(QListWidgetItem* item) 0163 { 0164 if (item->data(Qt::UserRole).toInt() > 0) { 0165 item->setIcon(Icons::get(Icon::SortAscending)); 0166 } else { 0167 item->setIcon(Icons::get(Icon::SortDescending)); 0168 } 0169 } 0170 0171 QString TransactionSortOption::settings() const 0172 { 0173 QString rc; 0174 auto item = dynamic_cast<QListWidgetItem*>(ui->m_selectedList->item(0)); 0175 while (item) { 0176 rc += QString::number(static_cast<int>(textToSortOrder(item->text())) * item->data(Qt::UserRole).toInt()); 0177 item = ui->m_selectedList->item(ui->m_selectedList->row(item) + 1); 0178 if (item != 0) 0179 rc += ','; 0180 } 0181 return rc; 0182 } 0183 0184 void TransactionSortOption::slotUpdateButtons() 0185 { 0186 auto availableItem = ui->m_availableList->currentItem(); 0187 auto selectedItem = ui->m_selectedList->currentItem(); 0188 ui->m_addButton->setEnabled(availableItem != 0); 0189 ui->m_removeButton->setEnabled(selectedItem != 0); 0190 if (selectedItem) { 0191 ui->m_upButton->setEnabled(ui->m_selectedList->row(selectedItem) != 0); 0192 ui->m_downButton->setEnabled(ui->m_selectedList->row(selectedItem) < ui->m_selectedList->count() - 1); 0193 } else { 0194 ui->m_upButton->setEnabled(false); 0195 ui->m_downButton->setEnabled(false); 0196 } 0197 } 0198 0199 void TransactionSortOption::slotAddItem() 0200 { 0201 QListWidgetItem* item; 0202 if ((item = ui->m_availableList->currentItem()) != 0) { 0203 auto next = ui->m_availableList->item(ui->m_availableList->row(item) + 1); 0204 if (!next) 0205 next = ui->m_availableList->item(ui->m_availableList->row(item) + 1); 0206 ui->m_availableList->takeItem(ui->m_availableList->row(item)); 0207 ui->m_selectedList->addItem(item); 0208 ui->m_addButton->setEnabled((ui->m_availableList->count() > 0)); 0209 if (next) { 0210 ui->m_availableList->setCurrentItem(next); 0211 } 0212 Q_EMIT settingsChanged(settings()); 0213 } 0214 } 0215 0216 void TransactionSortOption::slotRemoveItem() 0217 { 0218 QListWidgetItem* item; 0219 if ((item = ui->m_selectedList->currentItem()) != 0) { 0220 auto next = ui->m_selectedList->item(ui->m_selectedList->row(item) + 1); 0221 if (!next) 0222 next = ui->m_selectedList->item(ui->m_selectedList->row(item) + 1); 0223 ui->m_selectedList->takeItem(ui->m_selectedList->row(item)); 0224 ui->m_availableList->addItem(item); 0225 ui->m_removeButton->setEnabled(ui->m_selectedList->count() > 0); 0226 if (next) { 0227 ui->m_selectedList->setCurrentItem(next); 0228 } 0229 Q_EMIT settingsChanged(settings()); 0230 } 0231 } 0232 0233 void TransactionSortOption::slotUpItem() 0234 { 0235 auto item = ui->m_selectedList->currentItem(); 0236 auto prev = ui->m_selectedList->item(ui->m_selectedList->row(item) - 1); 0237 int prevRow = ui->m_selectedList->row(prev); 0238 if (prev) { 0239 ui->m_selectedList->takeItem(ui->m_selectedList->row(item)); 0240 ui->m_selectedList->insertItem(prevRow, item); 0241 ui->m_selectedList->setCurrentRow(ui->m_selectedList->row(item)); 0242 ui->m_upButton->setEnabled(ui->m_selectedList->row(item) > 0); 0243 ui->m_downButton->setEnabled(ui->m_selectedList->row(item) < ui->m_selectedList->count() - 1); 0244 Q_EMIT settingsChanged(settings()); 0245 } 0246 } 0247 0248 void TransactionSortOption::slotDownItem() 0249 { 0250 auto item = ui->m_selectedList->currentItem(); 0251 auto next = ui->m_selectedList->item(ui->m_selectedList->row(item) + 1); 0252 int nextRow = ui->m_selectedList->row(next); 0253 if (next) { 0254 ui->m_selectedList->takeItem(ui->m_selectedList->row(item)); 0255 ui->m_selectedList->insertItem(nextRow, item); 0256 ui->m_selectedList->setCurrentRow(ui->m_selectedList->row(item)); 0257 ui->m_upButton->setEnabled(ui->m_selectedList->row(item) > 0); 0258 ui->m_downButton->setEnabled(ui->m_selectedList->row(item) < ui->m_selectedList->count() - 1); 0259 Q_EMIT settingsChanged(settings()); 0260 } 0261 } 0262 0263 SortField TransactionSortOption::textToSortOrder(const QString& text) 0264 { 0265 for (auto idx = 1; idx < static_cast<int>(SortField::MaxFields); ++idx) { 0266 if (text == sortOrderText[idx].toString()) { 0267 return static_cast<SortField>(idx); 0268 } 0269 } 0270 return SortField::Unknown; 0271 } 0272 0273 QString TransactionSortOption::sortOrderToText(SortField idx) 0274 { 0275 if ((int)idx < (int)SortField::PostDate || (int)idx >= (int)SortField::MaxFields) 0276 idx = SortField::Unknown; 0277 return sortOrderText[(int)idx].toString(); 0278 }