1 #include "reading_list_model.h"
2
3 #include "reading_list_item.h"
4
5 #include "data_base_management.h"
6 #include "qnaturalsorting.h"
7 #include "db_helper.h"
8
9 #include "QsLog.h"
10
11 #include <typeinfo>
12
ReadingListModel(QObject * parent)13 ReadingListModel::ReadingListModel(QObject *parent)
14 : QAbstractItemModel(parent), rootItem(0)
15 {
16 separator1 = new ReadingListSeparatorItem;
17 separator2 = new ReadingListSeparatorItem;
18 }
19
rowCount(const QModelIndex & parent) const20 int ReadingListModel::rowCount(const QModelIndex &parent) const
21 {
22 if (!parent.isValid()) //TOP
23 {
24 int separatorsCount = 2; //labels.isEmpty()?1:2;
25 return specialLists.count() + labels.count() + rootItem->childCount() + separatorsCount;
26 } else {
27 auto item = static_cast<ListItem *>(parent.internalPointer());
28
29 if (typeid(*item) == typeid(ReadingListItem)) {
30 auto item = static_cast<ReadingListItem *>(parent.internalPointer());
31 return item->childCount();
32 }
33 }
34
35 return 0;
36 }
37
columnCount(const QModelIndex & parent) const38 int ReadingListModel::columnCount(const QModelIndex &parent) const
39 {
40 if (parent.isValid()) {
41 auto item = static_cast<ListItem *>(parent.internalPointer());
42 if (typeid(*item) == typeid(ReadingListSeparatorItem))
43 return 0;
44 }
45 return 1;
46 /*if (parent.isValid())
47 return static_cast<ListItem*>(parent.internalPointer())->columnCount();
48 else
49 return rootItem->columnCount();*/
50 }
51
data(const QModelIndex & index,int role) const52 QVariant ReadingListModel::data(const QModelIndex &index, int role) const
53 {
54 if (!index.isValid())
55 return QVariant();
56
57 auto item = static_cast<ListItem *>(index.internalPointer());
58
59 if (role == ReadingListModel::TypeListsRole) {
60 if (typeid(*item) == typeid(SpecialListItem))
61 return QVariant(ReadingListModel::SpecialList);
62
63 if (typeid(*item) == typeid(LabelItem))
64 return QVariant(ReadingListModel::Label);
65
66 if (typeid(*item) == typeid(ReadingListItem))
67 return QVariant(ReadingListModel::ReadingList);
68
69 if (typeid(*item) == typeid(ReadingListSeparatorItem))
70 return QVariant(ReadingListModel::Separator);
71 }
72
73 if (role == ReadingListModel::LabelColorRole && typeid(*item) == typeid(LabelItem)) {
74 auto labelItem = static_cast<LabelItem *>(item);
75 return QVariant(labelItem->colorid());
76 }
77
78 if (role == ReadingListModel::IDRole) {
79 QLOG_DEBUG() << "getting role";
80 return item->getId();
81 }
82
83 if (role == ReadingListModel::SpecialListTypeRole && typeid(*item) == typeid(SpecialListItem)) {
84 auto specialListItem = static_cast<SpecialListItem *>(item);
85 return QVariant(specialListItem->getType());
86 }
87
88 if (typeid(*item) == typeid(ReadingListSeparatorItem))
89 return QVariant();
90
91 if (role == Qt::DecorationRole) {
92 return QVariant(item->getIcon());
93 }
94
95 if (role != Qt::DisplayRole)
96 return QVariant();
97
98 return item->data(index.column());
99 }
100
flags(const QModelIndex & index) const101 Qt::ItemFlags ReadingListModel::flags(const QModelIndex &index) const
102 {
103 if (!index.isValid())
104 return {};
105
106 auto item = static_cast<ListItem *>(index.internalPointer());
107 if (typeid(*item) == typeid(ReadingListSeparatorItem))
108 return {};
109
110 if (typeid(*item) == typeid(ReadingListItem) && static_cast<ReadingListItem *>(item)->parent->getId() != 0)
111 return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDropEnabled | Qt::ItemIsDragEnabled; //only sublists are dragable
112
113 return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDropEnabled;
114 }
115
headerData(int section,Qt::Orientation orientation,int role) const116 QVariant ReadingListModel::headerData(int section, Qt::Orientation orientation, int role) const
117 {
118 if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
119 return rootItem->data(section);
120
121 return QVariant();
122 }
123
index(int row,int column,const QModelIndex & parent) const124 QModelIndex ReadingListModel::index(int row, int column, const QModelIndex &parent) const
125 {
126 if (!hasIndex(row, column, parent))
127 return QModelIndex();
128
129 if (!parent.isValid()) {
130 int separatorsCount = 2; //labels.isEmpty()?1:2;
131
132 if (rowIsSpecialList(row, parent))
133 return createIndex(row, column, specialLists.at(row));
134
135 if (row == specialLists.count())
136 return createIndex(row, column, separator1);
137
138 if (rowIsLabel(row, parent))
139 return createIndex(row, column, labels.at(row - specialLists.count() - 1));
140
141 if (separatorsCount == 2)
142 if (row == specialLists.count() + labels.count() + 1)
143 return createIndex(row, column, separator2);
144
145 if (rowIsReadingList(row, parent))
146 return createIndex(row, column, rootItem->child(row - (specialLists.count() + labels.count() + separatorsCount)));
147
148 } else //sublist
149 {
150 ReadingListItem *parentItem;
151
152 if (!parent.isValid())
153 parentItem = rootItem; //this should be impossible
154 else
155 parentItem = static_cast<ReadingListItem *>(parent.internalPointer());
156
157 ReadingListItem *childItem = parentItem->child(row);
158 return createIndex(row, column, childItem);
159 }
160 /*FolderItem *childItem = parentItem->child(row);
161 if (childItem)
162 return createIndex(row, column, childItem);
163 else*/
164 return QModelIndex();
165 }
166
parent(const QModelIndex & index) const167 QModelIndex ReadingListModel::parent(const QModelIndex &index) const
168 {
169
170 if (!index.isValid())
171 return QModelIndex();
172
173 auto item = static_cast<ListItem *>(index.internalPointer());
174
175 if (typeid(*item) == typeid(ReadingListItem)) {
176 auto childItem = static_cast<ReadingListItem *>(index.internalPointer());
177 ReadingListItem *parent = childItem->parent;
178 if (parent->getId() != 0)
179 return createIndex(parent->row() + specialLists.count() + labels.count() + 2, 0, parent);
180 }
181
182 return QModelIndex();
183 }
184
canDropMimeData(const QMimeData * data,Qt::DropAction action,int row,int column,const QModelIndex & parent) const185 bool ReadingListModel::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const
186 {
187 Q_UNUSED(action);
188
189 QLOG_DEBUG() << "trying to drop into row = " << row << "column column = " << column << "parent" << parent;
190
191 if (row == -1)
192 return false;
193
194 if (!parent.isValid()) //top level items
195 {
196 if (row == -1) //no list
197 return false;
198
199 if (row == 1) //reading is just an smart list
200 return false;
201
202 if (rowIsSeparator(row, parent))
203 return false;
204 }
205
206 if (data->formats().contains(YACReader::YACReaderLibrarComiscSelectionMimeDataFormat))
207 return true;
208
209 if (rowIsReadingList(row, parent)) // TODO avoid droping in a different parent
210 {
211 if (!parent.isValid())
212 return false;
213 else {
214 QList<QPair<int, int>> sublistsRows;
215 QByteArray rawData = data->data(YACReader::YACReaderLibrarSubReadingListMimeDataFormat);
216 QDataStream in(&rawData, QIODevice::ReadOnly);
217 in >> sublistsRows; //deserialize the list of indentifiers
218 if (parent.row() != sublistsRows.at(0).second)
219 return false;
220 return data->formats().contains(YACReader::YACReaderLibrarSubReadingListMimeDataFormat);
221 }
222 }
223
224 return false;
225 }
226
dropMimeData(const QMimeData * data,Qt::DropAction action,int row,int column,const QModelIndex & parent)227 bool ReadingListModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
228 {
229 QLOG_DEBUG() << "drop mimedata into row = " << row << " column = " << column << "parent" << parent;
230 if (data->formats().contains(YACReader::YACReaderLibrarComiscSelectionMimeDataFormat))
231 return dropComics(data, action, row, column, parent);
232
233 if (data->formats().contains(YACReader::YACReaderLibrarSubReadingListMimeDataFormat))
234 return dropSublist(data, action, row, column, parent);
235
236 return false;
237 }
238
dropComics(const QMimeData * data,Qt::DropAction action,int row,int column,const QModelIndex & parent)239 bool ReadingListModel::dropComics(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
240 {
241 Q_UNUSED(action);
242
243 QList<qulonglong> comicIds = YACReader::mimeDataToComicsIds(data);
244
245 QLOG_DEBUG() << "dropped : " << comicIds;
246
247 QModelIndex dest;
248 QModelIndex parentDest;
249
250 if (row == -1) {
251 dest = parent;
252 } else
253 dest = index(row, column, parent);
254
255 parentDest = dest.parent();
256
257 if (rowIsSpecialList(dest.row(), parentDest)) {
258 if (dest.row() == 0) //add to favorites
259 {
260 QLOG_DEBUG() << "-------addComicsToFavorites : " << comicIds << " to " << dest.data(IDRole).toULongLong();
261 emit addComicsToFavorites(comicIds);
262 return true;
263 }
264 }
265
266 if (rowIsLabel(dest.row(), parentDest)) {
267 QLOG_DEBUG() << "+++++++++++addComicsToLabel : " << comicIds << " to " << dest.data(IDRole).toULongLong();
268 emit addComicsToLabel(comicIds, dest.data(IDRole).toULongLong());
269 return true;
270 }
271
272 if (rowIsReadingList(dest.row(), parentDest)) {
273 QLOG_DEBUG() << "///////////addComicsToReadingList : " << comicIds << " to " << dest.data(IDRole).toULongLong();
274 emit addComicsToReadingList(comicIds, dest.data(IDRole).toULongLong());
275 return true;
276 }
277
278 return false;
279 }
280
dropSublist(const QMimeData * data,Qt::DropAction action,int row,int column,const QModelIndex & parent)281 bool ReadingListModel::dropSublist(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
282 {
283 Q_UNUSED(action);
284 Q_UNUSED(column);
285
286 QList<QPair<int, int>> sublistsRows;
287 QByteArray rawData = data->data(YACReader::YACReaderLibrarSubReadingListMimeDataFormat);
288 QDataStream in(&rawData, QIODevice::ReadOnly);
289 in >> sublistsRows; //deserialize the list of indentifiers
290
291 QLOG_DEBUG() << "dropped : " << sublistsRows;
292
293 int sourceRow = sublistsRows.at(0).first;
294 int destRow = row;
295 QModelIndex destParent = parent;
296 if (row == -1) {
297 QLOG_DEBUG() << "droping inside parent";
298 destRow = parent.row();
299 destParent = parent.parent();
300 }
301 QLOG_DEBUG() << "move " << sourceRow << "-" << destRow;
302
303 if (sourceRow == destRow)
304 return false;
305
306 //beginMoveRows(destParent,sourceRow,sourceRow,destParent,destRow);
307
308 auto parentItem = static_cast<ReadingListItem *>(destParent.internalPointer());
309 ReadingListItem *child = parentItem->child(sourceRow);
310 parentItem->removeChild(child);
311 parentItem->appendChild(child, destRow);
312
313 reorderingChildren(parentItem->children());
314 //endMoveRows();
315
316 return true;
317 }
318
mimeData(const QModelIndexList & indexes) const319 QMimeData *ReadingListModel::mimeData(const QModelIndexList &indexes) const
320 {
321 QLOG_DEBUG() << "mimeData requested" << indexes;
322
323 if (indexes.length() == 0) {
324 QLOG_ERROR() << "mimeData requested: indexes is empty";
325 return new QMimeData(); //TODO what happens if 0 is returned?
326 }
327
328 if (indexes.length() > 1) {
329 QLOG_DEBUG() << "mimeData requested for more than one index, this shouldn't be possible";
330 }
331
332 QModelIndex modelIndex = indexes.at(0);
333
334 QList<QPair<int, int>> rows;
335 rows << QPair<int, int>(modelIndex.row(), modelIndex.parent().row());
336 QLOG_DEBUG() << "mimeData requested for row : " << modelIndex.row();
337
338 QByteArray data;
339 QDataStream out(&data, QIODevice::WriteOnly);
340 out << rows; //serialize the list of identifiers
341
342 auto mimeData = new QMimeData();
343 mimeData->setData(YACReader::YACReaderLibrarSubReadingListMimeDataFormat, data);
344
345 return mimeData;
346 }
347
setupReadingListsData(QString path)348 void ReadingListModel::setupReadingListsData(QString path)
349 {
350 beginResetModel();
351
352 cleanAll();
353
354 _databasePath = path;
355 QSqlDatabase db = DataBaseManagement::loadDatabase(path);
356
357 //setup special lists
358 specialLists = setupSpecialLists(db);
359
360 //separator--------------------------------------------
361
362 //setup labels
363 setupLabels(db);
364
365 //separator--------------------------------------------
366
367 //setup reading list
368 setupReadingLists(db);
369
370 endResetModel();
371 }
372
addNewLabel(const QString & name,YACReader::LabelColors color)373 void ReadingListModel::addNewLabel(const QString &name, YACReader::LabelColors color)
374 {
375 QString connectionName = "";
376 {
377 QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
378 qulonglong id = DBHelper::insertLabel(name, color, db);
379
380 int newPos = addLabelIntoList(new LabelItem(QList<QVariant>() << name << YACReader::colorToName(color) << id << color));
381 beginInsertRows(QModelIndex(), specialLists.count() + 1 + newPos + 1, specialLists.count() + 1 + newPos + 1);
382
383 endInsertRows();
384 connectionName = db.connectionName();
385 }
386 QSqlDatabase::removeDatabase(connectionName);
387 }
388
addReadingList(const QString & name)389 void ReadingListModel::addReadingList(const QString &name)
390 {
391 QString connectionName = "";
392 {
393 QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
394 beginInsertRows(QModelIndex(), 0, 0); //TODO calculate the right coordinates before inserting
395
396 qulonglong id = DBHelper::insertReadingList(name, db);
397 ReadingListItem *newItem;
398 rootItem->appendChild(newItem = new ReadingListItem(QList<QVariant>()
399 << name
400 << id
401 << false
402 << true
403 << 0));
404
405 items.insert(id, newItem);
406
407 endInsertRows();
408 connectionName = db.connectionName();
409 }
410 QSqlDatabase::removeDatabase(connectionName);
411 }
412
addReadingListAt(const QString & name,const QModelIndex & mi)413 void ReadingListModel::addReadingListAt(const QString &name, const QModelIndex &mi)
414 {
415 QString connectionName = "";
416 {
417 QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
418
419 beginInsertRows(mi, 0, 0); //TODO calculate the right coordinates before inserting
420
421 auto readingListParent = static_cast<ReadingListItem *>(mi.internalPointer());
422 qulonglong id = DBHelper::insertReadingSubList(name, mi.data(IDRole).toULongLong(), readingListParent->childCount(), db);
423 ReadingListItem *newItem;
424
425 readingListParent->appendChild(newItem = new ReadingListItem(QList<QVariant>()
426 << name
427 << id
428 << false
429 << true
430 << readingListParent->childCount()));
431
432 items.insert(id, newItem);
433 endInsertRows();
434 connectionName = db.connectionName();
435 }
436 QSqlDatabase::removeDatabase(connectionName);
437 }
438
isEditable(const QModelIndex & mi)439 bool ReadingListModel::isEditable(const QModelIndex &mi)
440 {
441 if (!mi.isValid())
442 return false;
443 auto item = static_cast<ListItem *>(mi.internalPointer());
444 return typeid(*item) != typeid(SpecialListItem);
445 }
446
isReadingList(const QModelIndex & mi)447 bool ReadingListModel::isReadingList(const QModelIndex &mi)
448 {
449 if (!mi.isValid())
450 return false;
451 auto item = static_cast<ListItem *>(mi.internalPointer());
452 return typeid(*item) == typeid(ReadingListItem);
453 }
454
isReadingSubList(const QModelIndex & mi)455 bool ReadingListModel::isReadingSubList(const QModelIndex &mi)
456 {
457 if (!mi.isValid())
458 return false;
459 auto item = static_cast<ListItem *>(mi.internalPointer());
460 if (typeid(*item) == typeid(ReadingListItem)) {
461 auto readingListItem = static_cast<ReadingListItem *>(item);
462 if (readingListItem->parent == rootItem)
463 return false;
464 else
465 return true;
466 } else
467 return false;
468 }
469
name(const QModelIndex & mi)470 QString ReadingListModel::name(const QModelIndex &mi)
471 {
472 return data(mi, Qt::DisplayRole).toString();
473 }
474
rename(const QModelIndex & mi,const QString & name)475 void ReadingListModel::rename(const QModelIndex &mi, const QString &name)
476 {
477 if (!isEditable(mi))
478 return;
479 QString connectionName = "";
480 {
481 QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
482
483 auto item = static_cast<ListItem *>(mi.internalPointer());
484
485 if (typeid(*item) == typeid(ReadingListItem)) {
486 auto rli = static_cast<ReadingListItem *>(item);
487 rli->setName(name);
488 DBHelper::renameList(item->getId(), name, db);
489
490 if (rli->parent->getId() != 0) {
491 //TODO
492 //move row depending on the name
493 } else
494 emit dataChanged(index(mi.row(), 0), index(mi.row(), 0));
495 } else if (typeid(*item) == typeid(LabelItem)) {
496 auto li = static_cast<LabelItem *>(item);
497 li->setName(name);
498 DBHelper::renameLabel(item->getId(), name, db);
499 emit dataChanged(index(mi.row(), 0), index(mi.row(), 0));
500 }
501 connectionName = db.connectionName();
502 }
503 QSqlDatabase::removeDatabase(connectionName);
504 }
505
deleteItem(const QModelIndex & mi)506 void ReadingListModel::deleteItem(const QModelIndex &mi)
507 {
508 if (isEditable(mi)) {
509 QLOG_DEBUG() << "parent row :" << mi.parent().data() << "-" << mi.row();
510 beginRemoveRows(mi.parent(), mi.row(), mi.row());
511 QString connectionName = "";
512 {
513 QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
514
515 auto item = static_cast<ListItem *>(mi.internalPointer());
516
517 if (typeid(*item) == typeid(ReadingListItem)) {
518 auto rli = static_cast<ReadingListItem *>(item);
519 QLOG_DEBUG() << "num children : " << rli->parent->childCount();
520 rli->parent->removeChild(rli);
521 QLOG_DEBUG() << "num children : " << rli->parent->childCount();
522 DBHelper::removeListFromDB(item->getId(), db);
523 if (rli->parent->getId() != 0) {
524 reorderingChildren(rli->parent->children());
525 }
526 QLOG_DEBUG() << "num children : " << rli->parent->childCount();
527 } else if (typeid(*item) == typeid(LabelItem)) {
528 auto li = static_cast<LabelItem *>(item);
529 labels.removeOne(li);
530 DBHelper::removeLabelFromDB(item->getId(), db);
531 }
532 connectionName = db.connectionName();
533 }
534 QSqlDatabase::removeDatabase(connectionName);
535
536 endRemoveRows();
537 }
538 }
539
getLabels()540 const QList<LabelItem *> ReadingListModel::getLabels()
541 {
542 return labels;
543 }
544
cleanAll()545 void ReadingListModel::cleanAll()
546 {
547 if (rootItem != 0) {
548 delete rootItem;
549
550 qDeleteAll(specialLists);
551 qDeleteAll(labels);
552
553 specialLists.clear();
554 labels.clear();
555
556 items.clear();
557 }
558
559 rootItem = 0;
560 }
561
setupReadingListsData(QSqlQuery & sqlquery,ReadingListItem * parent)562 void ReadingListModel::setupReadingListsData(QSqlQuery &sqlquery, ReadingListItem *parent)
563 {
564 items.insert(parent->getId(), parent);
565
566 QSqlRecord record = sqlquery.record();
567
568 int name = record.indexOf("name");
569 int id = record.indexOf("id");
570 int finished = record.indexOf("finished");
571 int completed = record.indexOf("completed");
572 int ordering = record.indexOf("ordering");
573 int parentId = record.indexOf("parentId");
574
575 while (sqlquery.next()) {
576 ReadingListItem *rli = new ReadingListItem(QList<QVariant>()
577 << sqlquery.value(name)
578 << sqlquery.value(id)
579 << sqlquery.value(finished)
580 << sqlquery.value(completed)
581 << sqlquery.value(ordering));
582
583 ReadingListItem *currentParent;
584 if (sqlquery.value(parentId).isNull())
585 currentParent = rootItem;
586 else
587 currentParent = items.value(sqlquery.value(parentId).toULongLong());
588
589 currentParent->appendChild(rli);
590
591 items.insert(rli->getId(), rli);
592 }
593 }
594
setupSpecialLists(QSqlDatabase & db)595 QList<SpecialListItem *> ReadingListModel::setupSpecialLists(QSqlDatabase &db)
596 {
597 QList<SpecialListItem *> list;
598
599 QSqlQuery selectQuery("SELECT * FROM default_reading_list ORDER BY id,name", db);
600
601 QSqlRecord record = selectQuery.record();
602
603 int name = record.indexOf("name");
604 int id = record.indexOf("id");
605
606 while (selectQuery.next()) {
607 list << new SpecialListItem(QList<QVariant>()
608 << selectQuery.value(name)
609 << selectQuery.value(id));
610 }
611
612 //Reading after Favorites, Why? Because I want to :P
613 list.insert(1, new SpecialListItem(QList<QVariant>() << "Reading" << 0));
614
615 return list;
616 }
617
setupLabels(QSqlDatabase & db)618 void ReadingListModel::setupLabels(QSqlDatabase &db)
619 {
620 QSqlQuery selectQuery("SELECT * FROM label ORDER BY ordering,name", db);
621
622 QSqlRecord record = selectQuery.record();
623
624 int name = record.indexOf("name");
625 int color = record.indexOf("color");
626 int id = record.indexOf("id");
627 int ordering = record.indexOf("ordering");
628
629 while (selectQuery.next()) {
630 addLabelIntoList(new LabelItem(QList<QVariant>()
631 << selectQuery.value(name)
632 << selectQuery.value(color)
633 << selectQuery.value(id)
634 << selectQuery.value(ordering)));
635 }
636
637 //TEST
638
639 // INSERT INTO label (name, color, ordering) VALUES ("Oh Oh", "red", 1);
640 // INSERT INTO label (name, color, ordering) VALUES ("lalala", "orange", 2);
641 // INSERT INTO label (name, color, ordering) VALUES ("we are not sorry", "yellow", 3);
642 // INSERT INTO label (name, color, ordering) VALUES ("there we go", "green", 4);
643 // INSERT INTO label (name, color, ordering) VALUES ("oklabunga", "cyan", 5);
644 // INSERT INTO label (name, color, ordering) VALUES ("hailer mailer", "blue", 6);
645 // INSERT INTO label (name, color, ordering) VALUES ("lol", "violet", 7);
646 // INSERT INTO label (name, color, ordering) VALUES ("problems", "purple", 8);
647 // INSERT INTO label (name, color, ordering) VALUES ("me gussssta", "pink", 9);
648 // INSERT INTO label (name, color, ordering) VALUES (":D", "white", 10);
649 // INSERT INTO label (name, color, ordering) VALUES ("ainsss", "light", 11);
650 // INSERT INTO label (name, color, ordering) VALUES ("put a smile on my face", "dark", 12);
651 }
652
setupReadingLists(QSqlDatabase & db)653 void ReadingListModel::setupReadingLists(QSqlDatabase &db)
654 {
655 //setup root item
656 rootItem = new ReadingListItem(QList<QVariant>() << "ROOT" << 0 << true << false);
657
658 QSqlQuery selectQuery("select * from reading_list order by parentId IS NULL DESC", db);
659
660 //setup reading lists
661 setupReadingListsData(selectQuery, rootItem);
662
663 //TEST
664 // ReadingListItem * node1;
665 // rootItem->appendChild(node1 = new ReadingListItem(QList<QVariant>() /*<< 0*/ << "My reading list" << "atr"));
666 // rootItem->appendChild(new ReadingListItem(QList<QVariant>() /*<< 0*/ << "X timeline" << "atr"));
667
668 // node1->appendChild(new ReadingListItem(QList<QVariant>() /*<< 0*/ << "sublist" << "atr",node1));
669 }
670
addLabelIntoList(LabelItem * item)671 int ReadingListModel::addLabelIntoList(LabelItem *item)
672 {
673 if (labels.isEmpty())
674 labels << item;
675 else {
676 int i = 0;
677
678 while (i < labels.count() && (labels.at(i)->colorid() < item->colorid()))
679 i++;
680
681 if (i < labels.count()) {
682 if (labels.at(i)->colorid() == item->colorid()) //sort by name
683 {
684 while (i < labels.count() && labels.at(i)->colorid() == item->colorid() && naturalSortLessThanCI(labels.at(i)->name(), item->name()))
685 i++;
686 }
687 }
688
689 if (i >= labels.count()) {
690 QLOG_DEBUG() << "insertando label al final " << item->name();
691 labels << item;
692 } else {
693 QLOG_DEBUG() << "insertando label en " << i << "-" << item->name();
694 labels.insert(i, item);
695 }
696
697 return i;
698 }
699
700 return 0;
701 }
702
reorderingChildren(QList<ReadingListItem * > children)703 void ReadingListModel::reorderingChildren(QList<ReadingListItem *> children)
704 {
705 QList<qulonglong> childrenIds;
706 int i = 0;
707 foreach (ReadingListItem *item, children) {
708 item->setOrdering(i++);
709 childrenIds << item->getId();
710 }
711 QString connectionName = "";
712 {
713 QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
714 DBHelper::reasignOrderToSublists(childrenIds, db);
715 connectionName = db.connectionName();
716 }
717 QSqlDatabase::removeDatabase(connectionName);
718 }
719
rowIsSpecialList(int row,const QModelIndex & parent) const720 bool ReadingListModel::rowIsSpecialList(int row, const QModelIndex &parent) const
721 {
722 if (parent.isValid())
723 return false; //by now no sublists in special list
724
725 if (row >= 0 && row < specialLists.count())
726 return true;
727
728 return false;
729 }
730
rowIsLabel(int row,const QModelIndex & parent) const731 bool ReadingListModel::rowIsLabel(int row, const QModelIndex &parent) const
732 {
733 if (parent.isValid())
734 return false; //by now no sublists in labels
735
736 if (row > specialLists.count() && row <= specialLists.count() + labels.count())
737 return true;
738
739 return false;
740 }
741
rowIsReadingList(int row,const QModelIndex & parent) const742 bool ReadingListModel::rowIsReadingList(int row, const QModelIndex &parent) const
743 {
744 if (parent.isValid())
745 return true; //only lists with sublists
746
747 int separatorsCount = labels.isEmpty() ? 1 : 2;
748
749 if (row >= specialLists.count() + labels.count() + separatorsCount)
750 return true;
751
752 return false;
753 }
754
rowIsSeparator(int row,const QModelIndex & parent) const755 bool ReadingListModel::rowIsSeparator(int row, const QModelIndex &parent) const
756 {
757 if (parent.isValid())
758 return false; //only separators at top level
759
760 if (row == specialLists.count())
761 return true;
762
763 int separatorsCount = labels.isEmpty() ? 1 : 2;
764 if (separatorsCount == 2 && row == specialLists.count() + labels.count() + 1)
765 return true;
766
767 return false;
768 }
769
ReadingListModelProxy(QObject * parent)770 ReadingListModelProxy::ReadingListModelProxy(QObject *parent)
771 : QSortFilterProxyModel(parent)
772 {
773 }
774