Improve bookmark management.
[dorian] / librarydialog.cpp
1 #include <QtGui>
2 #include <QDebug>
3 #include <QFileInfo>
4 #include <QDir>
5 #include <QModelIndex>
6
7 #ifdef Q_WS_MAEMO_5
8 #include <QtMaemo5/QMaemo5InformationBox>
9 #endif
10
11 #include "librarydialog.h"
12 #include "library.h"
13 #include "sortedlibrary.h"
14 #include "book.h"
15 #include "infodialog.h"
16 #include "settings.h"
17 #include "listwindow.h"
18 #include "listview.h"
19 #include "trace.h"
20 #include "bookfinder.h"
21
22 LibraryDialog::LibraryDialog(QWidget *parent): ListWindow(parent)
23 {
24     setWindowTitle(tr("Library"));
25
26     // Add actions
27
28 #ifndef Q_WS_MAEMO_5
29     addItemAction(tr("Details"), this, SLOT(onDetails()));
30     addItemAction(tr("Read"), this, SLOT(onRead()));
31     addItemAction(tr("Delete"), this, SLOT(onRemove()));
32 #endif // ! Q_WS_MAEMO_5
33
34     addAction(tr("Add book"), this, SLOT(onAdd()));
35     addAction(tr("Add books from folder"), this, SLOT(onAddFolder()));
36
37     // Create and add list view
38     list = new ListView(this);
39     sortedLibrary = new SortedLibrary(this);
40     list->setModel(sortedLibrary);
41     list->setSelectionMode(QAbstractItemView::SingleSelection);
42     list->setSpacing(1);
43     Library *library = Library::instance();
44     QModelIndex current = library->nowReading();
45     setSelected(current);
46     addList(list);
47
48     progress = new QProgressDialog(tr("Adding books"), "", 0, 0, this);
49     progress->reset();
50     progress->setMinimumDuration(0);
51     progress->setWindowModality(Qt::WindowModal);
52     progress->setCancelButton(0);
53
54     connect(Library::instance(), SIGNAL(nowReadingChanged()),
55             this, SLOT(onCurrentBookChanged()));
56     connect(Library::instance(),
57             SIGNAL(rowsInserted(const QModelIndex &, int, int)),
58             this,
59             SLOT(onBookAdded()));
60     connect(list, SIGNAL(activated(const QModelIndex &)),
61             this, SLOT(onItemActivated(const QModelIndex &)));
62 }
63
64 void LibraryDialog::onAdd()
65 {
66     Library *library = Library::instance();
67
68     // Figure out directory to show
69     QString lastDir = Settings::instance()->value("lastdir").toString();
70     if (lastDir == "") {
71         lastDir = QDir::homePath();
72     }
73
74     // Get book file name
75     QString path = QFileDialog::getOpenFileName(this, tr("Add Book"),
76                                                 lastDir, "Books (*.epub)");
77     if (path == "") {
78         return;
79     }
80
81     // Save directory selected
82     Settings::instance()->setValue("lastdir", QFileInfo(path).absolutePath());
83
84     // Add book to library
85     QModelIndex index = library->find(path);
86     if (index.isValid()) {
87 #ifdef Q_WS_MAEMO_5
88         QMaemo5InformationBox::information(this,
89             tr("This book is already in the library"),
90             QMaemo5InformationBox::DefaultTimeout);
91 #else
92         (void)QMessageBox::information(this, tr("Dorian"),
93             tr("This book is already in the library"), QMessageBox::Ok);
94 #endif // Q_WS_MAEMO_5
95         setSelected(index);
96     }
97     else {
98         library->add(path);
99     }
100 }
101
102 void LibraryDialog::onBookAdded()
103 {
104     Library *library = Library::instance();
105     setSelected(library->index(library->rowCount() - 1));
106 }
107
108 #ifndef Q_WS_MAEMO_5
109
110 void LibraryDialog::onRemove()
111 {
112     QModelIndex current = sortedLibrary->mapToSource(list->currentIndex());
113     if (current.isValid()) {
114         Book *currentBook = Library::instance()->book(current);
115         QString title = currentBook->name();
116         if (QMessageBox::Yes ==
117             QMessageBox::question(this, tr("Delete book"),
118                 tr("Delete book \"%1\" from library?").
119                     arg(currentBook->shortName()),
120                 QMessageBox::Yes | QMessageBox::No)) {
121             Library::instance()->remove(current);
122         }
123     }
124 }
125
126 void LibraryDialog::onRead()
127 {
128     qDebug() << "LibraryDialog::onRead";
129     QModelIndex current = sortedLibrary->mapToSource(list->currentIndex());
130     if (current.isValid()) {
131         Library::instance()->setNowReading(current);
132     }
133 }
134
135 void LibraryDialog::onDetails()
136 {
137     onItemActivated(list->currentIndex());
138 }
139
140 #endif // Q_WS_MAEMO_5
141
142 void LibraryDialog::onItemActivated(const QModelIndex &index)
143 {
144     qDebug() << "LibraryDialog::onItemActivated";
145     QModelIndex libraryIndex = sortedLibrary->mapToSource(index);
146     Book *book = Library::instance()->book(libraryIndex);
147     (new InfoDialog(book, this))->exec();
148 }
149
150 QString LibraryDialog::createItemText(const Book *book)
151 {
152     QString text = book->title + "\n";
153     if (book->creators.size()) {
154         text += book->creators[0];
155         for (int i = 1; i < book->creators.size(); i++) {
156             text += ", " + book->creators[i];
157         }
158     }
159     return text;
160 }
161
162 void LibraryDialog::onCurrentBookChanged()
163 {
164     close();
165 }
166
167 void LibraryDialog::setSelected(const QModelIndex &libraryIndex)
168 {
169     QModelIndex sortedIndex = sortedLibrary->mapFromSource(libraryIndex);
170     list->selectionModel()->clearSelection();
171     if (sortedIndex.isValid()) {
172         list->selectionModel()->select(sortedIndex,
173                                        QItemSelectionModel::Select);
174         list->setCurrentIndex(sortedIndex);
175     }
176 }
177
178 QModelIndex LibraryDialog::selected() const
179 {
180     QModelIndexList selectedItems = list->selectionModel()->selectedIndexes();
181     if (selectedItems.size()) {
182         return sortedLibrary->mapToSource(selectedItems[0]);
183     }
184     return QModelIndex();
185 }
186
187 void LibraryDialog::onAddFolder()
188 {
189     Trace t("LibraryDialog::onAddFolder");
190
191     // Get folder name
192     Settings *settings = Settings::instance();
193     QString last =
194             settings->value("lastfolderadded", QDir::homePath()).toString();
195     QString path =
196             QFileDialog::getExistingDirectory(this, tr("Select folder"), last);
197     if (path == "") {
198         return;
199     }
200     settings->setValue("lastfolderadded", QFileInfo(path).absolutePath());
201     qDebug() << path;
202
203     // Add books from folder
204     progress->setWindowTitle(tr("Adding books"));
205     BookFinder *bookFinder = new BookFinder(this);
206     Library *library = Library::instance();
207     connect(bookFinder, SIGNAL(begin(int)), progress, SLOT(setMaximum(int)));
208     connect(bookFinder, SIGNAL(add(const QString &)),
209             this, SLOT(onAddFromFolder(const QString &)));
210     connect(bookFinder, SIGNAL(add(const QString &)),
211             library, SLOT(add(const QString &)));
212     connect(bookFinder, SIGNAL(done(int)),
213             this, SLOT(onAddFromFolderDone(int)));
214     bookFinder->find(path, Library::instance()->bookPaths());
215 }
216
217 void LibraryDialog::onAddFromFolderDone(int added)
218 {
219     QString msg;
220
221     switch (added) {
222     case 0: msg = tr("No new books found"); break;
223     case 1: msg = tr("One new book added"); break;
224     default: msg = tr("%1 new books added").arg(added);
225     }
226
227     progress->reset();
228     qDebug() << "LibraryDialog::onRefreshDone:" << msg;
229 #ifdef Q_WS_MAEMO_5
230     QMaemo5InformationBox::information(this, msg);
231 #else
232     // FIXME
233 #endif
234 }
235
236 void LibraryDialog::onAddFromFolder(const QString &path)
237 {
238     progress->setLabelText(QFileInfo(path).fileName());
239     progress->setValue(progress->value() + 1);
240 }