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