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 <QMessageBox>
6 #include <QMimeData>
7 #include <utility>
8 
9 QDataStream &
10 operator<<(QDataStream &out,
15  return out;
16 }
17 
18 QDataStream &
19 operator>>(QDataStream &in,
23  return in;
24 }
25 
31 StoreModel::StoreModel() { fs = nullptr; }
32 
40 bool StoreModel::filterAcceptsRow(int sourceRow,
41  const QModelIndex &sourceParent) const {
42  QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
43  return ShowThis(index);
44 }
45 
52 bool StoreModel::ShowThis(const QModelIndex index) const {
53  bool retVal = false;
54  if (fs == nullptr)
55  return retVal;
56  // Gives you the info for number of childs with a parent
57  if (sourceModel()->rowCount(index) > 0) {
58  for (int nChild = 0; nChild < sourceModel()->rowCount(index); ++nChild) {
59  QModelIndex childIndex = sourceModel()->index(nChild, 0, index);
60  if (!childIndex.isValid())
61  break;
62  retVal = ShowThis(childIndex);
63  if (retVal)
64  break;
65  }
66  } else {
67  QModelIndex useIndex = sourceModel()->index(index.row(), 0, index.parent());
68  QString path = fs->filePath(useIndex);
69  path = QDir(store).relativeFilePath(path);
70  path.replace(QRegExp("\\.gpg$"), "");
71  retVal = path.contains(filterRegExp());
72  }
73  return retVal;
74 }
75 
81 void StoreModel::setModelAndStore(QFileSystemModel *sourceModel,
82  QString passStore) {
83  setSourceModel(sourceModel);
84  fs = sourceModel;
85  store = std::move(passStore);
86 }
87 
94 QVariant StoreModel::data(const QModelIndex &index, int role) const {
95  if (!index.isValid())
96  return QVariant();
97 
98  QVariant initial_value;
99  initial_value = QSortFilterProxyModel::data(index, role);
100 
101  if (role == Qt::DisplayRole) {
102  QString name = initial_value.toString();
103  name.replace(QRegExp("\\.gpg$"), "");
104  initial_value.setValue(name);
105  }
106 
107  return initial_value;
108 }
109 
114 Qt::DropActions StoreModel::supportedDropActions() const {
115  return Qt::CopyAction | Qt::MoveAction;
116 }
117 
122 Qt::DropActions StoreModel::supportedDragActions() const {
123  return Qt::CopyAction | Qt::MoveAction;
124 }
125 
131 Qt::ItemFlags StoreModel::flags(const QModelIndex &index) const {
132  Qt::ItemFlags defaultFlags = QSortFilterProxyModel::flags(index);
133 
134  if (index.isValid()) {
135  return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | defaultFlags;
136  }
137  return Qt::ItemIsDropEnabled | defaultFlags;
138 }
139 
144 QStringList StoreModel::mimeTypes() const {
145  QStringList types;
146  types << "application/vnd+qtpass.dragAndDropInfoPasswordStore";
147  return types;
148 }
149 
155 QMimeData *StoreModel::mimeData(const QModelIndexList &indexes) const {
157 
158  QByteArray encodedData;
159  // only use the first, otherwise we should enable multiselection
160  QModelIndex index = indexes.at(0);
161  if (index.isValid()) {
162  QModelIndex useIndex = mapToSource(index);
163 
164  info.isDir = fs->fileInfo(useIndex).isDir();
165  info.isFile = fs->fileInfo(useIndex).isFile();
166  info.path = fs->fileInfo(useIndex).absoluteFilePath();
167  QDataStream stream(&encodedData, QIODevice::WriteOnly);
168  stream << info;
169  }
170 
171  auto *mimeData = new QMimeData();
172  mimeData->setData("application/vnd+qtpass.dragAndDropInfoPasswordStore",
173  encodedData);
174  return mimeData;
175 }
176 
186 bool StoreModel::canDropMimeData(const QMimeData *data, Qt::DropAction action,
187  int row, int column,
188  const QModelIndex &parent) const {
189 #ifdef QT_DEBUG
190  qDebug() << action << row;
191 #else
192  Q_UNUSED(action)
193  Q_UNUSED(row)
194 #endif
195 
196  QModelIndex useIndex =
197  this->index(parent.row(), parent.column(), parent.parent());
198  QByteArray encodedData =
199  data->data("application/vnd+qtpass.dragAndDropInfoPasswordStore");
200  QDataStream stream(&encodedData, QIODevice::ReadOnly);
202  stream >> info;
203  if (!data->hasFormat("application/vnd+qtpass.dragAndDropInfoPasswordStore"))
204  return false;
205 
206  if (column > 0) {
207  return false;
208  }
209 
210  // you can drop a folder on a folder
211  if (fs->fileInfo(mapToSource(useIndex)).isDir() && info.isDir) {
212  return true;
213  }
214  // you can drop a file on a folder
215  if (fs->fileInfo(mapToSource(useIndex)).isDir() && info.isFile) {
216  return true;
217  }
218  // you can drop a file on a file
219  if (fs->fileInfo(mapToSource(useIndex)).isFile() && info.isFile) {
220  return true;
221  }
222 
223  return false;
224 }
225 
235 bool StoreModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
236  int row, int column, const QModelIndex &parent) {
237  if (!canDropMimeData(data, action, row, column, parent))
238  return false;
239 
240  if (action == Qt::IgnoreAction) {
241  return true;
242  }
243  QByteArray encodedData =
244  data->data("application/vnd+qtpass.dragAndDropInfoPasswordStore");
245 
246  QDataStream stream(&encodedData, QIODevice::ReadOnly);
248  stream >> info;
249  QModelIndex destIndex =
250  this->index(parent.row(), parent.column(), parent.parent());
251  QFileInfo destFileinfo = fs->fileInfo(mapToSource(destIndex));
252  QFileInfo srcFileInfo = QFileInfo(info.path);
253  QDir qdir;
254  QString cleanedSrc = QDir::cleanPath(srcFileInfo.absoluteFilePath());
255  QString cleanedDest = QDir::cleanPath(destFileinfo.absoluteFilePath());
256  if (info.isDir) {
257  QDir srcDir = QDir(info.path);
258  // dropped dir onto dir
259  if (destFileinfo.isDir()) {
260  QDir destDir = QDir(cleanedDest).filePath(srcFileInfo.fileName());
261  QString cleanedDestDir = QDir::cleanPath(destDir.absolutePath());
262  if (action == Qt::MoveAction) {
263  QtPassSettings::getPass()->Move(cleanedSrc, cleanedDestDir);
264  } else if (action == Qt::CopyAction) {
265  QtPassSettings::getPass()->Copy(cleanedSrc, cleanedDestDir);
266  }
267  }
268  } else if (info.isFile) {
269  // dropped file onto a directory
270  if (destFileinfo.isDir()) {
271  if (action == Qt::MoveAction) {
272  QtPassSettings::getPass()->Move(cleanedSrc, cleanedDest);
273  } else if (action == Qt::CopyAction) {
274  QtPassSettings::getPass()->Copy(cleanedSrc, cleanedDest);
275  }
276  } else if (destFileinfo.isFile()) {
277  // dropped file onto a file
278  int answer = QMessageBox::question(
279  nullptr, tr("force overwrite?"),
280  tr("overwrite %1 with %2?").arg(cleanedDest).arg(cleanedSrc),
281  QMessageBox::Yes | QMessageBox::No);
282  bool force = answer == QMessageBox::Yes;
283  if (action == Qt::MoveAction) {
284  QtPassSettings::getPass()->Move(cleanedSrc, cleanedDest, force);
285  } else if (action == Qt::CopyAction) {
286  QtPassSettings::getPass()->Copy(cleanedSrc, cleanedDest, force);
287  }
288  }
289  }
290  return true;
291 }
292 
299 bool StoreModel::lessThan(const QModelIndex &source_left,
300  const QModelIndex &source_right) const {
301 /* matches logic in QFileSystemModelSorter::compareNodes() */
302 #ifndef Q_OS_MAC
303  if (fs && (source_left.column() == 0 || source_left.column() == 1)) {
304  bool leftD = fs->isDir(source_left);
305  bool rightD = fs->isDir(source_right);
306 
307  if (leftD ^ rightD)
308  return leftD;
309  }
310 #endif
311 
312  return QSortFilterProxyModel::lessThan(source_left, source_right);
313 }
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:235
StoreModel::supportedDragActions
Qt::DropActions supportedDragActions() const override
StoreModel::supportedDragActions enable drag.
Definition: storemodel.cpp:122
StoreModel::mimeTypes
QStringList mimeTypes() const override
StoreModel::mimeTypes.
Definition: storemodel.cpp:144
StoreModel::ShowThis
bool ShowThis(const QModelIndex) const
StoreModel::ShowThis should a row be shown, based on our search criteria.
Definition: storemodel.cpp:52
dragAndDropInfoPasswordStore::path
QString path
Definition: storemodel.h:49
StoreModel::flags
Qt::ItemFlags flags(const QModelIndex &index) const override
StoreModel::flags.
Definition: storemodel.cpp:131
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:94
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:186
StoreModel::supportedDropActions
Qt::DropActions supportedDropActions() const override
StoreModel::supportedDropActions enable drop.
Definition: storemodel.cpp:114
StoreModel::mimeData
QMimeData * mimeData(const QModelIndexList &indexes) const override
StoreModel::mimeData.
Definition: storemodel.cpp:155
StoreModel::setModelAndStore
void setModelAndStore(QFileSystemModel *sourceModel, QString passStore)
StoreModel::setModelAndStore update the source model and store.
Definition: storemodel.cpp:81
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:31
operator<<
QDataStream & operator<<(QDataStream &out, const dragAndDropInfoPasswordStore &dragAndDropInfoPasswordStore)
Definition: storemodel.cpp:10
StoreModel::lessThan
bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override
StoreModel::lessThan.
Definition: storemodel.cpp:299
operator>>
QDataStream & operator>>(QDataStream &in, dragAndDropInfoPasswordStore &dragAndDropInfoPasswordStore)
Definition: storemodel.cpp:19
StoreModel::filterAcceptsRow
bool filterAcceptsRow(int, const QModelIndex &) const override
StoreModel::filterAcceptsRow should row be shown, wrapper for StoreModel::ShowThis method.
Definition: storemodel.cpp:40
qtpasssettings.h
Pass::Copy
virtual void Copy(const QString srcDir, const QString dest, const bool force=false)=0