~ubuntu-branches/ubuntu/vivid/fbreader/vivid-proposed

« back to all changes in this revision

Viewing changes to fbreader/src/fbreader/CollectionView.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Eugene V. Lyubimkin
  • Date: 2008-06-17 23:01:53 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20080617230153-a16c45tq69j8geru
Tags: 0.8.17-11
* debian/control:
  - Enhanced all ZLibrary descriptions, not the main one.
  - Done some renaming to use canonical names of libraries and toolkits in
    decriptions, as suggested by developers-reference:
    'qt' -> 'Qt', 'gtk' -> 'GTK+', 'zlibrary' -> 'ZLibrary'.
  - Bump 'Depends' on quilt to (>= 0.24).
* debian/rules:
  - Included quilt makefile instead of quilt makefile instead
    of copy&paste'ing it.
* debian/fbreader.links:
  - Added this file to relay on dh_link's work instead of using 'ln -sf'
    directly in the debian/rules.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 * 02110-1301, USA.
18
18
 */
19
19
 
20
 
#include <ZLibrary.h>
21
 
#include <ZLFileImage.h>
22
 
#include <ZLDialogManager.h>
23
20
#include <ZLOptionsDialog.h>
24
21
#include <ZLStringUtil.h>
25
22
 
26
 
#include <ZLTextModel.h>
27
 
#include <ZLTextParagraph.h>
28
 
#include <ZLTextParagraphCursor.h>
29
 
 
30
23
#include "CollectionView.h"
 
24
#include "CollectionModel.h"
31
25
#include "FBReader.h"
32
26
#include "BookInfoDialog.h"
33
27
 
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"
39
 
 
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";
44
 
 
45
 
class CollectionModel : public ZLTextTreeModel {
46
 
 
47
 
public:
48
 
        CollectionModel(BookCollection &collection);
49
 
        ~CollectionModel();
50
 
 
51
 
        BookDescriptionPtr bookByParagraphNumber(int num);
52
 
        int paragraphNumberByBook(BookDescriptionPtr book);
53
 
 
54
 
        void update();
55
 
 
56
 
private:
57
 
        void build();
58
 
 
59
 
        void insertText(FBTextKind kind, const std::string &text);
60
 
        void insertImage(const std::string &id);
61
 
 
62
 
private:
63
 
        BookCollection &myCollection;
64
 
 
65
 
        ZLImageMap myImageMap;
66
 
        std::map<ZLTextParagraph*,BookDescriptionPtr> myParagraphToBook;
67
 
        std::map<BookDescriptionPtr,int> myBookToParagraph;
68
 
};
69
 
 
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);
76
 
}
77
 
 
78
 
CollectionModel::~CollectionModel() {
79
 
}
80
 
 
81
 
BookDescriptionPtr CollectionModel::bookByParagraphNumber(int num) {
82
 
        if ((num < 0) || ((int)paragraphsNumber() <= num)) {
83
 
                return 0;
84
 
        }
85
 
        std::map<ZLTextParagraph*,BookDescriptionPtr>::iterator it = myParagraphToBook.find((*this)[num]);
86
 
        return (it != myParagraphToBook.end()) ? it->second : 0;
87
 
}
88
 
 
89
 
int CollectionModel::paragraphNumberByBook(BookDescriptionPtr book) {
90
 
        std::map<BookDescriptionPtr,int>::iterator it = myBookToParagraph.find(book);
91
 
        return (it != myBookToParagraph.end()) ? it->second : -1;
92
 
}
93
 
 
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;
103
 
 
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);
117
 
                                }
118
 
                                ZLTextTreeParagraph *bookParagraph = createParagraph(
119
 
                                        (sequenceParagraph == 0) ? authorParagraph : sequenceParagraph
120
 
                                );
121
 
                                insertText(LIBRARY_BOOK_ENTRY, (*jt)->title());
122
 
                                insertImage(BOOK_INFO_IMAGE_ID);
123
 
                                if (myCollection.isBookExternal(*jt)) {
124
 
                                        insertImage(DELETE_IMAGE_ID);
125
 
                                }
126
 
                                myParagraphToBook[bookParagraph] = *jt;
127
 
                                myBookToParagraph[*jt] = paragraphsNumber() - 1;
128
 
                        }
129
 
                }
130
 
        }
131
 
}
132
 
 
133
 
void CollectionModel::update() {
134
 
        myParagraphToBook.clear();
135
 
        myBookToParagraph.clear();
136
 
        for (int i = paragraphsNumber() - 1; i >= 0; --i) {
137
 
                removeParagraph(i);
138
 
        }
139
 
        build();
140
 
}
141
 
 
142
 
void CollectionModel::insertText(FBTextKind kind, const std::string &text) {
143
 
        addControl(kind, true);
144
 
        addText(text);
145
 
}
146
 
 
147
 
void CollectionModel::insertImage(const std::string &id) {
148
 
        addFixedHSpace(1);
149
 
        addImage(id, myImageMap, 0);
150
 
}
151
 
 
152
 
CollectionView::CollectionView(FBReader &reader, shared_ptr<ZLPaintContext> context) : FBView(reader, context), myUpdateModel(true) {
153
 
        setModel(new CollectionModel(myCollection));
 
29
 
 
30
static const std::string LIBRARY = "Library";
 
31
 
 
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),
 
35
        myUpdateModel(true) {
 
36
        setModel(new CollectionModel(*this, myCollection));
 
37
        myShowTags = ShowTagsOption.value();
 
38
        myShowAllBooksList = ShowAllBooksTagOption.value();
154
39
}
155
40
 
156
41
CollectionView::~CollectionView() {
169
54
}
170
55
 
171
56
const std::string &CollectionView::caption() const {
172
 
        static const std::string LIBRARY = "Library";
173
 
        return LIBRARY;
 
57
        return ZLResource::resource("library")["caption"].value();
174
58
}
175
59
 
176
60
void CollectionView::selectBook(BookDescriptionPtr book) {
181
65
                setModel(oldModel);
182
66
                myUpdateModel = false;
183
67
        }
184
 
        int toSelect = collectionModel().paragraphNumberByBook(book);
185
 
        if (toSelect >= 0) {
186
 
                highlightParagraph(toSelect);
187
 
                gotoParagraph(toSelect);
 
68
        collectionModel().removeAllMarks();
 
69
        const std::vector<int> &toSelect = collectionModel().paragraphNumbersByBook(book);
 
70
        for (std::vector<int>::const_iterator it = toSelect.begin(); it != toSelect.end(); ++it) {
 
71
                highlightParagraph(*it);
 
72
        }
 
73
        if (!toSelect.empty()) {
 
74
                gotoParagraph(toSelect[toSelect.size() - 1]);
188
75
                scrollPage(false, ZLTextView::SCROLL_PERCENTAGE, 40);
189
76
        }
190
77
}
191
78
 
192
79
void CollectionView::paint() {
 
80
        if ((myShowTags != ShowTagsOption.value()) ||
 
81
                        (myShowAllBooksList != ShowAllBooksTagOption.value())) {
 
82
                myShowTags = ShowTagsOption.value();
 
83
                myShowAllBooksList = ShowAllBooksTagOption.value();
 
84
                myUpdateModel = true;
 
85
        }
193
86
        if (myUpdateModel) {
194
87
                shared_ptr<ZLTextModel> oldModel = model();
195
88
                setModel(0);
212
105
                }
213
106
                const ZLTextImageElement &imageElement = (ZLTextImageElement&)element;
214
107
 
215
 
                BookDescriptionPtr book = collectionModel().bookByParagraphNumber(imageArea->ParagraphNumber);
216
 
                if (book.isNull()) {
 
108
                const std::string &id = imageElement.id();
 
109
 
 
110
                if (id == CollectionModel::BookInfoImageId) {
 
111
                        editBookInfo(collectionModel().bookByParagraphNumber(imageArea->ParagraphNumber));
 
112
                        return true;
 
113
                } else if (id == CollectionModel::RemoveBookImageId) {
 
114
                        removeBook(collectionModel().bookByParagraphNumber(imageArea->ParagraphNumber));
 
115
                        return true;
 
116
                } else if (id == CollectionModel::RemoveTagImageId) {
 
117
                        removeTag(collectionModel().tagByParagraphNumber(imageArea->ParagraphNumber));
 
118
                        return true;
 
119
                } else if (id == CollectionModel::TagInfoImageId) {
 
120
                        editTagInfo(collectionModel().tagByParagraphNumber(imageArea->ParagraphNumber));
 
121
                        return true;
 
122
                } else {
217
123
                        return false;
218
124
                }
219
 
 
220
 
                if (imageElement.id() == BOOK_INFO_IMAGE_ID) {
221
 
                        if (BookInfoDialog(myCollection, book->fileName()).dialog().run()) {
222
 
                                myCollection.rebuild(false);
223
 
                                myUpdateModel = true;
224
 
                                selectBook(book);
225
 
                                application().refreshWindow();
226
 
                        }
227
 
                        return true;
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);
241
 
                                } else {
242
 
                                        collectionModel().removeParagraph(imageArea->ParagraphNumber);
243
 
                                }
244
 
                                if (collectionModel().paragraphsNumber() == 0) {
245
 
                                        setStartCursor(0);
246
 
                                }
247
 
                                rebuildPaintInfo(true);
248
 
                                application().refreshWindow();
249
 
                        }
250
 
                        return true;
251
 
                }
252
 
                return false;
253
125
        }
254
126
 
255
127
        int index = paragraphIndexByCoordinate(y);
267
139
        return false;
268
140
}
269
141
 
 
142
void CollectionView::editBookInfo(BookDescriptionPtr book) {
 
143
        if (!book.isNull() && BookInfoDialog(myCollection, book->fileName()).dialog().run()) {
 
144
                myCollection.rebuild(false);
 
145
                myUpdateModel = true;
 
146
                selectBook(book);
 
147
                application().refreshWindow();
 
148
        }
 
149
}
 
150
 
 
151
void CollectionView::removeBook(BookDescriptionPtr book) {
 
152
        if (book.isNull()) {
 
153
                return;
 
154
        }
 
155
 
 
156
        CollectionModel &cModel = collectionModel();
 
157
 
 
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());
 
165
                
 
166
                cModel.removeBook(book);
 
167
                if (cModel.paragraphsNumber() == 0) {
 
168
                        setStartCursor(0);
 
169
                } else {
 
170
                        size_t index = startCursor().paragraphCursor().index();
 
171
                        if (index >= cModel.paragraphsNumber()) {
 
172
                                index = cModel.paragraphsNumber() - 1;
 
173
                        }
 
174
                        while (!((ZLTextTreeParagraph*)cModel[index])->parent()->isOpen()) {
 
175
                                --index;
 
176
                        }
 
177
                        gotoParagraph(index);
 
178
                }
 
179
                rebuildPaintInfo(true);
 
180
                application().refreshWindow();
 
181
        }
 
182
}
 
183
 
 
184
void CollectionView::removeTag(const std::string &tag) {
 
185
        if (tag.empty()) {
 
186
                return;
 
187
        }
 
188
 
 
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
 
199
                                                        )) {
 
200
                                case 0:
 
201
                                        code = REMOVE_TAG;
 
202
                                        break;
 
203
                                case 1:
 
204
                                        code = REMOVE_SUBTREE;
 
205
                                        break;
 
206
                        }
 
207
                } else {
 
208
                        if (ZLDialogManager::instance().questionBox(boxKey, message,
 
209
                                ZLResourceKey("withSubtags"), ZLDialogManager::CANCEL_BUTTON) == 0) {
 
210
                                code = REMOVE_SUBTREE;
 
211
                        }
 
212
                }
 
213
        } else {
 
214
                if (ZLDialogManager::instance().questionBox(boxKey, message,
 
215
                        ZLDialogManager::YES_BUTTON, ZLDialogManager::CANCEL_BUTTON) == 0) {
 
216
                        code = REMOVE_TAG;
 
217
                }
 
218
        }
 
219
        if (code != DONT_REMOVE) {
 
220
                collectionModel().removeAllMarks();
 
221
                myCollection.removeTag(tag, code == REMOVE_SUBTREE);
 
222
                updateModel();
 
223
                application().refreshWindow();
 
224
        }
 
225
}
 
226
 
270
227
CollectionModel &CollectionView::collectionModel() {
271
228
        return (CollectionModel&)*model();
272
229
}