QtPass 1.5.1
Multi-platform GUI for pass, the standard unix password manager.
Loading...
Searching...
No Matches
storemodel.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2016 Anne Jan Brouwer
2// SPDX-License-Identifier: GPL-3.0-or-later
3#include "storemodel.h"
4#include "qtpasssettings.h"
5
6#include "util.h"
7#include <QDebug>
8#include <QFileSystemModel>
9#include <QMessageBox>
10#include <QMimeData>
11#include <QRegularExpression>
12#include <utility>
13
23
31
37StoreModel::StoreModel() { fs = nullptr; }
38
47 const QModelIndex &sourceParent) const
48 -> bool {
49 QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
50 return ShowThis(index);
51}
52
59auto StoreModel::ShowThis(const QModelIndex index) const -> bool {
60 bool retVal = false;
61 if (fs == nullptr) {
62 return retVal;
63 }
64 // Gives you the info for number of childs with a parent
65 if (sourceModel()->rowCount(index) > 0) {
66 for (int nChild = 0; nChild < sourceModel()->rowCount(index); ++nChild) {
67 QModelIndex childIndex = sourceModel()->index(nChild, 0, index);
68 if (!childIndex.isValid()) {
69 break;
70 }
71 retVal = ShowThis(childIndex);
72 if (retVal) {
73 break;
74 }
75 }
76 } else {
77 QModelIndex useIndex = sourceModel()->index(index.row(), 0, index.parent());
78 QString path = fs->filePath(useIndex);
79 path = QDir(store).relativeFilePath(path);
80 path.replace(Util::endsWithGpg(), "");
81 retVal = path.contains(filterRegularExpression());
82 }
83 return retVal;
84}
85
91void StoreModel::setModelAndStore(QFileSystemModel *sourceModel,
92 QString passStore) {
93 setSourceModel(sourceModel);
94 fs = sourceModel;
95 store = std::move(passStore);
96}
97
104auto StoreModel::data(const QModelIndex &index, int role) const -> QVariant {
105 if (!index.isValid()) {
106 return {};
107 }
108
109 QVariant initial_value;
110 initial_value = QSortFilterProxyModel::data(index, role);
111
112 if (role == Qt::DisplayRole) {
113 QString name = initial_value.toString();
114 name.replace(Util::endsWithGpg(), "");
115 initial_value.setValue(name);
116 }
117
118 return initial_value;
119}
120
125auto StoreModel::supportedDropActions() const -> Qt::DropActions {
126 return Qt::CopyAction | Qt::MoveAction;
127}
128
133auto StoreModel::supportedDragActions() const -> Qt::DropActions {
134 return Qt::CopyAction | Qt::MoveAction;
135}
136
142auto StoreModel::flags(const QModelIndex &index) const -> Qt::ItemFlags {
143 Qt::ItemFlags defaultFlags = QSortFilterProxyModel::flags(index);
144
145 if (index.isValid()) {
146 return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | defaultFlags;
147 }
148 return Qt::ItemIsDropEnabled | defaultFlags;
149}
150
155auto StoreModel::mimeTypes() const -> QStringList {
156 QStringList types;
157 types << "application/vnd+qtpass.dragAndDropInfoPasswordStore";
158 return types;
159}
160
166auto StoreModel::mimeData(const QModelIndexList &indexes) const -> QMimeData * {
168
169 QByteArray encodedData;
170 // only use the first, otherwise we should enable multiselection
171 QModelIndex index = indexes.at(0);
172 if (index.isValid()) {
173 QModelIndex useIndex = mapToSource(index);
174
175 info.isDir = fs->fileInfo(useIndex).isDir();
176 info.isFile = fs->fileInfo(useIndex).isFile();
177 info.path = fs->fileInfo(useIndex).absoluteFilePath();
178 QDataStream stream(&encodedData, QIODevice::WriteOnly);
179 stream << info;
180 }
181
182 auto *mimeData = new QMimeData();
183 mimeData->setData("application/vnd+qtpass.dragAndDropInfoPasswordStore",
184 encodedData);
185 return mimeData;
186}
187
197auto StoreModel::canDropMimeData(const QMimeData *data, Qt::DropAction action,
198 int row, int column,
199 const QModelIndex &parent) const -> bool {
200#ifdef QT_DEBUG
201 qDebug() << action << row;
202#else
203 Q_UNUSED(action)
204 Q_UNUSED(row)
205#endif
206
207 QModelIndex useIndex =
208 this->index(parent.row(), parent.column(), parent.parent());
209 QByteArray encodedData =
210 data->data("application/vnd+qtpass.dragAndDropInfoPasswordStore");
211 QDataStream stream(&encodedData, QIODevice::ReadOnly);
213 stream >> info;
214 if (!data->hasFormat("application/vnd+qtpass.dragAndDropInfoPasswordStore")) {
215 return false;
216 }
217
218 if (column > 0) {
219 return false;
220 }
221
222 // you can drop a folder on a folder
223 if (fs->fileInfo(mapToSource(useIndex)).isDir() && info.isDir) {
224 return true;
225 }
226 // you can drop a file on a folder
227 if (fs->fileInfo(mapToSource(useIndex)).isDir() && info.isFile) {
228 return true;
229 }
230 // you can drop a file on a file
231 if (fs->fileInfo(mapToSource(useIndex)).isFile() && info.isFile) {
232 return true;
233 }
234
235 return false;
236}
237
247auto StoreModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
248 int row, int column, const QModelIndex &parent)
249 -> bool {
250 if (!canDropMimeData(data, action, row, column, parent)) {
251 return false;
252 }
253
254 if (action == Qt::IgnoreAction) {
255 return true;
256 }
257 QByteArray encodedData =
258 data->data("application/vnd+qtpass.dragAndDropInfoPasswordStore");
259
260 QDataStream stream(&encodedData, QIODevice::ReadOnly);
262 stream >> info;
263 QModelIndex destIndex =
264 this->index(parent.row(), parent.column(), parent.parent());
265 QFileInfo destFileinfo = fs->fileInfo(mapToSource(destIndex));
266 QFileInfo srcFileInfo = QFileInfo(info.path);
267 QString cleanedSrc = QDir::cleanPath(srcFileInfo.absoluteFilePath());
268 QString cleanedDest = QDir::cleanPath(destFileinfo.absoluteFilePath());
269 if (info.isDir) {
270 // dropped dir onto dir
271 if (destFileinfo.isDir()) {
272 QDir destDir = QDir(cleanedDest).filePath(srcFileInfo.fileName());
273 QString cleanedDestDir = QDir::cleanPath(destDir.absolutePath());
274 if (action == Qt::MoveAction) {
275 QtPassSettings::getPass()->Move(cleanedSrc, cleanedDestDir);
276 } else if (action == Qt::CopyAction) {
277 QtPassSettings::getPass()->Copy(cleanedSrc, cleanedDestDir);
278 }
279 }
280 } else if (info.isFile) {
281 // dropped file onto a directory
282 if (destFileinfo.isDir()) {
283 if (action == Qt::MoveAction) {
284 QtPassSettings::getPass()->Move(cleanedSrc, cleanedDest);
285 } else if (action == Qt::CopyAction) {
286 QtPassSettings::getPass()->Copy(cleanedSrc, cleanedDest);
287 }
288 } else if (destFileinfo.isFile()) {
289 // dropped file onto a file
290 int answer = QMessageBox::question(
291 nullptr, tr("force overwrite?"),
292 tr("overwrite %1 with %2?").arg(cleanedDest, cleanedSrc),
293 QMessageBox::Yes | QMessageBox::No);
294 bool force = answer == QMessageBox::Yes;
295 if (action == Qt::MoveAction) {
296 QtPassSettings::getPass()->Move(cleanedSrc, cleanedDest, force);
297 } else if (action == Qt::CopyAction) {
298 QtPassSettings::getPass()->Copy(cleanedSrc, cleanedDest, force);
299 }
300 }
301 }
302 return true;
303}
304
311auto StoreModel::lessThan(const QModelIndex &source_left,
312 const QModelIndex &source_right) const -> bool {
313/* matches logic in QFileSystemModelSorter::compareNodes() */
314#ifndef Q_OS_MAC
315 if (fs && (source_left.column() == 0 || source_left.column() == 1)) {
316 bool leftD = fs->isDir(source_left);
317 bool rightD = fs->isDir(source_right);
318
319 if (leftD ^ rightD) {
320 return leftD;
321 }
322 }
323#endif
324
325 return QSortFilterProxyModel::lessThan(source_left, source_right);
326}
static auto getPass() -> Pass *
auto data(const QModelIndex &index, int role) const -> QVariant override
StoreModel::data don't show the .gpg at the end of a file.
StoreModel()
StoreModel::StoreModel SubClass of QSortFilterProxyModel via http://www.qtcentre.org/threads/46471-QT...
auto mimeTypes() const -> QStringList override
StoreModel::mimeTypes.
auto filterAcceptsRow(int, const QModelIndex &) const -> bool override
StoreModel::filterAcceptsRow should row be shown, wrapper for StoreModel::ShowThis method.
auto dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) -> bool override
StoreModel::dropMimeData.
auto mimeData(const QModelIndexList &indexes) const -> QMimeData *override
StoreModel::mimeData.
auto supportedDragActions() const -> Qt::DropActions override
StoreModel::supportedDragActions enable drag.
auto flags(const QModelIndex &index) const -> Qt::ItemFlags override
StoreModel::flags.
auto canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const -> bool override
StoreModel::canDropMimeData.
auto lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const -> bool override
StoreModel::lessThan.
void setModelAndStore(QFileSystemModel *sourceModel, QString passStore)
StoreModel::setModelAndStore update the source model and store.
auto supportedDropActions() const -> Qt::DropActions override
StoreModel::supportedDropActions enable drop.
auto ShowThis(const QModelIndex) const -> bool
StoreModel::ShowThis should a row be shown, based on our search criteria.
static auto endsWithGpg() -> const QRegularExpression &
Definition util.cpp:203
auto operator>>(QDataStream &in, dragAndDropInfoPasswordStore &dragAndDropInfoPasswordStore) -> QDataStream &
auto operator<<(QDataStream &out, const dragAndDropInfoPasswordStore &dragAndDropInfoPasswordStore) -> QDataStream &