File indexing completed on 2024-06-23 05:14:09
0001 /* -*- mode: c++; c-basic-offset:4 -*- 0002 newcertificatewizard/listwidget.cpp 0003 0004 This file is part of Kleopatra, the KDE keymanager 0005 SPDX-FileCopyrightText: 2008 Klarälvdalens Datakonsult AB 0006 0007 SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 0010 #include <config-kleopatra.h> 0011 0012 #include "listwidget.h" 0013 0014 #include "ui_listwidget.h" 0015 0016 #include <QIcon> 0017 0018 #include <QItemDelegate> 0019 #include <QLineEdit> 0020 #include <QRegularExpressionValidator> 0021 #include <QStringListModel> 0022 0023 using namespace Kleo::NewCertificateUi; 0024 0025 namespace 0026 { 0027 0028 class ItemDelegate : public QItemDelegate 0029 { 0030 Q_OBJECT 0031 public: 0032 explicit ItemDelegate(QObject *p = nullptr) 0033 : QItemDelegate(p) 0034 , m_rx() 0035 { 0036 } 0037 explicit ItemDelegate(const QRegularExpression &rx, QObject *p = nullptr) 0038 : QItemDelegate(p) 0039 , m_rx(rx) 0040 { 0041 } 0042 0043 void setRegExpFilter(const QRegularExpression &rx) 0044 { 0045 m_rx = rx; 0046 } 0047 const QRegularExpression ®ExpFilter() const 0048 { 0049 return m_rx; 0050 } 0051 0052 QWidget *createEditor(QWidget *p, const QStyleOptionViewItem &o, const QModelIndex &i) const override 0053 { 0054 QWidget *w = QItemDelegate::createEditor(p, o, i); 0055 if (m_rx.isValid()) 0056 if (auto const le = qobject_cast<QLineEdit *>(w)) { 0057 le->setValidator(new QRegularExpressionValidator(m_rx, le)); 0058 } 0059 return w; 0060 } 0061 0062 private: 0063 QRegularExpression m_rx; 0064 }; 0065 } 0066 0067 class ListWidget::Private 0068 { 0069 friend class ::Kleo::NewCertificateUi::ListWidget; 0070 ListWidget *const q; 0071 0072 public: 0073 explicit Private(ListWidget *qq) 0074 : q(qq) 0075 , stringListModel() 0076 , ui(q) 0077 { 0078 ui.listView->setModel(&stringListModel); 0079 ui.listView->setItemDelegate(&delegate); 0080 connect(ui.listView->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), q, SLOT(slotSelectionChanged())); 0081 connect(&stringListModel, &QAbstractItemModel::dataChanged, q, &ListWidget::itemsChanged); 0082 connect(&stringListModel, &QAbstractItemModel::rowsInserted, q, &ListWidget::itemsChanged); 0083 connect(&stringListModel, &QAbstractItemModel::rowsRemoved, q, &ListWidget::itemsChanged); 0084 } 0085 0086 private: 0087 void slotAdd() 0088 { 0089 const int idx = stringListModel.rowCount(); 0090 if (stringListModel.insertRows(idx, 1)) { 0091 stringListModel.setData(stringListModel.index(idx), defaultValue); 0092 editRow(idx); 0093 } 0094 } 0095 0096 void slotRemove() 0097 { 0098 const int idx = selectedRow(); 0099 stringListModel.removeRows(idx, 1); 0100 selectRow(idx); 0101 } 0102 0103 void slotUp() 0104 { 0105 const int idx = selectedRow(); 0106 swapRows(idx - 1, idx); 0107 selectRow(idx - 1); 0108 } 0109 0110 void slotDown() 0111 { 0112 const int idx = selectedRow(); 0113 swapRows(idx, idx + 1); 0114 selectRow(idx + 1); 0115 } 0116 0117 void slotSelectionChanged() 0118 { 0119 enableDisableActions(); 0120 } 0121 0122 private: 0123 void editRow(int idx) 0124 { 0125 const QModelIndex mi = stringListModel.index(idx); 0126 if (!mi.isValid()) { 0127 return; 0128 } 0129 ui.listView->setCurrentIndex(mi); 0130 ui.listView->edit(mi); 0131 } 0132 0133 QModelIndexList selectedIndexes() const 0134 { 0135 return ui.listView->selectionModel()->selectedRows(); 0136 } 0137 int selectedRow() const 0138 { 0139 const QModelIndexList mil = selectedIndexes(); 0140 return mil.empty() ? -1 : mil.front().row(); 0141 } 0142 void selectRow(int idx) 0143 { 0144 const QModelIndex mi = stringListModel.index(idx); 0145 if (mi.isValid()) { 0146 ui.listView->setCurrentIndex(mi); 0147 } 0148 } 0149 void swapRows(int r1, int r2) 0150 { 0151 if (r1 < 0 || r2 < 0 || r1 >= stringListModel.rowCount() || r2 >= stringListModel.rowCount()) { 0152 return; 0153 } 0154 const QModelIndex m1 = stringListModel.index(r1); 0155 const QModelIndex m2 = stringListModel.index(r2); 0156 const QVariant data1 = m1.data(); 0157 const QVariant data2 = m2.data(); 0158 stringListModel.setData(m1, data2); 0159 stringListModel.setData(m2, data1); 0160 } 0161 void enableDisableActions() 0162 { 0163 const QModelIndexList mil = selectedIndexes(); 0164 ui.removeTB->setEnabled(!mil.empty()); 0165 ui.upTB->setEnabled(mil.size() == 1 && mil.front().row() > 0); 0166 ui.downTB->setEnabled(mil.size() == 1 && mil.back().row() < stringListModel.rowCount() - 1); 0167 } 0168 0169 private: 0170 QStringListModel stringListModel; 0171 ItemDelegate delegate; 0172 QString defaultValue; 0173 struct UI : Ui_ListWidget { 0174 explicit UI(ListWidget *q) 0175 : Ui_ListWidget() 0176 { 0177 setupUi(q); 0178 0179 addTB->setIcon(QIcon::fromTheme(QStringLiteral("list-add"))); 0180 addTB->setAccessibleName(i18nc("@action:button", "Add Entry")); 0181 removeTB->setIcon(QIcon::fromTheme(QStringLiteral("list-remove"))); 0182 removeTB->setAccessibleName(i18nc("@action:button", "Remove Entry")); 0183 upTB->setIcon(QIcon::fromTheme(QStringLiteral("go-up"))); 0184 upTB->setAccessibleName(i18nc("@action:button", "Move Up")); 0185 downTB->setIcon(QIcon::fromTheme(QStringLiteral("go-down"))); 0186 downTB->setAccessibleName(i18nc("@action:button", "Move Down")); 0187 } 0188 } ui; 0189 }; 0190 0191 ListWidget::ListWidget(QWidget *p) 0192 : QWidget(p) 0193 , d(new Private(this)) 0194 { 0195 } 0196 0197 ListWidget::~ListWidget() 0198 { 0199 } 0200 0201 QStringList ListWidget::items() const 0202 { 0203 return d->stringListModel.stringList(); 0204 } 0205 0206 void ListWidget::setItems(const QStringList &items) 0207 { 0208 d->stringListModel.setStringList(items); 0209 } 0210 0211 QRegularExpression ListWidget::regExpFilter() const 0212 { 0213 return d->delegate.regExpFilter(); 0214 } 0215 0216 void ListWidget::setRegExpFilter(const QRegularExpression &rx) 0217 { 0218 d->delegate.setRegExpFilter(rx); 0219 } 0220 0221 QString ListWidget::defaultValue() const 0222 { 0223 return d->defaultValue; 0224 } 0225 0226 void ListWidget::setDefaultValue(const QString &df) 0227 { 0228 d->defaultValue = df; 0229 } 0230 0231 #include "listwidget.moc" 0232 #include "moc_listwidget.cpp"