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