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
|
/*
* Copyright (C) 2009-2012 Geometer Plus <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#include "LibraryView.h"
#include "LibraryNodes.h"
#include "../library/Library.h"
#include "../library/Book.h"
#include "../library/Tag.h"
#include "../libraryActions/BooksUtil.h"
LibraryByTagView::LibraryByTagView(ZLPaintContext &context) : LibraryView(context) {
}
void LibraryByTagView::collectTagNodes(const ZLBlockTreeNode &root, std::map<shared_ptr<Tag>,TagNode*,TagComparator> &nodeMap) {
const ZLBlockTreeNode::List &children = root.children();
for (ZLBlockTreeNode::List::const_iterator it = children.begin(); it != children.end(); ++it) {
if ((*it)->isInstanceOf(TagNode::TYPE_ID)) {
TagNode *tagNode = (TagNode*)*it;
nodeMap[tagNode->tag()] = tagNode;
collectTagNodes(*tagNode, nodeMap);
}
}
}
void LibraryByTagView::updateBookList(TagNode *tagNode) {
const BookList &books = Library::Instance().books(tagNode->tag());
const ZLBlockTreeNode::List &subNodes = tagNode->children();
BookList::const_iterator jt = books.begin();
ZLBlockTreeNode::List::const_iterator kt = subNodes.begin();
for (; jt != books.end() && kt != subNodes.end(); ++jt, ++kt) {
if (!(*kt)->isInstanceOf(BookNode::TYPE_ID)) {
break;
}
if (((BookNode*)(*kt))->book()->file() != (*jt)->file()) {
break;
}
}
std::size_t index = jt - books.begin();
while (tagNode->children().size() > index) {
ZLBlockTreeNode *bookNode = tagNode->children()[index];
if (!bookNode->isInstanceOf(BookNode::TYPE_ID)) {
break;
}
delete bookNode;
}
for (; jt != books.end(); ++jt) {
new BookNode(tagNode, index++, *jt);
}
}
void LibraryByTagView::makeUpToDate() {
TagList tags;
BooksUtil::collectTagsFromLibrary(tags);
std::map<shared_ptr<Tag>,TagNode*,TagComparator> nodeMap;
collectTagNodes(rootNode(), nodeMap);
for (TagList::const_iterator it = tags.begin(); it != tags.end(); ++it) {
shared_ptr<Tag> tag = *it;
TagNode *tagNode = nodeMap[tag];
if (tagNode == 0) {
tagNode =
(tag.isNull() || tag->parent().isNull()) ?
new TagNode(&rootNode(), tag) :
new TagNode(nodeMap[tag->parent()], tag);
nodeMap[tag] = tagNode;
}
updateBookList(tagNode);
}
for (TagList::const_iterator it = tags.begin(); it != tags.end(); ++it) {
nodeMap.erase(nodeMap.find(*it));
}
for (std::map<shared_ptr<Tag>,TagNode*,TagComparator>::reverse_iterator it = nodeMap.rbegin(); it != nodeMap.rend(); ++it) {
delete it->second;
}
}
|