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