QtPass  1.3.3
Multi-platform GUI for pass, the standard unix password manager.
storemodel.cpp
Go to the documentation of this file.
1 #include "storemodel.h"
2 #include "qtpasssettings.h"
3 
4 #include <QDebug>
5 #include <QRegularExpression>
6 #include <QMessageBox>
7 #include <QMimeData>
8 #include <utility>
9 
10 QDataStream &
11 operator<<(QDataStream &out,
16  return out;
17 }
18 
19 QDataStream &
20 operator>>(QDataStream &in,
24  return in;
25 }
26 
32 StoreModel::StoreModel() { fs = nullptr; }
33 
41 bool StoreModel::filterAcceptsRow(int sourceRow,
42  const QModelIndex &sourceParent) const {
43  QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
44  return ShowThis(index);
45 }
46 
53 bool StoreModel::ShowThis(const QModelIndex index) const {
54  bool retVal = false;
55  if (fs == nullptr)
56  return retVal;
57  // Gives you the info for number of childs with a parent
58  if (sourceModel()->rowCount(index) > 0) {
59  for (int nChild = 0; nChild < sourceModel()->rowCount(index); ++nChild) {
60  QModelIndex childIndex = sourceModel()->index(nChild, 0, index);
61  if (!childIndex.isValid())
62  break;
63  retVal = ShowThis(childIndex);
64  if (retVal)
65  break;
66  }
67  } else {
68  QModelIndex useIndex = sourceModel()->index(index.row(), 0, index.parent());
69  QString path = fs->filePath(useIndex);
70  path = QDir(store).relativeFilePath(path);
71  path.replace(QRegularExpression("\\.gpg$"), "");
72  retVal = path.contains(filterRegularExpression());
73  }
74  return retVal;
75 }
76 
82 void StoreModel::setModelAndStore(QFileSystemModel *sourceModel,
83  QString passStore) {
84  setSourceModel(sourceModel);
85  fs = sourceModel;
86  store = std::move(passStore);
87 }
88 
95 QVariant StoreModel::data(const QModelIndex &index, int role) const {
96  if (!index.isValid())
97  return QVariant();
98 
99  QVariant initial_value;
100  initial_value = QSortFilterProxyModel::data(index, role);
101 
102  if (role == Qt::DisplayRole) {
103  QString name = initial_value.toString();
104  name.replace(QRegularExpression("\\.gpg$"), "");
105  initial_value.setValue(name);
106  }
107 
108  return initial_value;
109 }
110 
115 Qt::DropActions StoreModel::supportedDropActions() const {
116  return Qt::CopyAction | Qt::MoveAction;
117 }
118 
123 Qt::DropActions StoreModel::supportedDragActions() const {
124  return Qt::CopyAction | Qt::MoveAction;
125 }
126 
132 Qt::ItemFlags StoreModel::flags(const QModelIndex &index) const {
133  Qt::ItemFlags defaultFlags = QSortFilterProxyModel::flags(index);
134 
135  if (index.isValid()) {
136  return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | defaultFlags;
137  }
138  return Qt::ItemIsDropEnabled | defaultFlags;
139 }
140 
145 QStringList StoreModel::mimeTypes() const {
146  QStringList types;
147  types << "application/vnd+qtpass.dragAndDropInfoPasswordStore";
148  return types;
149 }
150 
156 QMimeData *StoreModel::mimeData(const QModelIndexList &indexes) const {
158 
159  QByteArray encodedData;
160  // only use the first, otherwise we should enable multiselection
161  QModelIndex index = indexes.at(0);
162  if (index.isValid()) {
163  QModelIndex useIndex = mapToSource(index);
164 
165  info.isDir = fs->fileInfo(useIndex).isDir();
166  info.isFile = fs->fileInfo(useIndex).isFile();
167  info.path = fs->fileInfo(useIndex).absoluteFilePath();
168  QDataStream stream(&encodedData, QIODevice::WriteOnly);
169  stream << info;
170  }
171 
172  auto *mimeData = new QMimeData();
173  mimeData->setData("application/vnd+qtpass.dragAndDropInfoPasswordStore",
174  encodedData);
175  return mimeData;
176 }
177 
187 bool StoreModel::canDropMimeData(const QMimeData *data, Qt::DropAction action,
188  int row, int column,
189  const QModelIndex &parent) const {
190 #ifdef QT_DEBUG
191  qDebug() << action << row;
192 #else
193  Q_UNUSED(action)
194  Q_UNUSED(row)
195 #endif
196 
197  QModelIndex useIndex =
198  this->index(parent.row(), parent.column(), parent.parent());
199  QByteArray encodedData =
200  data->data("application/vnd+qtpass.dragAndDropInfoPasswordStore");
201  QDataStream stream(&encodedData, QIODevice::ReadOnly);
203  stream >> info;
204  if (!data->hasFormat("application/vnd+qtpass.dragAndDropInfoPasswordStore"))
205  return false;
206 
207  if (column > 0) {
208  return false;
209  }
210 
211  // you can drop a folder on a folder
212  if (fs->fileInfo(mapToSource(useIndex)).isDir() && info.isDir) {
213  return true;
214  }
215  // you can drop a file on a folder
216  if (fs->fileInfo(mapToSource(useIndex)).isDir() && info.isFile) {
217  return true;
218  }
219  // you can drop a file on a file
220  if (fs->fileInfo(mapToSource(useIndex)).isFile() && info.isFile) {
221  return true;
222  }
223 
224  return false;
225 }
226 
236 bool StoreModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
237  int row, int column, const QModelIndex &parent) {
238  if (!canDropMimeData(data, action, row, column, parent))
239  return false;
240 
241  if (action == Qt::IgnoreAction) {
242  return true;
243  }
244  QByteArray encodedData =
245  data->data("application/vnd+qtpass.dragAndDropInfoPasswordStore");
246 
247  QDataStream stream(&encodedData, QIODevice::ReadOnly);
249  stream >> info;
250  QModelIndex destIndex =
251  this->index(parent.row(), parent.column(), parent.parent());
252  QFileInfo destFileinfo = fs->fileInfo(mapToSource(destIndex));
253  QFileInfo srcFileInfo = QFileInfo(info.path);
254  QDir qdir;
255  QString cleanedSrc = QDir::cleanPath(srcFileInfo.absoluteFilePath());
256  QString cleanedDest = QDir::cleanPath(destFileinfo.absoluteFilePath());
257  if (info.isDir) {
258  QDir srcDir = QDir(info.path);
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).arg(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 
300 bool 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 }
dragAndDropInfoPasswordStore
Definition: storemodel.h:46
Pass::Move
virtual void Move(const QString srcDir, const QString dest, const bool force=false)=0
storemodel.h
StoreModel::dropMimeData
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override
StoreModel::dropMimeData.
Definition: storemodel.cpp:236
StoreModel::supportedDragActions
Qt::DropActions supportedDragActions() const override
StoreModel::supportedDragActions enable drag.
Definition: storemodel.cpp:123
StoreModel::mimeTypes
QStringList mimeTypes() const override
StoreModel::mimeTypes.
Definition: storemodel.cpp:145
StoreModel::ShowThis
bool ShowThis(const QModelIndex) const
StoreModel::ShowThis should a row be shown, based on our search criteria.
Definition: storemodel.cpp:53
dragAndDropInfoPasswordStore::path
QString path
Definition: storemodel.h:49
StoreModel::flags
Qt::ItemFlags flags(const QModelIndex &index) const override
StoreModel::flags.
Definition: storemodel.cpp:132
StoreModel::data
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:95
QtPassSettings::getPass
static Pass * getPass()
Definition: qtpasssettings.cpp:87
StoreModel::canDropMimeData
bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const override
StoreModel::canDropMimeData.
Definition: storemodel.cpp:187
StoreModel::supportedDropActions
Qt::DropActions supportedDropActions() const override
StoreModel::supportedDropActions enable drop.
Definition: storemodel.cpp:115
StoreModel::mimeData
QMimeData * mimeData(const QModelIndexList &indexes) const override
StoreModel::mimeData.
Definition: storemodel.cpp:156
StoreModel::setModelAndStore
void setModelAndStore(QFileSystemModel *sourceModel, QString passStore)
StoreModel::setModelAndStore update the source model and store.
Definition: storemodel.cpp:82
dragAndDropInfoPasswordStore::isFile
bool isFile
Definition: storemodel.h:48
dragAndDropInfoPasswordStore::isDir
bool isDir
Definition: storemodel.h:47
StoreModel::StoreModel
StoreModel()
StoreModel::StoreModel SubClass of QSortFilterProxyModel via http://www.qtcentre.org/threads/46471-QT...
Definition: storemodel.cpp:32
operator<<
QDataStream & operator<<(QDataStream &out, const dragAndDropInfoPasswordStore &dragAndDropInfoPasswordStore)
Definition: storemodel.cpp:11
StoreModel::lessThan
bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override
StoreModel::lessThan.
Definition: storemodel.cpp:300
operator>>
QDataStream & operator>>(QDataStream &in, dragAndDropInfoPasswordStore &dragAndDropInfoPasswordStore)
Definition: storemodel.cpp:20
StoreModel::filterAcceptsRow
bool filterAcceptsRow(int, const QModelIndex &) const override
StoreModel::filterAcceptsRow should row be shown, wrapper for StoreModel::ShowThis method.
Definition: storemodel.cpp:41
qtpasssettings.h
Pass::Copy
virtual void Copy(const QString srcDir, const QString dest, const bool force=false)=0