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