Skip to content

Commit f38bb17

Browse files
committed
dropMimeData method moved from model to proxy
1 parent ef0c66c commit f38bb17

File tree

6 files changed

+240
-158
lines changed

6 files changed

+240
-158
lines changed

plugins/gui/include/gui/context_manager_widget/models/context_proxy_model.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
#include <QRegularExpression>
3232
#include <QSortFilterProxyModel>
33+
#include <QMimeData>
3334

3435
namespace hal
3536
{
@@ -60,6 +61,11 @@ namespace hal
6061
*/
6162
bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const override;
6263

64+
QStringList mimeTypes() const override;
65+
QMimeData* mimeData(const QModelIndexList &indexes) const override;
66+
bool dropMimeData(const QMimeData *mimeData, Qt::DropAction action, int row, int column, const QModelIndex &parent) override;
67+
bool canDropMimeData(const QMimeData *mimeData, Qt::DropAction action, int row, int column, const QModelIndex &parent) const override;
68+
6369
public Q_SLOTS:
6470

6571
/**
@@ -74,13 +80,13 @@ namespace hal
7480
protected:
7581

7682
/**
77-
* Defines the compare criteria of 2 data entries (might be defined for each column specifically).
83+
* Defines the compare criteria of tree entries (might be defined for each column specifically).
7884
*
7985
* @param left - The first entry.
8086
* @param right - The seconds entry.
8187
* @return True if left < right, False otherwise.
8288
*/
83-
bool lessThan(const QModelIndex& left, const QModelIndex& right) const override;
89+
bool lessThan(const QModelIndex& left, const QModelIndex& right) const override;
8490

8591
};
8692
} // namespace hal

plugins/gui/include/gui/context_manager_widget/models/context_tree_model.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,10 @@ namespace hal
5454
*/
5555
void writeToFile(QJsonObject& json);
5656

57-
5857
QString name() const { return mName; }
5958
u32 id() const { return mId; }
6059
void setId(u32 id_) { mId = id_; }
6160
void setName(QString name_) { mName = name_; }
62-
6361
};
6462

6563
class ContextTreeItem : public BaseTreeItem
@@ -80,6 +78,8 @@ namespace hal
8078
bool isDirectory() const;
8179
bool isContext() const;
8280
u32 getId() const;
81+
QString getName() const;
82+
QDateTime getTimestamp() const;
8383
GraphContext* context() const;
8484
ContextDirectory* directory() const;
8585
};
@@ -169,9 +169,6 @@ namespace hal
169169

170170
Qt::ItemFlags flags(const QModelIndex& index) const override;
171171
QStringList mimeTypes() const override;
172-
QMimeData* mimeData(const QModelIndexList &indexes) const override;
173-
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override;
174-
bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const override;
175172

176173
/**
177174
* Get all GraphContext%s of the model.
@@ -221,5 +218,7 @@ namespace hal
221218
QVector<ContextDirectory*> mDirectoryList;
222219
u32 mMinDirectoryId;
223220

221+
void dumpRecursion(ContextTreeItem* parent = nullptr, int level = 0) const;
222+
224223
};
225224
} // namespace hal

plugins/gui/src/context_manager_widget/context_manager_widget.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ namespace hal
8787
mContextTreeView->setSelectionBehavior(QAbstractItemView::SelectRows);
8888
mContextTreeView->setSelectionMode(QAbstractItemView::SingleSelection); // ERROR ???
8989
mContextTreeView->setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu);
90-
mContextTreeView->sortByColumn(1, Qt::SortOrder::DescendingOrder);
9190
mContextTreeView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
9291

9392
mContextTreeView->setDragEnabled(true);

plugins/gui/src/context_manager_widget/models/context_proxy_model.cpp

Lines changed: 192 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
#include "gui/context_manager_widget/models/context_proxy_model.h"
22

33
#include "gui/gui_utils/sort.h"
4+
#include "gui/basic_tree_model/base_tree_model.h"
5+
#include "gui/context_manager_widget/models/context_tree_model.h"
6+
#include "gui/user_action/action_move_item.h"
47

58
#include <QDateTime>
69

@@ -18,13 +21,33 @@ namespace hal
1821

1922
bool ContextProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
2023
{
21-
QVariant leftData = sourceModel()->data(left, Qt::UserRole);
22-
QVariant rightData = sourceModel()->data(right, Qt::UserRole);
24+
BaseTreeModel* model = static_cast<BaseTreeModel*>(sourceModel());
25+
if (!model) return false;
2326

24-
if(leftData.userType() == QMetaType::QDateTime)
25-
return leftData.toDateTime() > rightData.toDateTime();
26-
else
27-
return !(gui_utility::compare(gui_utility::mSortMechanism::natural, leftData.toString(), rightData.toString()));
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:
41+
return gui_utility::compare(gui_utility::mSortMechanism::numerated, ctiLeft->getName(), ctiRight->getName());
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;
2851
}
2952

3053
void ContextProxyModel::startSearch(QString text, int options)
@@ -33,4 +56,167 @@ namespace hal
3356
mSearchOptions = SearchOptions(options);
3457
invalidateFilter();
3558
}
59+
60+
QStringList ContextProxyModel::mimeTypes() const
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+
BaseTreeItem* bti = model->getItemFromIndex(mapToSource(indexes.at(0)));
83+
BaseTreeItem* parentItem = bti->getParent();
84+
ContextTreeItem* item = dynamic_cast<ContextTreeItem*>(bti);
85+
if (!item)
86+
{
87+
qDebug() << "cannot cast" << indexes.at(0);
88+
return retval;
89+
}
90+
QByteArray encodedData;
91+
QDataStream stream(&encodedData, QIODevice::WriteOnly);
92+
QString type;
93+
int id;
94+
if (item->isDirectory())
95+
{
96+
id = item->directory()->id();
97+
type = "dir";
98+
}
99+
else if (item->isContext())
100+
{
101+
id = item->context()->id();
102+
type = "view";
103+
}
104+
else
105+
Q_ASSERT (1==0);
106+
stream << type << id << row << (quintptr) parentItem;
107+
retval->setText(type);
108+
retval->setData("contexttreemodel/item", encodedData);
109+
return retval;
110+
111+
}
112+
113+
bool ContextProxyModel::dropMimeData(const QMimeData *mimeData, Qt::DropAction action, int row, int column, const QModelIndex &parent)
114+
{
115+
Q_UNUSED(column);
116+
Q_UNUSED(action);
117+
118+
BaseTreeModel* model = static_cast<BaseTreeModel*>(sourceModel());
119+
if (!model) return false;
120+
121+
QString type;
122+
int id;
123+
int sourceRow = -1;
124+
quintptr sourceParent = 0;
125+
126+
std::cerr << "***drop " << row << (parent.isValid() ? " valid" : " root") << std::endl;
127+
auto encItem = mimeData->data("contexttreemodel/item");
128+
QDataStream dataStream(&encItem, QIODevice::ReadOnly);
129+
dataStream >> type >> id >> sourceRow >> sourceParent;
130+
ContextTreeItem* sourceParentItem = dynamic_cast<ContextTreeItem*>((BaseTreeItem*) sourceParent);
131+
u32 sourceParentId = sourceParentItem ? sourceParentItem->getId() : 0;
132+
133+
QModelIndex moveInx = model->index(sourceRow, 0, model->getIndexFromItem((BaseTreeItem*) sourceParent)); // source model index to item
134+
ContextTreeItem* itemToMove = dynamic_cast<ContextTreeItem*>(model->getItemFromIndex(moveInx));
135+
UserActionObject uao;
136+
if (itemToMove->isContext())
137+
uao = UserActionObject(itemToMove->context()->id(), UserActionObjectType::ContextView);
138+
else if (itemToMove->isDirectory())
139+
uao = UserActionObject(itemToMove->directory()->id(), UserActionObjectType::ContextDir);
140+
else
141+
return false;
142+
143+
u32 targetParentId = 0;
144+
145+
if (parent.isValid())
146+
{
147+
BaseTreeItem* targetParentItem = model->getItemFromIndex(mapToSource(parent));
148+
ContextTreeItem* cti = dynamic_cast<ContextTreeItem*>(targetParentItem);
149+
if (cti)
150+
{
151+
if (!cti->isDirectory()) return false;
152+
targetParentId = cti->directory()->id();
153+
}
154+
155+
}
156+
157+
if (sourceParentId == targetParentId)
158+
{
159+
if (sourceRow == row || sourceRow == row-1) return false; // nothing to do
160+
if (sourceRow < row) row -= 1; // move up, take removed source item into account
161+
}
162+
163+
ActionMoveItem* act = new ActionMoveItem(targetParentId, sourceParentId, row);
164+
act->setObject(uao);
165+
act->exec();
166+
167+
return true;
168+
}
169+
170+
bool ContextProxyModel::canDropMimeData(const QMimeData *mimeData, Qt::DropAction action, int row, int column, const QModelIndex &parent) const
171+
{
172+
Q_UNUSED(column)
173+
Q_UNUSED(action)
174+
Q_UNUSED(row)
175+
176+
BaseTreeModel* model = static_cast<BaseTreeModel*>(sourceModel());
177+
if (!model) return false;
178+
179+
std::cerr << " test " << row << (parent.isValid() ? " valid" : " root") << std::endl;
180+
181+
if (!parent.isValid())
182+
return true; // can always drop on root
183+
184+
int moveRow = -1;
185+
quintptr moveParent = 0;
186+
if(!mimeData->formats().contains("contexttreemodel/item")) return false;
187+
188+
/*
189+
{
190+
if (parent.isValid())
191+
{
192+
ContextTreeItem* cti = dynamic_cast<ContextTreeItem*>(getItemFromIndex(parent));
193+
if (cti)
194+
qDebug() << "drop on " << (cti->isDirectory() ? "directory" : "view") << cti->getId() << row << column;
195+
else
196+
qDebug() << "drop on root " << row << column;
197+
}
198+
else
199+
qDebug() << "drop no parent " << row << column;
200+
}
201+
*/
202+
BaseTreeItem* targetParentItem = model->getItemFromIndex(mapToSource(parent));
203+
if (targetParentItem == model->getRootItem()) return true;
204+
ContextTreeItem* parentItem = dynamic_cast<ContextTreeItem*>(targetParentItem);
205+
if (!parentItem || parentItem->isContext()) return false;
206+
207+
QString type;
208+
int id;
209+
auto encItem = mimeData->data("contexttreemodel/item");
210+
QDataStream dataStream(&encItem, QIODevice::ReadOnly);
211+
dataStream >> type >> id >> moveRow >> moveParent;
212+
213+
if (type == "dir")
214+
{
215+
if (parentItem->isDirectory() && (int) parentItem->directory()->id() == id)
216+
return false;
217+
}
218+
219+
return true;
220+
}
221+
36222
}

0 commit comments

Comments
 (0)