1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
|
#include "lsscenemodel.h"
#include "lsglobals.h"
LSSceneModel::LSSceneModel(LYTLayout *layout, QObject *parent) :
QAbstractItemModel(parent)
{
m_layout = layout;
m_paneIcons[LYTPane::PaneType] = LSGlobals::getIcon("pane");
m_paneIcons[LYTPane::PictureType] = LSGlobals::getIcon("picture");
m_paneIcons[LYTPane::TextBoxType] = LSGlobals::getIcon("textbox");
m_paneIcons[LYTPane::WindowType] = LSGlobals::getIcon("window");
m_paneIcons[LYTPane::BoundingType] = LSGlobals::getIcon("bounding");
m_movingPaneParent = 0;
}
LSSceneModel::~LSSceneModel() {
if (m_movingPaneParent)
delete m_movingPaneParent;
}
QModelIndex LSSceneModel::index(int row, int column, const QModelIndex &parent) const {
if (!hasIndex(row, column, parent))
return QModelIndex();
if (!parent.isValid())
return createIndex(row, column, m_layout->rootPane);
// what's the parent..?
LYTPane *parentPane = (LYTPane*)parent.internalPointer();
LYTPane *pane = parentPane->children.at(row);
return createIndex(row, column, pane);
}
QModelIndex LSSceneModel::parent(const QModelIndex &child) const {
if (!child.isValid())
return QModelIndex();
LYTPane *childPane = (LYTPane*)child.internalPointer();
LYTPane *parentPane = childPane->parent;
if (parentPane) {
LYTPane *parentParentPane = parentPane->parent;
int index = parentParentPane ? parentParentPane->children.indexOf(parentPane) : 0;
return createIndex(index, 0, parentPane);
} else {
return QModelIndex();
}
}
int LSSceneModel::rowCount(const QModelIndex &parent) const {
if (!parent.isValid()) {
return 1; // the root pane
}
LYTPane *parentPane = (LYTPane*)parent.internalPointer();
return parentPane->children.count();
}
int LSSceneModel::columnCount(const QModelIndex &parent) const {
(void)parent;
return 1;
}
QVariant LSSceneModel::data(const QModelIndex &index, int role) const {
LYTPane *pane = (LYTPane*)index.internalPointer();
if (pane) {
switch (role) {
case Qt::DisplayRole:
return pane->name;
case Qt::DecorationRole:
return m_paneIcons[pane->type()];
}
}
return QVariant();
}
Qt::ItemFlags LSSceneModel::flags(const QModelIndex &index) const {
Qt::ItemFlags flag;
flag = Qt::ItemIsEnabled | Qt::ItemIsSelectable |
Qt::ItemIsDropEnabled | Qt::ItemIsEditable;
if (index.isValid() && index.parent().isValid())
flag |= Qt::ItemIsDragEnabled;
return flag;
}
Qt::DropActions LSSceneModel::supportedDropActions() const {
return Qt::MoveAction;
}
// I am doing a terrible, terrible, terrible thing here.
// I hate drag-and-drop.
// As far as I can see, insertRows and removeRows are ONLY called by Qt when
// dragging something. So instead of doing a real insertion/removal... I'll
// store the intended destination, and once I'm told what pane needs to be
// removed (moved) I do the whole thing at once.
bool LSSceneModel::insertRows(int row, int count, const QModelIndex &parent) {
qDebug("LSSceneModel::insertRows(%d, %d, something)", row, count);
if (count != 1) {
qWarning("huh, what? count != 1");
return false;
}
if (m_movingPaneParent) {
qWarning("huh, already moving something? dunno");
return false;
}
m_movingPaneParent = new QPersistentModelIndex(parent);
m_movingPaneRow = row;
return true;
}
bool LSSceneModel::removeRows(int row, int count, const QModelIndex &parent) {
qDebug("LSSceneModel::removeRows(%d, %d, something)", row, count);
if (count != 1) {
qWarning("huh, what? count != 1");
return false;
}
if (!m_movingPaneParent) {
qWarning("huh, not moving anything? dunno");
return false;
}
LYTPane *parentPane = (LYTPane*)parent.internalPointer();
LYTPane *pane = parentPane->children.at(row);
beginRemoveRows(parent, row, row);
parentPane->children.removeAt(row);
endRemoveRows();
// now add it!
LYTPane *newParentPane = (LYTPane*)m_movingPaneParent->internalPointer();
// note: compensate for the offset: if we're moving the thing within the
// same parent and the destination row is higher than the source row, then
// removing the source row will have changed the index of the row the user
// actually wanted to move the moved row to... what a terrible sentence :|
if (*m_movingPaneParent == parent && m_movingPaneRow > row)
m_movingPaneRow--;
beginInsertRows(*m_movingPaneParent, m_movingPaneRow, m_movingPaneRow);
pane->parent = newParentPane;
newParentPane->children.insert(m_movingPaneRow, pane);
endInsertRows();
delete m_movingPaneParent;
m_movingPaneParent = 0;
return true;
}
|