blob: 60c91d164524391886ac1130c79adf8925c2de02 [file] [log] [blame]
Alexandre Lision8521baa2015-03-13 11:08:00 -04001/*
2 * Copyright (C) 2004-2015 Savoir-Faire Linux Inc.
3 * Author: Alexandre Lision <alexandre.lision@savoirfairelinux.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Additional permission under GNU GPL version 3 section 7:
20 *
21 * If you modify this program, or any covered work, by linking or
22 * combining it with the OpenSSL project's OpenSSL library (or a
23 * modified version of that library), containing parts covered by the
24 * terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
25 * grants you additional permission to convey the resulting work.
26 * Corresponding Source for a non-source form of such a combination
27 * shall include the source code for the parts of OpenSSL used as well
28 * as that of the covered work.
29 */
Alexandre Lision5855b6a2015-02-03 11:31:05 -050030#import "QNSTreeController.h"
Alexandre Lision5855b6a2015-02-03 11:31:05 -050031
Alexandre Lision2db8f472015-07-22 15:05:46 -040032#import <QDebug>
33
Alexandre Lision5855b6a2015-02-03 11:31:05 -050034@interface Node : NSObject {
35 NSMutableArray *children;
36}
37@end
38
39@implementation Node
40- (id) init
41{
42 if (self = [super init]) {
43 children = [[NSMutableArray alloc] init];
44 }
45 return self;
46}
47
Alexandre Lision2db8f472015-07-22 15:05:46 -040048- (void) addChild:(Node*) child AtIndex:(NSUInteger) idx
Alexandre Lision5855b6a2015-02-03 11:31:05 -050049{
Alexandre Lision2db8f472015-07-22 15:05:46 -040050 [children insertObject:child atIndex:idx];
51}
52
53- (NSMutableArray*) children
54{
55 return children;
Alexandre Lision5855b6a2015-02-03 11:31:05 -050056}
57
Alexandre Lision5855b6a2015-02-03 11:31:05 -050058@end
59
60
61@implementation QNSTreeController
62
63- (id) initWithQModel:(QAbstractItemModel*) model
64{
Alexandre Lision81c97212015-06-17 15:51:53 -040065 self = [super init];
Alexandre Lision5855b6a2015-02-03 11:31:05 -050066 self->privateQModel = model;
67
Alexandre Lision2db8f472015-07-22 15:05:46 -040068 NSMutableArray* nodes = [[NSMutableArray alloc] init];
Alexandre Lision5855b6a2015-02-03 11:31:05 -050069 [self connect];
70
Alexandre Lision2db8f472015-07-22 15:05:46 -040071 [self populate:nodes];
Alexandre Lisionf5fc4792015-03-17 09:15:43 -040072
Alexandre Lision2db8f472015-07-22 15:05:46 -040073 return [self initWithContent:nodes];
Alexandre Lision5855b6a2015-02-03 11:31:05 -050074}
75
Alexandre Lision2db8f472015-07-22 15:05:46 -040076-(void) populate:(NSMutableArray*) nodes
Alexandre Lisionf5fc4792015-03-17 09:15:43 -040077{
Alexandre Lision2db8f472015-07-22 15:05:46 -040078 for (int i = 0 ; i < self->privateQModel->rowCount() ; ++i) {
79 Node* n = [[Node alloc] init];
80 //qDebug() << "POUPL TOP:"<< self->privateQModel->index(i, 0) ;
81 [self populateChild:[n children] withParent:self->privateQModel->index(i, 0)];
82 [nodes insertObject:n atIndex:i];
83 }
84}
85
86- (void) populateChild:(NSMutableArray*) nodes withParent:(QModelIndex)qIdx
87{
88 if (!qIdx.isValid())
89 return;
90 for (int i = 0 ; i < self->privateQModel->rowCount(qIdx) ; ++i) {
91 Node* n = [[Node alloc] init];
92 //qDebug() << "POPUL CHILD:"<< self->privateQModel->index(i, 0, qIdx) ;
93 [self populateChild:[n children] withParent:self->privateQModel->index(i, 0, qIdx)];
94 [nodes insertObject:n atIndex:i];
Alexandre Lisionf5fc4792015-03-17 09:15:43 -040095 }
96}
97
Alexandre Lision5855b6a2015-02-03 11:31:05 -050098- (BOOL)isEditable
99{
100 return self->privateQModel->flags(self->privateQModel->index(0, 0)) | Qt::ItemIsEditable;
101}
102
Alexandre Lision2db8f472015-07-22 15:05:46 -0400103- (QModelIndex) indexPathtoQIdx:(NSIndexPath*) path
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400104{
Alexandre Lision2db8f472015-07-22 15:05:46 -0400105 NSUInteger myArray[[path length]];
106 [path getIndexes:myArray];
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400107 QModelIndex toReturn;
Alexandre Lision3b0bd332015-03-15 18:43:07 -0400108
Alexandre Lision2db8f472015-07-22 15:05:46 -0400109 for (int i = 0; i < path.length; ++i) {
Alexandre Lision3b0bd332015-03-15 18:43:07 -0400110 toReturn = self->privateQModel->index(myArray[i], 0, toReturn);
111 }
112
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400113 return toReturn;
114}
115
Alexandre Lision2db8f472015-07-22 15:05:46 -0400116- (QModelIndex) toQIdx:(NSTreeNode*) node
Alexandre Lision3b0bd332015-03-15 18:43:07 -0400117{
Alexandre Lision2db8f472015-07-22 15:05:46 -0400118 return [self indexPathtoQIdx:node.indexPath];
119}
Alexandre Lision3b0bd332015-03-15 18:43:07 -0400120
Alexandre Lision2db8f472015-07-22 15:05:46 -0400121- (NSIndexPath*) qIdxToNSIndexPath:(QModelIndex) qIdx
122{
Alexandre Lision3b0bd332015-03-15 18:43:07 -0400123 QModelIndex tmp = qIdx.parent();
124 NSMutableArray* allIndexes = [NSMutableArray array];
125 while (tmp.isValid()) {
126 [allIndexes insertObject:@(tmp.row()) atIndex:0];
127 tmp = tmp.parent();
128 }
129 [allIndexes insertObject:@(qIdx.row()) atIndex:allIndexes.count];
130
131 NSUInteger indexes[allIndexes.count];
132 for (int i = 0 ; i < allIndexes.count ; ++i) {
133 indexes[i] = [[allIndexes objectAtIndex:i] intValue];
134 }
Alexandre Lision2db8f472015-07-22 15:05:46 -0400135 return [[NSIndexPath alloc] initWithIndexes:indexes length:allIndexes.count];
136}
137
138- (void) insertNodeAtQIndex:(QModelIndex) qIdx
139{
140 NSIndexPath* path = [self qIdxToNSIndexPath:qIdx];
141 //qDebug() << "insertNodeAt" << qIdx;
142 //NSLog(@"insertNodeAt index: %@", path);
143 if (path.length == 1 && [path indexAtPosition:0] <= [[self arrangedObjects] count])
144 [self insertObject:[[Node alloc] init] atArrangedObjectIndexPath:path];
145 else if (path.length > 1)
146 [self insertObject:[[Node alloc] init] atArrangedObjectIndexPath:path];
147}
148
149- (void) removeNodeAtQIndex:(QModelIndex) qIdx
150{
151 NSIndexPath* path = [self qIdxToNSIndexPath:qIdx];
152 if ([self.arrangedObjects descendantNodeAtIndexPath:path]) {
153 //NSLog(@"removeNodeAt index: %@", path);
154 [self removeObjectAtArrangedObjectIndexPath:path];
155 }
Alexandre Lision3b0bd332015-03-15 18:43:07 -0400156}
157
Alexandre Lision5855b6a2015-02-03 11:31:05 -0500158- (void)connect
159{
160 QObject::connect(self->privateQModel,
161 &QAbstractItemModel::rowsInserted,
162 [=](const QModelIndex & parent, int first, int last) {
Alexandre Lision2db8f472015-07-22 15:05:46 -0400163 for( int row = first; row <= last; ++row) {
164 //qDebug() << "INSERTING:"<< self->privateQModel->index(row, 0, parent) ;
165 if(!self->privateQModel->index(row, 0, parent).isValid())
166 continue;
167
168 [self insertNodeAtQIndex:self->privateQModel->index(row, 0, parent)];
Alexandre Lision5855b6a2015-02-03 11:31:05 -0500169 }
Alexandre Lision2db8f472015-07-22 15:05:46 -0400170 });
Alexandre Lision5855b6a2015-02-03 11:31:05 -0500171
172 QObject::connect(self->privateQModel,
173 &QAbstractItemModel::rowsAboutToBeMoved,
174 [=](const QModelIndex & sourceParent, int sourceStart, int sourceEnd, const QModelIndex & destinationParent, int destinationRow) {
175 NSLog(@"rows about to be moved, start: %d, end: %d, moved to: %d", sourceStart, sourceEnd, destinationRow);
176 /* first remove the row from old location
177 * then insert them at the new location on the "rowsMoved signal */
178 for( int row = sourceStart; row <= sourceEnd; row++) {
179 //TODO
180 }
Alexandre Lision2db8f472015-07-22 15:05:46 -0400181 });
Alexandre Lision5855b6a2015-02-03 11:31:05 -0500182
183 QObject::connect(self->privateQModel,
184 &QAbstractItemModel::rowsMoved,
185 [=](const QModelIndex & sourceParent, int sourceStart, int sourceEnd, const QModelIndex & destinationParent, int destinationRow) {
186 //NSLog(@"rows moved, start: %d, end: %d, moved to: %d", sourceStart, sourceEnd, destinationRow);
187 /* these rows should have been removed in the "rowsAboutToBeMoved" handler
188 * now insert them in the new location */
189 for( int row = sourceStart; row <= sourceEnd; row++) {
190 //TODO
191 }
Alexandre Lision2db8f472015-07-22 15:05:46 -0400192 [self rearrangeObjects];
193 });
Alexandre Lision5855b6a2015-02-03 11:31:05 -0500194
195 QObject::connect(self->privateQModel,
196 &QAbstractItemModel::rowsAboutToBeRemoved,
Alexandre Lision2db8f472015-07-22 15:05:46 -0400197 [self](const QModelIndex & parent, int first, int last) {
198 for( int row = first; row <= last; row++) {
199 //qDebug() << "REMOVING:"<< self->privateQModel->index(row, 0, parent) ;
200 if (!self->privateQModel->index(row, 0, parent).isValid())
201 continue;
202
203 [self removeNodeAtQIndex:self->privateQModel->index(row, 0, parent)];
204 }
205 });
Alexandre Lision5855b6a2015-02-03 11:31:05 -0500206
207 QObject::connect(self->privateQModel,
208 &QAbstractItemModel::rowsRemoved,
Alexandre Lision2db8f472015-07-22 15:05:46 -0400209 [self](const QModelIndex& parent, int first, int last) {
210
211 });
Alexandre Lision5855b6a2015-02-03 11:31:05 -0500212
213 QObject::connect(self->privateQModel,
214 &QAbstractItemModel::layoutChanged,
Alexandre Lision2db8f472015-07-22 15:05:46 -0400215 [self]() {
Alexandre Lisionf5b90da2015-03-20 18:13:54 -0400216 //NSLog(@"layout changed");
Alexandre Lision2db8f472015-07-22 15:05:46 -0400217 [self rearrangeObjects];
218 });
Alexandre Lision5855b6a2015-02-03 11:31:05 -0500219
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400220 QObject::connect(self->privateQModel,
221 &QAbstractItemModel::dataChanged,
Alexandre Lision2db8f472015-07-22 15:05:46 -0400222 [self](const QModelIndex &topLeft, const QModelIndex &bottomRight) {
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400223 for(int row = topLeft.row() ; row <= bottomRight.row() ; ++row)
224 {
225 QModelIndex tmpIdx = self->privateQModel->index(row, 0);
226 if(tmpIdx.row() >= [self.arrangedObjects count]) {
227 Node* n = [[Node alloc] init];
228 if(tmpIdx.isValid())
229 [self insertObject:n atArrangedObjectIndexPath:[[NSIndexPath alloc] initWithIndex:row]];
230 }
231 }
Alexandre Lision2db8f472015-07-22 15:05:46 -0400232 [self rearrangeObjects];
Alexandre Lisionf5fc4792015-03-17 09:15:43 -0400233 });
Alexandre Lision5855b6a2015-02-03 11:31:05 -0500234}
235
236@end