Symbian fixes: full screen mode, dialog softkeys.
[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     qDebug() << "LibraryDialog::onRead";
135     QModelIndex current = sortedLibrary->mapToSource(list->currentIndex());
136     if (current.isValid()) {
137         Library::instance()->setNowReading(current);
138     }
139 }
140
141 void LibraryDialog::onDetails()
142 {
143     onItemActivated(list->currentIndex());
144 }
145
146 #endif // Q_WS_MAEMO_5
147
148 void LibraryDialog::onItemActivated(const QModelIndex &index)
149 {
150     qDebug() << "LibraryDialog::onItemActivated";
151     QModelIndex libraryIndex = sortedLibrary->mapToSource(index);
152     Book *book = Library::instance()->book(libraryIndex);
153     (new InfoDialog(book, this))->exec();
154 }
155
156 QString LibraryDialog::createItemText(const Book *book)
157 {
158     QString text = book->title + "\n";
159     if (book->creators.size()) {
160         text += book->creators[0];
161         for (int i = 1; i < book->creators.size(); i++) {
162             text += ", " + book->creators[i];
163         }
164     }
165     return text;
166 }
167
168 void LibraryDialog::onCurrentBookChanged()
169 {
170     close();
171 }
172
173 void LibraryDialog::setSelected(const QModelIndex &libraryIndex)
174 {
175     QModelIndex sortedIndex = sortedLibrary->mapFromSource(libraryIndex);
176     list->selectionModel()->clearSelection();
177     if (sortedIndex.isValid()) {
178         list->selectionModel()->select(sortedIndex,
179                                        QItemSelectionModel::Select);
180         list->setCurrentIndex(sortedIndex);
181     }
182 }
183
184 QModelIndex LibraryDialog::selected() const
185 {
186     QModelIndexList selectedItems = list->selectionModel()->selectedIndexes();
187     if (selectedItems.size()) {
188         return sortedLibrary->mapToSource(selectedItems[0]);
189     }
190     return QModelIndex();
191 }
192
193 void LibraryDialog::onAddFolder()
194 {
195     Trace t("LibraryDialog::onAddFolder");
196
197     // Get folder name
198     Settings *settings = Settings::instance();
199     QString last =
200             settings->value("lastfolderadded", QDir::homePath()).toString();
201     QString path =
202             QFileDialog::getExistingDirectory(this, tr("Select folder"), last);
203     if (path == "") {
204         return;
205     }
206     settings->setValue("lastfolderadded", QFileInfo(path).absolutePath());
207     qDebug() << path;
208
209     // Add books from folder
210     progress->setWindowTitle(tr("Adding books"));
211     BookFinder *bookFinder = new BookFinder(this);
212     Library *library = Library::instance();
213     connect(bookFinder, SIGNAL(begin(int)), progress, SLOT(setMaximum(int)));
214     connect(bookFinder, SIGNAL(add(const QString &)),
215             this, SLOT(onAddFromFolder(const QString &)));
216     connect(bookFinder, SIGNAL(add(const QString &)),
217             library, SLOT(add(const QString &)));
218     connect(bookFinder, SIGNAL(done(int)),
219             this, SLOT(onAddFromFolderDone(int)));
220     bookFinder->find(path, Library::instance()->bookPaths());
221 }
222
223 void LibraryDialog::onAddFromFolderDone(int added)
224 {
225     QString msg;
226
227     switch (added) {
228     case 0: msg = tr("No new books found"); break;
229     case 1: msg = tr("One book added"); break;
230     default: msg = tr("%1 books added").arg(added);
231     }
232
233     progress->reset();
234     qDebug() << "LibraryDialog::onRefreshDone:" << msg;
235 #ifdef Q_WS_MAEMO_5
236     QMaemo5InformationBox::information(this, msg);
237 #else
238     QMessageBox::information(this, tr("Done adding books"), msg);
239 #endif
240 }
241
242 void LibraryDialog::onAddFromFolder(const QString &path)
243 {
244     progress->setLabelText(QFileInfo(path).fileName());
245     progress->setValue(progress->value() + 1);
246 }
247
248 void LibraryDialog::onSearch()
249 {
250     int ret = searchDialog->exec();
251     if (ret != QDialog::Accepted) {
252         return;
253     }
254     progress->setLabelText(tr("Searching Project Gutenberg"));
255     progress->showWait();
256     Search::instance()->start(searchDialog->query());
257 }
258
259 void LibraryDialog::showSearchResults()
260 {
261     progress->reset();
262     QList<Search::Result> results = Search::instance()->results();
263     if (results.count() == 0) {
264         QMessageBox::information(this, tr("Search results"),
265                                  tr("No books found"));
266         return;
267     }
268
269     SearchResultsDialog *dialog = new SearchResultsDialog(results, this);
270     connect(dialog, SIGNAL(add(const Search::Result &)),
271             this, SLOT(onAddSearchResult(const Search::Result &)));
272     dialog->show();
273 }