Make full screen switching more robust. Add in/out traces.
[dorian] / library.cpp
1 #include <QSettings>
2 #include <QDebug>
3 #include <QFileInfo>
4
5 #include "library.h"
6 #include "book.h"
7 #include "trace.h"
8
9 Library *Library::mInstance = 0;
10
11 Library::Library(QObject *parent): QAbstractListModel(parent)
12 {
13     load();
14 }
15
16 Library::~Library()
17 {
18     clear();
19 }
20
21 Library *Library::instance()
22 {
23     if (!mInstance) {
24         mInstance = new Library();
25     }
26     return mInstance;
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     if (!index.isValid()) {
41         return QVariant();
42     }
43
44     switch (role) {
45     case Qt::DisplayRole:
46         return mBooks[index.row()]->name();
47     default:
48         return QVariant();
49     }
50 }
51
52 Book *Library::book(const QModelIndex &index)
53 {
54     if (index.isValid()) {
55         if ((index.row() >= 0) && (index.row() < mBooks.size())) {
56             return mBooks[index.row()];
57         } else {
58             qCritical() << "*** Library::book: Bad index" << index.row();
59         }
60     }
61     return 0;
62 }
63
64 void Library::close()
65 {
66     delete mInstance;
67     mInstance = 0;
68 }
69
70 void Library::load()
71 {
72     QSettings settings;
73     clear();
74     int size = settings.value("lib/size").toInt();
75     for (int i = 0; i < size; i++) {
76         QString key = "lib/book" + QString::number(i);
77         QString path = settings.value(key).toString();
78         Book *book = new Book(path);
79         book->load();
80         mBooks.append(book);
81     }
82     QString currentPath = settings.value("lib/nowreading").toString();
83     mNowReading = find(currentPath);
84 }
85
86 void Library::save()
87 {
88     QSettings settings;
89     settings.setValue("lib/size", mBooks.size());
90     for (int i = 0; i < mBooks.size(); i++) {
91         QString key = "lib/book" + QString::number(i);
92         settings.setValue(key, mBooks[i]->path());
93     }
94     Book *currentBook = book(mNowReading);
95     settings.setValue("lib/nowreading",
96                       currentBook? currentBook->path(): QString());
97 }
98
99 bool Library::add(QString path)
100 {
101     Trace t("Library::add " + path);
102     if (path == "") {
103         qCritical() << "*** Library::add: Empty path";
104         return false;
105     }
106     if (find(path).isValid()) {
107         t.trace("Book already exists in library");
108         return false;
109     }
110     int size = mBooks.size();
111     Book *book = new Book(path);
112     beginInsertRows(QModelIndex(), size, size);
113     mBooks.append(book);
114     save();
115     endInsertRows();
116     return true;
117 }
118
119 void Library::remove(const QModelIndex &index)
120 {
121     Book *toRemove = book(index);
122     if (!toRemove) {
123         return;
124     }
125     int row = index.row();
126     beginRemoveRows(QModelIndex(), row, row);
127     mBooks.removeAt(row);
128     save();
129     endRemoveRows();
130     if (index == mNowReading) {
131         mNowReading = QModelIndex();
132         emit nowReadingChanged();
133     }
134     delete toRemove;
135 }
136
137 QModelIndex Library::nowReading() const
138 {
139     return mNowReading;
140 }
141
142 void Library::setNowReading(const QModelIndex &index)
143 {
144     mNowReading = index;
145     save();
146     emit nowReadingChanged();
147 }
148
149 void Library::clear()
150 {
151     for (int i = 0; i < mBooks.size(); i++) {
152         delete mBooks[i];
153     }
154     mBooks.clear();
155     mNowReading = QModelIndex();
156 }
157
158 QModelIndex Library::find(QString path) const
159 {
160     if (path != "") {
161         QString absolutePath = QFileInfo(path).absoluteFilePath();
162         for (int i = 0; i < mBooks.size(); i++) {
163             if (absolutePath == mBooks[i]->path()) {
164                 return index(i);
165             }
166         }
167     }
168     return QModelIndex();
169 }
170
171 QModelIndex Library::find(const Book *book) const
172 {
173     if (book) {
174         for (int i = 0; i < mBooks.size(); i++) {
175             if (book == mBooks[i]) {
176                 return index(i);
177             }
178         }
179     }
180     return QModelIndex();
181 }