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