ListWindow starts working again.
[dorian] / model / library.cpp
1 #include "library.h"
2 #include "book.h"
3 #include "trace.h"
4 #include "bookdb.h"
5
6 static const char *DORIAN_VERSION =
7 #include "pkg/version.txt"
8 ;
9
10 static Library *theInstance = 0;
11
12 Library::Library(QObject *parent): QAbstractListModel(parent)
13 {
14 }
15
16 Library::~Library()
17 {
18     clear();
19 }
20
21 Library *Library::instance()
22 {
23     if (!theInstance) {
24         theInstance = new Library();
25     }
26     return theInstance;
27 }
28
29 int Library::rowCount(const QModelIndex &parent) const
30 {
31     if (parent.isValid()) {
32         return 0;
33     } else {
34         return mBooks.size();
35     }
36 }
37
38 QVariant Library::data(const QModelIndex &index, int role) const
39 {
40     TRACE;
41
42     QVariant ret;
43     if (!index.isValid()) {
44         return ret;
45     }
46
47     switch (role) {
48     case Qt::DisplayRole:
49         qDebug() << mBooks[index.row()]->name();
50         ret = mBooks[index.row()]->name();
51         break;
52     case Qt::DecorationRole:
53         qDebug() << "(cover)";
54         ret.setValue(mBooks[index.row()]->cover);
55         break;
56     default:
57         ;
58     }
59
60     return ret;
61 }
62
63 Book *Library::book(const QModelIndex &index)
64 {
65     if (index.isValid()) {
66         if ((index.row() >= 0) && (index.row() < mBooks.size())) {
67             return mBooks[index.row()];
68         } else {
69             qCritical() << "Library::book: Bad index" << index.row();
70         }
71     }
72     return 0;
73 }
74
75 void Library::close()
76 {
77     delete theInstance;
78     theInstance = 0;
79 }
80
81 void Library::load()
82 {
83     TRACE;
84
85     clear();
86     QStringList books = BookDb::instance()->books();
87     emit beginLoad(books.size());
88
89     foreach(QString path, books) {
90         emit loading(path);
91         Book *book = new Book(path);
92         connect(book, SIGNAL(opened(const QString &)),
93                 this, SLOT(onBookOpened(const QString &)));
94         // book->load();
95         mBooks.append(book);
96     }
97
98     QSettings settings;
99     QString currentPath = settings.value("lib/nowreading").toString();
100     mNowReading = find(currentPath);
101     emit endLoad();
102 }
103
104 void Library::save()
105 {
106     TRACE;
107     QSettings settings;
108     Book *currentBook = book(mNowReading);
109     settings.setValue("lib/nowreading",
110                       currentBook? currentBook->path(): QString());
111 }
112
113 bool Library::add(const QString &path)
114 {
115     TRACE;
116     if (path == "") {
117         qCritical() << "Library::add: Empty path";
118         return false;
119     }
120     if (find(path).isValid()) {
121         qDebug() << "Book already exists in library";
122         return false;
123     }
124     int size = mBooks.size();
125     beginInsertRows(QModelIndex(), size, size);
126     Book *book = new Book(path);
127     book->peek();
128     mBooks.append(book);
129     save();
130     endInsertRows();
131     return true;
132 }
133
134 void Library::remove(const QModelIndex &index)
135 {
136     TRACE;
137     Book *toRemove = book(index);
138     if (!toRemove) {
139         return;
140     }
141     if (index == mNowReading) {
142         mNowReading = QModelIndex();
143         emit nowReadingChanged();
144     }
145     toRemove->remove();
146     int row = index.row();
147     beginRemoveRows(QModelIndex(), row, row);
148     mBooks.removeAt(row);
149     save();
150     endRemoveRows();
151     delete toRemove;
152 }
153
154 void Library::remove(const QString &path)
155 {
156     remove(find(path));
157 }
158
159 QModelIndex Library::nowReading() const
160 {
161     return mNowReading;
162 }
163
164 void Library::setNowReading(const QModelIndex &index)
165 {
166     mNowReading = index;
167     save();
168     emit nowReadingChanged();
169 }
170
171 void Library::clear()
172 {
173     for (int i = 0; i < mBooks.size(); i++) {
174         delete mBooks[i];
175     }
176     mBooks.clear();
177     mNowReading = QModelIndex();
178 }
179
180 QModelIndex Library::find(QString path) const
181 {
182     if (path != "") {
183         QString absolutePath = QFileInfo(path).absoluteFilePath();
184         for (int i = 0; i < mBooks.size(); i++) {
185             if (absolutePath == mBooks[i]->path()) {
186                 return index(i);
187             }
188         }
189     }
190     return QModelIndex();
191 }
192
193 QModelIndex Library::find(const Book *book) const
194 {
195     if (book) {
196         for (int i = 0; i < mBooks.size(); i++) {
197             if (book == mBooks[i]) {
198                 return index(i);
199             }
200         }
201     }
202     return QModelIndex();
203 }
204
205 void Library::onBookOpened(const QString &path)
206 {
207     TRACE;
208     QModelIndex index = find(path);
209     if (index.isValid()) {
210         emit dataChanged(index, index);
211     }
212 }
213
214 QStringList Library::bookPaths()
215 {
216     QStringList ret;
217     foreach (Book *book, mBooks) {
218         ret.append(book->path());
219     }
220     return ret;
221 }
222
223 void Library::upgrade()
224 {
225     TRACE;
226     QSettings settings;
227     QString oldVersion = settings.value("lib/version").toString();
228     if (oldVersion.isEmpty()) {
229         int size = settings.value("lib/size").toInt();
230         emit beginUpgrade(size);
231         for (int i = 0; i < size; i++) {
232             QString key = "lib/book" + QString::number(i);
233             QString path = settings.value(key).toString();
234             emit upgrading(path);
235             Book *book = new Book(path);
236             book->upgrade();
237         }
238     } else {
239         emit beginUpgrade(0);
240     }
241     settings.setValue("lib/version", QString(DORIAN_VERSION));
242     emit endUpgrade();
243 }