File indexing completed on 2024-09-08 08:15:52
0001 /* 0002 SPDX-FileCopyrightText: 2008 Rolf Eike Beer <kde@opensource.sf-tec.de> 0003 0004 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 #include "keytreeview.h" 0007 0008 #include "model/keylistproxymodel.h" 0009 #include "model/kgpgitemmodel.h" 0010 #include "model/kgpgitemnode.h" 0011 #include "transactions/kgpgexport.h" 0012 #include "transactions/kgpgimport.h" 0013 0014 #include <KConfigGroup> 0015 #include <KLocalizedString> 0016 #include <KMessageBox> 0017 #include <KUrlMimeData> 0018 0019 #include <QDrag> 0020 #include <QDragMoveEvent> 0021 #include <QDropEvent> 0022 #include <QHeaderView> 0023 #include <QMimeData> 0024 0025 KeyTreeView::KeyTreeView(QWidget *parent, KeyListProxyModel *model) 0026 : QTreeView(parent), m_proxy(model) 0027 { 0028 setModel(model); 0029 setDragEnabled(true); 0030 setDragDropMode(DragDrop); 0031 setAcceptDrops(true); 0032 setEditTriggers(QTreeView::NoEditTriggers); 0033 } 0034 0035 std::vector<KGpgNode *> 0036 KeyTreeView::selectedNodes(bool *psame, KgpgCore::KgpgItemType *pt) const 0037 { 0038 QModelIndexList selidx = selectedIndexes(); 0039 std::vector<KGpgNode *> ndlist; 0040 KgpgItemType tp = {}; 0041 bool sametype = true; 0042 0043 if (selidx.isEmpty()) { 0044 if (pt != nullptr) 0045 *pt = tp; 0046 if (psame != nullptr) 0047 *psame = sametype; 0048 return ndlist; 0049 } 0050 0051 tp = m_proxy->nodeForIndex(selidx[0])->getType(); 0052 0053 for (int i = 0; i < selidx.count(); i++) { 0054 if (selidx[i].column() != 0) 0055 continue; 0056 KGpgNode *nd = m_proxy->nodeForIndex(selidx[i]); 0057 0058 if (nd->getType() != tp) { 0059 tp |= nd->getType(); 0060 sametype = false; 0061 } 0062 0063 ndlist.push_back(nd); 0064 } 0065 0066 if (pt != nullptr) 0067 *pt = tp; 0068 if (psame != nullptr) 0069 *psame = sametype; 0070 return ndlist; 0071 } 0072 0073 KGpgNode * 0074 KeyTreeView::selectedNode() const 0075 { 0076 QModelIndexList selidx = selectedIndexes(); 0077 0078 if (selidx.isEmpty()) 0079 return nullptr; 0080 0081 return m_proxy->nodeForIndex(selidx[0]); 0082 } 0083 0084 void 0085 KeyTreeView::selectNode(KGpgNode *nd) 0086 { 0087 if (nd == nullptr) 0088 return; 0089 0090 QModelIndex idx = m_proxy->nodeIndex(nd); 0091 0092 selectionModel()->select(idx, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); 0093 selectionModel()->setCurrentIndex(idx, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); 0094 } 0095 0096 void 0097 KeyTreeView::restoreLayout(KConfigGroup &cg) 0098 { 0099 QStringList cols(cg.readEntry("ColumnWidths", QStringList())); 0100 int i = 0; 0101 0102 QStringList::ConstIterator it(cols.constBegin()); 0103 const QStringList::ConstIterator itEnd(cols.constEnd()); 0104 for (; it != itEnd; ++it) 0105 setColumnWidth(i++, (*it).toInt()); 0106 0107 while (i < model()->columnCount(QModelIndex())) { 0108 int width = 100; 0109 switch (i) { 0110 case KEYCOLUMN_NAME: 0111 width = 250; 0112 break; 0113 case KEYCOLUMN_EMAIL: 0114 width = 150; 0115 break; 0116 case KEYCOLUMN_TRUST: 0117 // the trust column needs to be only that big as the header which is done automatically 0118 i++; 0119 continue; 0120 } 0121 setColumnWidth(i, width); 0122 i++; 0123 } 0124 0125 if (cg.hasKey("SortColumn")) { 0126 Qt::SortOrder order = cg.readEntry("SortAscending", true) ? Qt::AscendingOrder : Qt::DescendingOrder; 0127 sortByColumn(cg.readEntry("SortColumn", 0), order); 0128 } 0129 } 0130 0131 void 0132 KeyTreeView::saveLayout(KConfigGroup &cg) const 0133 { 0134 QStringList widths; 0135 0136 const int colCount = model()->columnCount(); 0137 0138 for (int i = 0; i < colCount; ++i) { 0139 widths << QString::number(columnWidth(i)); 0140 } 0141 cg.writeEntry("ColumnWidths", widths); 0142 cg.writeEntry( "SortColumn", header ()->sortIndicatorSection () ); 0143 cg.writeEntry( "SortAscending", ( header()->sortIndicatorOrder () == Qt::AscendingOrder ) ); 0144 } 0145 0146 void 0147 KeyTreeView::contentsDragMoveEvent(QDragMoveEvent *e) 0148 { 0149 e->setAccepted(e->mimeData()->hasUrls()); 0150 } 0151 0152 void 0153 KeyTreeView::contentsDropEvent(QDropEvent *o) 0154 { 0155 QList<QUrl> uriList = KUrlMimeData::urlsFromMimeData(o->mimeData()); 0156 if (!uriList.isEmpty()) { 0157 if (KMessageBox::questionTwoActions(this, i18n("<p>Do you want to import file <b>%1</b> into your key ring?</p>", 0158 uriList.first().path()), QString(), KGuiItem(i18n("Import")), 0159 KGuiItem(i18n("Do Not Import"))) != KMessageBox::PrimaryAction) 0160 return; 0161 0162 Q_EMIT importDrop(uriList); 0163 } 0164 } 0165 0166 void 0167 KeyTreeView::startDrag(Qt::DropActions supportedActions) 0168 { 0169 const auto nodes = selectedNodes(); 0170 0171 if (nodes.empty()) 0172 return; 0173 0174 const KGpgNode * const nd = nodes.front(); 0175 const QString keyid = nd->getId(); 0176 0177 if (!(nd->getType() & ITYPE_PUBLIC)) 0178 return; 0179 0180 KGpgExport *exp = new KGpgExport(this, QStringList(keyid)); 0181 exp->start(); 0182 0183 int result = exp->waitForFinished(); 0184 0185 if (result == KGpgTransaction::TS_OK) { 0186 QMimeData *m = new QMimeData(); 0187 m->setText(QString::fromLatin1( exp->getOutputData() )); 0188 QDrag *drag = new QDrag(this); 0189 drag->setMimeData(m); 0190 drag->exec(supportedActions, Qt::IgnoreAction); 0191 // do NOT delete drag. 0192 } 0193 0194 delete exp; 0195 } 0196 0197 void 0198 KeyTreeView::resizeColumnsToContents() 0199 { 0200 for (int i = m_proxy->columnCount() - 1; i >= 0; i--) 0201 resizeColumnToContents(i); 0202 } 0203 0204 void 0205 KeyTreeView::keyPressEvent(QKeyEvent *event) 0206 { 0207 if (event->key() == Qt::Key_Return) { 0208 if (!event->isAutoRepeat()) 0209 Q_EMIT returnPressed(); 0210 0211 return; 0212 } 0213 QTreeView::keyPressEvent(event); 0214 } 0215 0216 bool 0217 KeyTreeView::isEditing() const 0218 { 0219 return (state() == EditingState); 0220 }