QtPass 1.4.0
Multi-platform GUI for pass, the standard unix password manager.
Loading...
Searching...
No Matches
storemodel.cpp
Go to the documentation of this file.
1#include "storemodel.h"
2#include "qtpasssettings.h"
3
4#include "util.h"
5#include <QDebug>
6#include <QFileSystemModel>
7#include <QMessageBox>
8#include <QMimeData>
9#include <QRegularExpression>
10#include <utility>
11
12QDataStream &
13operator<<(QDataStream &out,
18 return out;
19}
20
21QDataStream &
22operator>>(QDataStream &in,
26 return in;
27}
28
34StoreModel::StoreModel() { fs = nullptr; }
35
44 const QModelIndex &sourceParent) const {
45 QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
46 return ShowThis(index);
47}
48
55bool StoreModel::ShowThis(const QModelIndex index) const {
56 bool retVal = false;
57 if (fs == nullptr)
58 return retVal;
59 // Gives you the info for number of childs with a parent
60 if (sourceModel()->rowCount(index) > 0) {
61 for (int nChild = 0; nChild < sourceModel()->rowCount(index); ++nChild) {
62 QModelIndex childIndex = sourceModel()->index(nChild, 0, index);
63 if (!childIndex.isValid())
64 break;
65 retVal = ShowThis(childIndex);
66 if (retVal)
67 break;
68 }
69 } else {
70 QModelIndex useIndex = sourceModel()->index(index.row(), 0, index.parent());
71 QString path = fs->filePath(useIndex);
72 path = QDir(store).relativeFilePath(path);
73 path.replace(Util::endsWithGpg(), "");
74 retVal = path.contains(filterRegularExpression());
75 }
76 return retVal;
77}
78
84void StoreModel::setModelAndStore(QFileSystemModel *sourceModel,
85 QString passStore) {
86 setSourceModel(sourceModel);
87 fs = sourceModel;
88 store = std::move(passStore);
89}
90
97QVariant StoreModel::data(const QModelIndex &index, int role) const {
98 if (!index.isValid())
99 return QVariant();
100
101 QVariant initial_value;
102 initial_value = QSortFilterProxyModel::data(index, role);
103
104 if (role == Qt::DisplayRole) {
105 QString name = initial_value.toString();
106 name.replace(Util::endsWithGpg(), "");
107 initial_value.setValue(name);
108 }
109
110 return initial_value;
111}
112
117Qt::DropActions StoreModel::supportedDropActions() const {
118 return Qt::CopyAction | Qt::MoveAction;
119}
120
125Qt::DropActions StoreModel::supportedDragActions() const {
126 return Qt::CopyAction | Qt::MoveAction;
127}
128
134Qt::ItemFlags StoreModel::flags(const QModelIndex &index) const {
135 Qt::ItemFlags defaultFlags = QSortFilterProxyModel::flags(index);
136
137 if (index.isValid()) {
138 return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | defaultFlags;
139 }
140 return Qt::ItemIsDropEnabled | defaultFlags;
141}
142
147QStringList StoreModel::mimeTypes() const {
148 QStringList types;
149 types << "application/vnd+qtpass.dragAndDropInfoPasswordStore";
150 return types;
151}
152
158QMimeData *StoreModel::mimeData(const QModelIndexList &indexes) const {
160
161 QByteArray encodedData;
162 // only use the first, otherwise we should enable multiselection
163 QModelIndex index = indexes.at(0);
164 if (index.isValid()) {
165 QModelIndex useIndex = mapToSource(index);
166
167 info.isDir = fs->fileInfo(useIndex).isDir();
168 info.isFile = fs->fileInfo(useIndex).isFile();
169 info.path = fs->fileInfo(useIndex).absoluteFilePath();
170 QDataStream stream(&encodedData, QIODevice::WriteOnly);
171 stream << info;
172 }
173
174 auto *mimeData = new QMimeData();
175 mimeData->setData("application/vnd+qtpass.dragAndDropInfoPasswordStore",
176 encodedData);
177 return mimeData;
178}
179
189bool StoreModel::canDropMimeData(const QMimeData *data, Qt::DropAction action,
190 int row, int column,
191 const QModelIndex &parent) const {
192#ifdef QT_DEBUG
193 qDebug() << action << row;
194#else
195 Q_UNUSED(action)
196 Q_UNUSED(row)
197#endif
198
199 QModelIndex useIndex =
200 this->index(parent.row(), parent.column(), parent.parent());
201 QByteArray encodedData =
202 data->data("application/vnd+qtpass.dragAndDropInfoPasswordStore");
203 QDataStream stream(&encodedData, QIODevice::ReadOnly);
205 stream >> info;
206 if (!data->hasFormat("application/vnd+qtpass.dragAndDropInfoPasswordStore"))
207 return false;
208
209 if (column > 0) {
210 return false;
211 }
212
213 // you can drop a folder on a folder
214 if (fs->fileInfo(mapToSource(useIndex)).isDir() && info.isDir) {
215 return true;
216 }
217 // you can drop a file on a folder
218 if (fs->fileInfo(mapToSource(useIndex)).isDir() && info.isFile) {
219 return true;
220 }
221 // you can drop a file on a file
222 if (fs->fileInfo(mapToSource(useIndex)).isFile() && info.isFile) {
223 return true;
224 }
225
226 return false;
227}
228
238bool StoreModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
239 int row, int column, const QModelIndex &parent) {
240 if (!canDropMimeData(data, action, row, column, parent))
241 return false;
242
243 if (action == Qt::IgnoreAction) {
244 return true;
245 }
246 QByteArray encodedData =
247 data->data("application/vnd+qtpass.dragAndDropInfoPasswordStore");
248
249 QDataStream stream(&encodedData, QIODevice::ReadOnly);
251 stream >> info;
252 QModelIndex destIndex =
253 this->index(parent.row(), parent.column(), parent.parent());
254 QFileInfo destFileinfo = fs->fileInfo(mapToSource(destIndex));
255 QFileInfo srcFileInfo = QFileInfo(info.path);
256 QString cleanedSrc = QDir::cleanPath(srcFileInfo.absoluteFilePath());
257 QString cleanedDest = QDir::cleanPath(destFileinfo.absoluteFilePath());
258 if (info.isDir) {
259 // dropped dir onto dir
260 if (destFileinfo.isDir()) {
261 QDir destDir = QDir(cleanedDest).filePath(srcFileInfo.fileName());
262 QString cleanedDestDir = QDir::cleanPath(destDir.absolutePath());
263 if (action == Qt::MoveAction) {
264 QtPassSettings::getPass()->Move(cleanedSrc, cleanedDestDir);
265 } else if (action == Qt::CopyAction) {
266 QtPassSettings::getPass()->Copy(cleanedSrc, cleanedDestDir);
267 }
268 }
269 } else if (info.isFile) {
270 // dropped file onto a directory
271 if (destFileinfo.isDir()) {
272 if (action == Qt::MoveAction) {
273 QtPassSettings::getPass()->Move(cleanedSrc, cleanedDest);
274 } else if (action == Qt::CopyAction) {
275 QtPassSettings::getPass()->Copy(cleanedSrc, cleanedDest);
276 }
277 } else if (destFileinfo.isFile()) {
278 // dropped file onto a file
279 int answer = QMessageBox::question(
280 nullptr, tr("force overwrite?"),
281 tr("overwrite %1 with %2?").arg(cleanedDest, cleanedSrc),
282 QMessageBox::Yes | QMessageBox::No);
283 bool force = answer == QMessageBox::Yes;
284 if (action == Qt::MoveAction) {
285 QtPassSettings::getPass()->Move(cleanedSrc, cleanedDest, force);
286 } else if (action == Qt::CopyAction) {
287 QtPassSettings::getPass()->Copy(cleanedSrc, cleanedDest, force);
288 }
289 }
290 }
291 return true;
292}
293
300bool StoreModel::lessThan(const QModelIndex &source_left,
301 const QModelIndex &source_right) const {
302/* matches logic in QFileSystemModelSorter::compareNodes() */
303#ifndef Q_OS_MAC
304 if (fs && (source_left.column() == 0 || source_left.column() == 1)) {
305 bool leftD = fs->isDir(source_left);
306 bool rightD = fs->isDir(source_right);
307
308 if (leftD ^ rightD)
309 return leftD;
310 }
311#endif
312
313 return QSortFilterProxyModel::lessThan(source_left, source_right);
314}
virtual void Copy(const QString srcDir, const QString dest, const bool force=false)=0
virtual void Move(const QString srcDir, const QString dest, const bool force=false)=0
static Pass * getPass()
Qt::DropActions supportedDropActions() const override
StoreModel::supportedDropActions enable drop.
Definition: storemodel.cpp:117
QStringList mimeTypes() const override
StoreModel::mimeTypes.
Definition: storemodel.cpp:147
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override
StoreModel::dropMimeData.
Definition: storemodel.cpp:238
StoreModel()
StoreModel::StoreModel SubClass of QSortFilterProxyModel via http://www.qtcentre.org/threads/46471-QT...
Definition: storemodel.cpp:34
bool filterAcceptsRow(int, const QModelIndex &) const override
StoreModel::filterAcceptsRow should row be shown, wrapper for StoreModel::ShowThis method.
Definition: storemodel.cpp:43
Qt::DropActions supportedDragActions() const override
StoreModel::supportedDragActions enable drag.
Definition: storemodel.cpp:125
QMimeData * mimeData(const QModelIndexList &indexes) const override
StoreModel::mimeData.
Definition: storemodel.cpp:158
bool ShowThis(const QModelIndex) const
StoreModel::ShowThis should a row be shown, based on our search criteria.
Definition: storemodel.cpp:55
bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override
StoreModel::lessThan.
Definition: storemodel.cpp:300
bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const override
StoreModel::canDropMimeData.
Definition: storemodel.cpp:189
QVariant data(const QModelIndex &index, int role) const override
StoreModel::data don't show the .gpg at the end of a file.
Definition: storemodel.cpp:97
void setModelAndStore(QFileSystemModel *sourceModel, QString passStore)
StoreModel::setModelAndStore update the source model and store.
Definition: storemodel.cpp:84
Qt::ItemFlags flags(const QModelIndex &index) const override
StoreModel::flags.
Definition: storemodel.cpp:134
static const QRegularExpression & endsWithGpg()
Definition: util.cpp:198
QDataStream & operator>>(QDataStream &in, dragAndDropInfoPasswordStore &dragAndDropInfoPasswordStore)
Definition: storemodel.cpp:22
QDataStream & operator<<(QDataStream &out, const dragAndDropInfoPasswordStore &dragAndDropInfoPasswordStore)
Definition: storemodel.cpp:13