@@ -114,19 +114,25 @@ QModelIndex QgsLayerTreeModel::parent( const QModelIndex &child ) const
114
114
if ( !child.isValid () )
115
115
return QModelIndex ();
116
116
117
- QgsLayerTreeNode *parentNode = 0 ;
118
- QgsLayerTreeNode *n = index2node ( child );
119
- if ( !n )
117
+ if ( QgsLayerTreeNode *n = index2node ( child ) )
118
+ {
119
+ return indexOfParentLayerTreeNode ( n->parent () ); // must not be null
120
+ }
121
+ else if ( QgsLayerTreeModelLegendNode* legendNode = index2legendNode ( child ) )
120
122
{
121
- QgsLayerTreeModelLegendNode* sym = index2legendNode ( child );
122
- Q_ASSERT ( sym );
123
- parentNode = sym->layerNode ();
123
+ return legendParent ( legendNode );
124
124
}
125
125
else
126
126
{
127
- parentNode = n->parent (); // must not be null
127
+ Q_ASSERT ( false ); // no other node types!
128
+ return QModelIndex ();
128
129
}
129
130
131
+ }
132
+
133
+
134
+ QModelIndex QgsLayerTreeModel::indexOfParentLayerTreeNode ( QgsLayerTreeNode* parentNode ) const
135
+ {
130
136
Q_ASSERT ( parentNode );
131
137
132
138
QgsLayerTreeNode* grandParentNode = parentNode->parent ();
@@ -1036,7 +1042,10 @@ QList<QgsLayerTreeModelLegendNode*> QgsLayerTreeModel::filterLegendNodes( const
1036
1042
void QgsLayerTreeModel::legendCleanup ()
1037
1043
{
1038
1044
foreach ( const LayerLegendData& data, mLegend )
1045
+ {
1039
1046
qDeleteAll ( data.originalNodes );
1047
+ delete data.tree ;
1048
+ }
1040
1049
mLegend .clear ();
1041
1050
}
1042
1051
@@ -1046,6 +1055,7 @@ void QgsLayerTreeModel::removeLegendFromLayer( QgsLayerTreeLayer* nodeLayer )
1046
1055
if ( mLegend .contains ( nodeLayer ) )
1047
1056
{
1048
1057
qDeleteAll ( mLegend [nodeLayer].originalNodes );
1058
+ delete mLegend [nodeLayer].tree ;
1049
1059
mLegend .remove ( nodeLayer );
1050
1060
}
1051
1061
}
@@ -1077,13 +1087,60 @@ void QgsLayerTreeModel::addLegendToLayer( QgsLayerTreeLayer* nodeL )
1077
1087
connect ( n, SIGNAL ( dataChanged () ), this , SLOT ( legendNodeDataChanged () ) );
1078
1088
}
1079
1089
1080
- mLegend [nodeL].originalNodes = lstNew;
1081
- mLegend [nodeL].activeNodes = filteredLstNew;
1090
+ LayerLegendData& data = mLegend [nodeL];
1091
+ data.originalNodes = lstNew;
1092
+ data.activeNodes = filteredLstNew;
1093
+
1094
+ data.tree = 0 ;
1095
+
1096
+ // maybe the legend nodes form a tree - try to create a tree structure from the list
1097
+ if ( testFlag ( ShowLegendAsTree ) )
1098
+ tryBuildLegendTree ( data );
1082
1099
1083
1100
if ( ! isEmbedded ) endInsertRows ();
1084
1101
}
1085
1102
1086
1103
1104
+ void QgsLayerTreeModel::tryBuildLegendTree ( LayerLegendData& data )
1105
+ {
1106
+ // first check whether there are any legend nodes that are not top-level
1107
+ bool hasParentKeys = false ;
1108
+ foreach ( QgsLayerTreeModelLegendNode* n, data.activeNodes )
1109
+ {
1110
+ if ( !n->data ( QgsLayerTreeModelLegendNode::ParentRuleKeyRole ).toString ().isEmpty () )
1111
+ {
1112
+ hasParentKeys = true ;
1113
+ break ;
1114
+ }
1115
+ }
1116
+ if ( !hasParentKeys )
1117
+ return ; // all legend nodes are top-level => stick with list representation
1118
+
1119
+ // make mapping from rules to nodes and do some sanity checks
1120
+ QHash<QString, QgsLayerTreeModelLegendNode*> rule2node;
1121
+ rule2node[QString ()] = 0 ;
1122
+ foreach ( QgsLayerTreeModelLegendNode* n, data.activeNodes )
1123
+ {
1124
+ QString ruleKey = n->data ( QgsLayerTreeModelLegendNode::RuleKeyRole ).toString ();
1125
+ if ( ruleKey.isEmpty () ) // in tree all nodes must have key
1126
+ return ;
1127
+ if ( rule2node.contains ( ruleKey ) ) // and they must be unique
1128
+ return ;
1129
+ rule2node[ruleKey] = n;
1130
+ }
1131
+
1132
+ // create the tree structure
1133
+ data.tree = new LayerLegendTree;
1134
+ foreach ( QgsLayerTreeModelLegendNode* n, data.activeNodes )
1135
+ {
1136
+ QString parentRuleKey = n->data ( QgsLayerTreeModelLegendNode::ParentRuleKeyRole ).toString ();
1137
+ QgsLayerTreeModelLegendNode* parent = rule2node.value ( parentRuleKey, 0 );
1138
+ data.tree ->parents [n] = parent;
1139
+ data.tree ->children [parent] << n;
1140
+ }
1141
+ }
1142
+
1143
+
1087
1144
QgsLayerTreeModelLegendNode* QgsLayerTreeModel::index2legendNode ( const QModelIndex& index )
1088
1145
{
1089
1146
return qobject_cast<QgsLayerTreeModelLegendNode*>( reinterpret_cast <QObject*>( index.internalPointer () ) );
@@ -1092,9 +1149,26 @@ QgsLayerTreeModelLegendNode* QgsLayerTreeModel::index2legendNode( const QModelIn
1092
1149
1093
1150
QModelIndex QgsLayerTreeModel::legendNode2index ( QgsLayerTreeModelLegendNode* legendNode )
1094
1151
{
1152
+ const LayerLegendData& data = mLegend [legendNode->layerNode ()];
1153
+ if ( data.tree )
1154
+ {
1155
+ if ( QgsLayerTreeModelLegendNode* parentLegendNode = data.tree ->parents [legendNode] )
1156
+ {
1157
+ QModelIndex parentIndex = legendNode2index ( parentLegendNode );
1158
+ int row = data.tree ->children [parentLegendNode].indexOf ( legendNode );
1159
+ return index ( row, 0 , parentIndex );
1160
+ }
1161
+ else
1162
+ {
1163
+ QModelIndex parentIndex = node2index ( legendNode->layerNode () );
1164
+ int row = data.tree ->children [0 ].indexOf ( legendNode );
1165
+ return index ( row, 0 , parentIndex );
1166
+ }
1167
+ }
1168
+
1095
1169
QModelIndex parentIndex = node2index ( legendNode->layerNode () );
1096
1170
Q_ASSERT ( parentIndex.isValid () );
1097
- int row = mLegend [legendNode-> layerNode ()] .activeNodes .indexOf ( legendNode );
1171
+ int row = data .activeNodes .indexOf ( legendNode );
1098
1172
if ( row < 0 ) // legend node may be filtered (exists within the list of original nodes, but not in active nodes)
1099
1173
return QModelIndex ();
1100
1174
return index ( row, 0 , parentIndex );
@@ -1103,7 +1177,10 @@ QModelIndex QgsLayerTreeModel::legendNode2index( QgsLayerTreeModelLegendNode* le
1103
1177
1104
1178
int QgsLayerTreeModel::legendNodeRowCount ( QgsLayerTreeModelLegendNode* node ) const
1105
1179
{
1106
- Q_UNUSED ( node );
1180
+ const LayerLegendData& data = mLegend [node->layerNode ()];
1181
+ if ( data.tree )
1182
+ return data.tree ->children [node].count ();
1183
+
1107
1184
return 0 ; // they are leaves
1108
1185
}
1109
1186
@@ -1113,26 +1190,55 @@ int QgsLayerTreeModel::legendRootRowCount( QgsLayerTreeLayer* nL ) const
1113
1190
if ( legendEmbeddedInParent ( nL ) )
1114
1191
return 0 ;
1115
1192
1116
- return mLegend [nL].activeNodes .count ();
1193
+ const LayerLegendData& data = mLegend [nL];
1194
+ if ( data.tree )
1195
+ return data.tree ->children [0 ].count ();
1196
+
1197
+ return data.activeNodes .count ();
1117
1198
}
1118
1199
1119
1200
1120
1201
QModelIndex QgsLayerTreeModel::legendRootIndex ( int row, int column, QgsLayerTreeLayer* nL ) const
1121
1202
{
1122
1203
Q_ASSERT ( mLegend .contains ( nL ) );
1123
- return createIndex ( row, column, static_cast <QObject*>( mLegend [nL].activeNodes .at ( row ) ) );
1204
+ const LayerLegendData& data = mLegend [nL];
1205
+ if ( data.tree )
1206
+ return createIndex ( row, column, static_cast <QObject*>( data.tree ->children [0 ].at ( row ) ) );
1207
+
1208
+ return createIndex ( row, column, static_cast <QObject*>( data.activeNodes .at ( row ) ) );
1124
1209
}
1125
1210
1126
1211
1127
1212
QModelIndex QgsLayerTreeModel::legendNodeIndex ( int row, int column, QgsLayerTreeModelLegendNode* node ) const
1128
1213
{
1129
- Q_UNUSED ( row );
1130
- Q_UNUSED ( column );
1131
- Q_UNUSED ( node );
1214
+ const LayerLegendData& data = mLegend [node->layerNode ()];
1215
+ if ( data.tree )
1216
+ return createIndex ( row, column, static_cast <QObject*>( data.tree ->children [node].at ( row ) ) );
1217
+
1132
1218
return QModelIndex (); // have no children
1133
1219
}
1134
1220
1135
1221
1222
+ QModelIndex QgsLayerTreeModel::legendParent ( QgsLayerTreeModelLegendNode* legendNode ) const
1223
+ {
1224
+ QgsLayerTreeLayer* layerNode = legendNode->layerNode ();
1225
+ const LayerLegendData& data = mLegend [layerNode];
1226
+ if ( data.tree )
1227
+ {
1228
+ if ( QgsLayerTreeModelLegendNode* parentNode = data.tree ->parents [legendNode] )
1229
+ {
1230
+ QgsLayerTreeModelLegendNode* grandParentNode = data.tree ->parents [parentNode]; // may be null (not a problem)
1231
+ int row = data.tree ->children [grandParentNode].indexOf ( parentNode );
1232
+ return createIndex ( row, 0 , static_cast <QObject*>( parentNode ) );
1233
+ }
1234
+ else
1235
+ return indexOfParentLayerTreeNode ( layerNode );
1236
+ }
1237
+
1238
+ return indexOfParentLayerTreeNode ( layerNode );
1239
+ }
1240
+
1241
+
1136
1242
QVariant QgsLayerTreeModel::legendNodeData ( QgsLayerTreeModelLegendNode* node, int role ) const
1137
1243
{
1138
1244
if ( role == Qt::CheckStateRole && !testFlag ( AllowLegendChangeState ) )
@@ -1153,13 +1259,13 @@ Qt::ItemFlags QgsLayerTreeModel::legendNodeFlags( QgsLayerTreeModelLegendNode* n
1153
1259
bool QgsLayerTreeModel::legendEmbeddedInParent ( QgsLayerTreeLayer* nodeLayer ) const
1154
1260
{
1155
1261
const LayerLegendData& data = mLegend [nodeLayer];
1156
- return data.activeNodes .count () == 1 && data.activeNodes [0 ]->isEmbeddedInParent ();
1262
+ return data.activeNodes .count () == 1 && data.activeNodes [0 ]->isEmbeddedInParent ();
1157
1263
}
1158
1264
1159
1265
1160
1266
QIcon QgsLayerTreeModel::legendIconEmbeddedInParent ( QgsLayerTreeLayer* nodeLayer ) const
1161
1267
{
1162
- return QIcon ( qvariant_cast<QPixmap>( mLegend [nodeLayer].activeNodes [0 ]->data ( Qt::DecorationRole ) ) );
1268
+ return QIcon ( qvariant_cast<QPixmap>( mLegend [nodeLayer].activeNodes [0 ]->data ( Qt::DecorationRole ) ) );
1163
1269
}
1164
1270
1165
1271
0 commit comments