21
#include <ZLFileImage.h>
22
#include <ZLDialogManager.h>
23
20
#include <ZLOptionsDialog.h>
24
21
#include <ZLStringUtil.h>
26
#include <ZLTextModel.h>
27
#include <ZLTextParagraph.h>
28
#include <ZLTextParagraphCursor.h>
30
23
#include "CollectionView.h"
24
#include "CollectionModel.h"
31
25
#include "FBReader.h"
32
26
#include "BookInfoDialog.h"
34
#include "../bookmodel/FBTextKind.h"
35
#include "../collection/BookCollection.h"
36
28
#include "../collection/BookList.h"
37
#include "../description/BookDescription.h"
38
#include "../description/Author.h"
40
static const std::string DELETE_IMAGE_ID = "delete";
41
static const std::string BOOK_INFO_IMAGE_ID = "bookInfo";
42
static const std::string AUTHOR_INFO_IMAGE_ID = "authorInfo";
43
static const std::string SERIES_ORDER_IMAGE_ID = "seriesOrder";
45
class CollectionModel : public ZLTextTreeModel {
48
CollectionModel(BookCollection &collection);
51
BookDescriptionPtr bookByParagraphNumber(int num);
52
int paragraphNumberByBook(BookDescriptionPtr book);
59
void insertText(FBTextKind kind, const std::string &text);
60
void insertImage(const std::string &id);
63
BookCollection &myCollection;
65
ZLImageMap myImageMap;
66
std::map<ZLTextParagraph*,BookDescriptionPtr> myParagraphToBook;
67
std::map<BookDescriptionPtr,int> myBookToParagraph;
70
CollectionModel::CollectionModel(BookCollection &collection) : ZLTextTreeModel(), myCollection(collection) {
71
const std::string prefix = ZLibrary::ApplicationImageDirectory() + ZLibrary::FileNameDelimiter;
72
myImageMap[DELETE_IMAGE_ID] = new ZLFileImage("image/png", prefix + "tree-remove.png", 0);
73
myImageMap[BOOK_INFO_IMAGE_ID] = new ZLFileImage("image/png", prefix + "tree-bookinfo.png", 0);
74
myImageMap[AUTHOR_INFO_IMAGE_ID] = new ZLFileImage("image/png", prefix + "tree-authorinfo.png", 0);
75
myImageMap[SERIES_ORDER_IMAGE_ID] = new ZLFileImage("image/png", prefix + "tree-order.png", 0);
78
CollectionModel::~CollectionModel() {
81
BookDescriptionPtr CollectionModel::bookByParagraphNumber(int num) {
82
if ((num < 0) || ((int)paragraphsNumber() <= num)) {
85
std::map<ZLTextParagraph*,BookDescriptionPtr>::iterator it = myParagraphToBook.find((*this)[num]);
86
return (it != myParagraphToBook.end()) ? it->second : 0;
89
int CollectionModel::paragraphNumberByBook(BookDescriptionPtr book) {
90
std::map<BookDescriptionPtr,int>::iterator it = myBookToParagraph.find(book);
91
return (it != myBookToParagraph.end()) ? it->second : -1;
94
void CollectionModel::build() {
95
const std::vector<AuthorPtr> &authors = myCollection.authors();
96
std::string currentSequenceName;
97
ZLTextTreeParagraph *sequenceParagraph;
98
for (std::vector<AuthorPtr>::const_iterator it = authors.begin(); it != authors.end(); ++it) {
99
const Books &books = myCollection.books(*it);
100
if (!books.empty()) {
101
currentSequenceName.erase();
102
sequenceParagraph = 0;
104
ZLTextTreeParagraph *authorParagraph = createParagraph();
105
insertText(LIBRARY_AUTHOR_ENTRY, (*it)->displayName());
106
//insertImage(AUTHOR_INFO_IMAGE_ID);
107
for (Books::const_iterator jt = books.begin(); jt != books.end(); ++jt) {
108
const std::string &sequenceName = (*jt)->sequenceName();
109
if (sequenceName.empty()) {
110
currentSequenceName.erase();
111
sequenceParagraph = 0;
112
} else if (sequenceName != currentSequenceName) {
113
currentSequenceName = sequenceName;
114
sequenceParagraph = createParagraph(authorParagraph);
115
insertText(LIBRARY_BOOK_ENTRY, sequenceName);
116
//insertImage(SERIES_ORDER_IMAGE_ID);
118
ZLTextTreeParagraph *bookParagraph = createParagraph(
119
(sequenceParagraph == 0) ? authorParagraph : sequenceParagraph
121
insertText(LIBRARY_BOOK_ENTRY, (*jt)->title());
122
insertImage(BOOK_INFO_IMAGE_ID);
123
if (myCollection.isBookExternal(*jt)) {
124
insertImage(DELETE_IMAGE_ID);
126
myParagraphToBook[bookParagraph] = *jt;
127
myBookToParagraph[*jt] = paragraphsNumber() - 1;
133
void CollectionModel::update() {
134
myParagraphToBook.clear();
135
myBookToParagraph.clear();
136
for (int i = paragraphsNumber() - 1; i >= 0; --i) {
142
void CollectionModel::insertText(FBTextKind kind, const std::string &text) {
143
addControl(kind, true);
147
void CollectionModel::insertImage(const std::string &id) {
149
addImage(id, myImageMap, 0);
152
CollectionView::CollectionView(FBReader &reader, shared_ptr<ZLPaintContext> context) : FBView(reader, context), myUpdateModel(true) {
153
setModel(new CollectionModel(myCollection));
30
static const std::string LIBRARY = "Library";
32
CollectionView::CollectionView(FBReader &reader, shared_ptr<ZLPaintContext> context) : FBView(reader, context),
33
ShowTagsOption(ZLCategoryKey::LOOK_AND_FEEL, LIBRARY, "ShowTags", true),
34
ShowAllBooksTagOption(ZLCategoryKey::LOOK_AND_FEEL, LIBRARY, "ShowAllBooksTag", true),
36
setModel(new CollectionModel(*this, myCollection));
37
myShowTags = ShowTagsOption.value();
38
myShowAllBooksList = ShowAllBooksTagOption.value();
156
41
CollectionView::~CollectionView() {
213
106
const ZLTextImageElement &imageElement = (ZLTextImageElement&)element;
215
BookDescriptionPtr book = collectionModel().bookByParagraphNumber(imageArea->ParagraphNumber);
108
const std::string &id = imageElement.id();
110
if (id == CollectionModel::BookInfoImageId) {
111
editBookInfo(collectionModel().bookByParagraphNumber(imageArea->ParagraphNumber));
113
} else if (id == CollectionModel::RemoveBookImageId) {
114
removeBook(collectionModel().bookByParagraphNumber(imageArea->ParagraphNumber));
116
} else if (id == CollectionModel::RemoveTagImageId) {
117
removeTag(collectionModel().tagByParagraphNumber(imageArea->ParagraphNumber));
119
} else if (id == CollectionModel::TagInfoImageId) {
120
editTagInfo(collectionModel().tagByParagraphNumber(imageArea->ParagraphNumber));
220
if (imageElement.id() == BOOK_INFO_IMAGE_ID) {
221
if (BookInfoDialog(myCollection, book->fileName()).dialog().run()) {
222
myCollection.rebuild(false);
223
myUpdateModel = true;
225
application().refreshWindow();
228
} else if (imageElement.id() == DELETE_IMAGE_ID) {
229
ZLResourceKey boxKey("removeBookBox");
230
const std::string message =
231
ZLStringUtil::printf(ZLDialogManager::dialogMessage(boxKey), book->title());
232
if (ZLDialogManager::instance().questionBox(boxKey, message,
233
ZLDialogManager::YES_BUTTON, ZLDialogManager::NO_BUTTON) == 0) {
234
collectionModel().removeAllMarks();
235
BookList().removeFileName(book->fileName());
236
ZLTextTreeParagraph *paragraph = (ZLTextTreeParagraph*)collectionModel()[imageArea->ParagraphNumber];
237
ZLTextTreeParagraph *parent = paragraph->parent();
238
if (parent->children().size() == 1) {
239
collectionModel().removeParagraph(imageArea->ParagraphNumber);
240
collectionModel().removeParagraph(imageArea->ParagraphNumber - 1);
242
collectionModel().removeParagraph(imageArea->ParagraphNumber);
244
if (collectionModel().paragraphsNumber() == 0) {
247
rebuildPaintInfo(true);
248
application().refreshWindow();
255
127
int index = paragraphIndexByCoordinate(y);
142
void CollectionView::editBookInfo(BookDescriptionPtr book) {
143
if (!book.isNull() && BookInfoDialog(myCollection, book->fileName()).dialog().run()) {
144
myCollection.rebuild(false);
145
myUpdateModel = true;
147
application().refreshWindow();
151
void CollectionView::removeBook(BookDescriptionPtr book) {
156
CollectionModel &cModel = collectionModel();
158
ZLResourceKey boxKey("removeBookBox");
159
const std::string message =
160
ZLStringUtil::printf(ZLDialogManager::dialogMessage(boxKey), book->title());
161
if (ZLDialogManager::instance().questionBox(boxKey, message,
162
ZLDialogManager::YES_BUTTON, ZLDialogManager::NO_BUTTON) == 0) {
163
cModel.removeAllMarks();
164
BookList().removeFileName(book->fileName());
166
cModel.removeBook(book);
167
if (cModel.paragraphsNumber() == 0) {
170
size_t index = startCursor().paragraphCursor().index();
171
if (index >= cModel.paragraphsNumber()) {
172
index = cModel.paragraphsNumber() - 1;
174
while (!((ZLTextTreeParagraph*)cModel[index])->parent()->isOpen()) {
177
gotoParagraph(index);
179
rebuildPaintInfo(true);
180
application().refreshWindow();
184
void CollectionView::removeTag(const std::string &tag) {
189
ZLResourceKey boxKey("removeTagBox");
190
const std::string message =
191
ZLStringUtil::printf(ZLDialogManager::dialogMessage(boxKey), tag);
192
enum { REMOVE_TAG, REMOVE_SUBTREE, DONT_REMOVE } code = DONT_REMOVE;
193
if (myCollection.hasSubtags(tag)) {
194
if (myCollection.hasBooks(tag)) {
195
switch (ZLDialogManager::instance().questionBox(boxKey, message,
196
ZLResourceKey("thisOnly"),
197
ZLResourceKey("withSubtags"),
198
ZLDialogManager::CANCEL_BUTTON
204
code = REMOVE_SUBTREE;
208
if (ZLDialogManager::instance().questionBox(boxKey, message,
209
ZLResourceKey("withSubtags"), ZLDialogManager::CANCEL_BUTTON) == 0) {
210
code = REMOVE_SUBTREE;
214
if (ZLDialogManager::instance().questionBox(boxKey, message,
215
ZLDialogManager::YES_BUTTON, ZLDialogManager::CANCEL_BUTTON) == 0) {
219
if (code != DONT_REMOVE) {
220
collectionModel().removeAllMarks();
221
myCollection.removeTag(tag, code == REMOVE_SUBTREE);
223
application().refreshWindow();
270
227
CollectionModel &CollectionView::collectionModel() {
271
228
return (CollectionModel&)*model();