HAL
context_proxy_model.cpp
Go to the documentation of this file.
2 
3 #include "gui/gui_utils/sort.h"
7 
8 #include <QDateTime>
9 
10 namespace hal
11 {
13  {
14 
15  }
16 
17  bool ContextProxyModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const
18  {
19  return checkRowRecursion(source_row, source_parent, 0, 1);
20  }
21 
22  bool ContextProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
23  {
24  BaseTreeModel* model = static_cast<BaseTreeModel*>(sourceModel());
25  if (!model) return false;
26 
27  ContextTreeItem* ctiLeft = dynamic_cast<ContextTreeItem*>(model->getItemFromIndex(left));
28  ContextTreeItem* ctiRight = dynamic_cast<ContextTreeItem*>(model->getItemFromIndex(right));
29 
30  // root item first
31  if (!ctiRight) return false;
32  if (!ctiLeft) return true;
33 
34  // directory before view
35  if (ctiRight->isDirectory() && !ctiLeft->isDirectory()) return false;
36  if (ctiLeft->isDirectory() && !ctiRight->isDirectory()) return false;
37 
38  switch (left.column())
39  {
40  case 0:
42  case 1:
43  return ctiLeft->getId() < ctiRight->getId();
44  case 2:
45  return ctiLeft->getTimestamp() < ctiRight->getTimestamp();
46  default:
47  break;
48  }
49 
50  return false;
51  }
52 
53  void ContextProxyModel::startSearch(QString text, int options)
54  {
55  mSearchString = text;
56  mSearchOptions = SearchOptions(options);
58  }
59 
61  {
62  return sourceModel()->mimeTypes();
63  }
64 
65  QMimeData* ContextProxyModel::mimeData(const QModelIndexList &indexes) const
66  {
67  QMimeData* retval = new QMimeData;
68  // only single row allowed
69  int row = -1;
70  for (const QModelIndex& inx : indexes)
71  {
72  if (row < 0)
73  row = inx.row();
74  else if (row != inx.row())
75  return retval;
76  }
77  if (row < 0)
78  return retval;
79 
80  BaseTreeModel* model = static_cast<BaseTreeModel*>(sourceModel());
81  if (!model) return retval;
82 
83  QModelIndex sourceIndex = mapToSource(indexes.at(0));
84  BaseTreeItem* bti = model->getItemFromIndex(sourceIndex);
85  row = sourceIndex.row();
86  BaseTreeItem* parentItem = bti->getParent();
87  ContextTreeItem* item = dynamic_cast<ContextTreeItem*>(bti);
88  if (!item)
89  {
90  qDebug() << "cannot cast" << indexes.at(0);
91  return retval;
92  }
93  QByteArray encodedData;
94  QDataStream stream(&encodedData, QIODevice::WriteOnly);
95  QString moveType;
96  QString moveText;
97  int id;
98  if (item->isDirectory())
99  {
100  id = item->directory()->id();
101  moveType = "dir";
102  moveText = QString("gui.View.setCurrentDirectory(%1)").arg(id);
103  }
104  else if (item->isContext())
105  {
106  id = item->context()->id();
107  moveType = "view";
108  moveText = QString("gui.View.getName(%1)").arg(id);
109  }
110  else
111  Q_ASSERT (1==0);
112  stream << moveType << id << row << (quintptr) parentItem;
113  retval->setText(moveText);
114  retval->setData("contexttreemodel/item", encodedData);
115  return retval;
116 
117  }
118 
119  bool ContextProxyModel::dropMimeData(const QMimeData *mimeData, Qt::DropAction action, int row, int column, const QModelIndex &parent)
120  {
121  Q_UNUSED(column);
122  Q_UNUSED(action);
123 
124  BaseTreeModel* model = static_cast<BaseTreeModel*>(sourceModel());
125  if (!model) return false;
126 
127  QString moveType;
128  int moveId;
129  int sourceRow = -1;
130  quintptr sourceParent = 0;
131 
132  auto encItem = mimeData->data("contexttreemodel/item");
133  QDataStream dataStream(&encItem, QIODevice::ReadOnly);
134  dataStream >> moveType >> moveId >> sourceRow >> sourceParent;
135  ContextTreeItem* sourceParentItem = dynamic_cast<ContextTreeItem*>((BaseTreeItem*) sourceParent);
136  u32 sourceParentId = sourceParentItem ? sourceParentItem->getId() : 0;
137 
138  QModelIndex moveInx = model->index(sourceRow, 0, model->getIndexFromItem((BaseTreeItem*) sourceParent)); // source model index to item
139  ContextTreeItem* itemToMove = dynamic_cast<ContextTreeItem*>(model->getItemFromIndex(moveInx));
140  UserActionObject uao;
141  if (itemToMove->isContext())
143  else if (itemToMove->isDirectory())
145  else
146  return false;
147 
148  u32 targetParentId = 0;
149 
150  if (parent.isValid())
151  {
152  BaseTreeItem* targetParentItem = model->getItemFromIndex(mapToSource(parent));
153  ContextTreeItem* cti = dynamic_cast<ContextTreeItem*>(targetParentItem);
154  if (cti)
155  {
156  if (!cti->isDirectory()) return false;
157  targetParentId = cti->directory()->id();
158  }
159 
160  }
161 
162  if (sourceParentId == targetParentId)
163  {
164  if (sourceRow == row || sourceRow == row-1) return false; // nothing to do
165  if (sourceRow < row) row -= 1; // move up, take removed source item into account
166  }
167 
168  ActionMoveItem* act = new ActionMoveItem(targetParentId, sourceParentId, row);
169  act->setObject(uao);
170  act->exec();
171 
172  return true;
173  }
174 
175  bool ContextProxyModel::canDropMimeData(const QMimeData *mimeData, Qt::DropAction action, int row, int column, const QModelIndex &parent) const
176  {
177  Q_UNUSED(column)
178  Q_UNUSED(action)
179  Q_UNUSED(row)
180 
181  BaseTreeModel* model = static_cast<BaseTreeModel*>(sourceModel());
182  if (!model) return false;
183 
184  if (!parent.isValid())
185  return true; // can always drop on root
186 
187  int moveRow = -1;
188  quintptr moveParent = 0;
189  if(!mimeData->formats().contains("contexttreemodel/item")) return false;
190 
191 /*
192  {
193  if (parent.isValid())
194  {
195  ContextTreeItem* cti = dynamic_cast<ContextTreeItem*>(getItemFromIndex(parent));
196  if (cti)
197  qDebug() << "drop on " << (cti->isDirectory() ? "directory" : "view") << cti->getId() << row << column;
198  else
199  qDebug() << "drop on root " << row << column;
200  }
201  else
202  qDebug() << "drop no parent " << row << column;
203  }
204  */
206  if (tpar == model->getRootItem()) return true;
207  ContextTreeItem* targetParentItem = dynamic_cast<ContextTreeItem*>(tpar);
208  if (!targetParentItem || targetParentItem->isContext()) return false;
209 
210  QString moveType;
211  int moveId;
212  auto encItem = mimeData->data("contexttreemodel/item");
213  QDataStream dataStream(&encItem, QIODevice::ReadOnly);
214  dataStream >> moveType >> moveId >> moveRow >> moveParent;
215 
216  if (moveType == "dir")
217  {
218  // target must not be the item itself or any (grand-)child of the item
219  ContextTreeItem* targetAnchestorItem = targetParentItem;
220  while (targetAnchestorItem)
221  {
222  if (targetAnchestorItem->isDirectory() && (int) targetAnchestorItem->directory()->id() == moveId)
223  return false;
224  targetAnchestorItem = dynamic_cast<ContextTreeItem*>(targetAnchestorItem->getParent());
225  }
226  }
227 
228  return true;
229  }
230 
231 }
bool exec() override
(Future) Base class for all tree models related to the details widget.
virtual BaseTreeItem * getParent() const
The BaseTreeModel implements generic standard functions of a tree model.
QModelIndex getIndexFromItem(BaseTreeItem *item) const
virtual QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
BaseTreeItem * getRootItem() const
BaseTreeItem * getItemFromIndex(QModelIndex index) const
QMimeData * mimeData(const QModelIndexList &indexes) const override
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override
QStringList mimeTypes() const override
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override
void startSearch(QString text, int options) override
bool dropMimeData(const QMimeData *mimeData, Qt::DropAction action, int row, int column, const QModelIndex &parent) override
ContextProxyModel(QObject *parent=nullptr)
bool canDropMimeData(const QMimeData *mimeData, Qt::DropAction action, int row, int column, const QModelIndex &parent) const override
QDateTime getTimestamp() const
GraphContext * context() const
ContextDirectory * directory() const
SearchOptions mSearchOptions
virtual bool checkRowRecursion(int sourceRow, const QModelIndex &sourceParent, int startIndex, int endIndex, int offset=0) const
virtual void setObject(const UserActionObject &obj)
Definition: user_action.cpp:32
The UserActionObject class represents a single object used in UserAction.
action
Definition: control.py:16
int compare(mSortMechanism mechanism, QString a, QString b)
Definition: sort.cpp:153
quint32 u32
i32 id
bool moveRow(const QModelIndex &sourceParent, int sourceRow, const QModelIndex &destinationParent, int destinationChild)
QByteArray data(const QString &mimeType) const const
virtual QStringList formats() const const
void setData(const QString &mimeType, const QByteArray &data)
void setText(const QString &text)
int row() const const
QObject * parent() const const
virtual QModelIndex mapToSource(const QModelIndex &proxyIndex) const const override
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
bool contains(const QString &str, Qt::CaseSensitivity cs) const const
DropAction