Local library: Basic setup working

A local books database is maintained at `/data/onboard/.inkbox/LocalLibrary.db`. It contains compressed JSON read by the GUI.

URGENT TODO: Fix `*** Error in '/mnt/onboard/.adds/inkbox/inkbox-bin': double free or corruption (out): 0x00648708 ***` error whenever we try to delete localLibraryWidget
This commit is contained in:
Nicolas Mailloux 2022-06-25 20:12:50 -04:00
parent 8bfc529498
commit 4a104522f5
8 changed files with 193 additions and 22 deletions

View file

@ -282,6 +282,16 @@ namespace {
return quoteNumber; return quoteNumber;
return 0; return 0;
} }
void writeFile(QString filename, QString content) {
QFile file(filename);
if(file.open(QIODevice::ReadWrite)) {
QTextStream stream(&file);
stream << content;
}
else {
QString function = __func__; log(function + ": Failed to write string '" + content + "' to file '" + filename + "'", "functions");
}
}
void string_writeconfig(std::string file, std::string config_option) { void string_writeconfig(std::string file, std::string config_option) {
std::ofstream fhandler; std::ofstream fhandler;
fhandler.open(file); fhandler.open(file);

View file

@ -12,6 +12,12 @@ localLibraryWidget::localLibraryWidget(QWidget *parent) :
ui->setupUi(this); ui->setupUi(this);
this->setFont(QFont("u001")); this->setFont(QFont("u001"));
ui->previousPageBtn->setProperty("type", "borderless");
ui->nextPageBtn->setProperty("type", "borderless");
ui->previousPageBtn->setIcon(QIcon(":/resources/chevron-left.png"));
ui->nextPageBtn->setIcon(QIcon(":/resources/chevron-right.png"));
ui->pageNumberLabel->setFont(QFont("Source Serif Pro"));
if(global::deviceID == "n705\n" or global::deviceID == "n905\n") { if(global::deviceID == "n705\n" or global::deviceID == "n905\n") {
buttonsNumber = 4; buttonsNumber = 4;
} }
@ -53,19 +59,22 @@ localLibraryWidget::localLibraryWidget(QWidget *parent) :
// Book icon label // Book icon label
bookIconArray[i] = new QLabel(this); bookIconArray[i] = new QLabel(this);
bookIconArray[i]->setStyleSheet("padding: 20px"); bookIconArray[i]->setStyleSheet("padding: 10px");
// Book button // Book button
bookBtnArray[i] = new QClickableLabel(this); bookBtnArray[i] = new QClickableLabel(this);
bookBtnArray[i]->setObjectName(QString::number(i));
connect(bookBtnArray[i], SIGNAL(bookID(int)), SLOT(btnOpenBook(int)));
bookBtnArray[i]->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); bookBtnArray[i]->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
bookBtnArray[i]->setStyleSheet("color: black; background-color: white; border-radius: 10px; padding: 20px"); bookBtnArray[i]->setStyleSheet("color: black; background-color: white; border-radius: 10px; padding: 10px");
bookBtnArray[i]->setFont(QFont("u001")); bookBtnArray[i]->setFont(QFont("u001"));
horizontalLayout->addWidget(bookIconArray[i]); horizontalLayout->addWidget(bookIconArray[i]);
horizontalLayout->addWidget(bookBtnArray[i]); horizontalLayout->addWidget(bookBtnArray[i]);
ui->booksVerticalLayout->addLayout(horizontalLayout); ui->booksVerticalLayout->addLayout(horizontalLayout);
} }
setupBooksList(); setupDatabase();
setupBooksList(currentPageNumber);
} }
localLibraryWidget::~localLibraryWidget() localLibraryWidget::~localLibraryWidget()
@ -73,10 +82,99 @@ localLibraryWidget::~localLibraryWidget()
delete ui; delete ui;
} }
void localLibraryWidget::setupBooksList() { void localLibraryWidget::setupDatabase() {
for(int i = 1; i <= buttonsNumber; i++) { QString localLibraryDatabasePath = "/mnt/onboard/onboard/.inkbox/LocalLibrary.db";
QPixmap pixmap(":/resources/starred_star.png"); setDefaultWorkDir();
bookIconArray[i]->setPixmap(pixmap.scaled(stdIconWidth, stdIconHeight)); if(!QFile::exists(localLibraryDatabasePath)) {
bookBtnArray[i]->setText("<b>Book " + QString::number(i) + "</b><br>Description"); QStringList booksList;
QDir dir("/mnt/onboard/onboard");
QDirIterator dirIt(dir, QDirIterator::Subdirectories);
while(dirIt.hasNext()) {
dirIt.next();
if(QFileInfo(dirIt.filePath()).isFile()) {
QString suffix = QFileInfo(dirIt.filePath()).suffix();
if(suffix == "epub" || suffix == "EPUB") {
booksList << dirIt.filePath();
} }
}
}
QString prog("sh");
QStringList args;
args << "explore_local_library.sh" << booksList;
QProcess *proc = new QProcess();
proc->setEnvironment((QStringList() << "EXTRACT_COVER=1"));
proc->start(prog, args);
proc->waitForFinished();
QJsonDocument jsonDocument = QJsonDocument::fromJson(proc->readAllStandardOutput());
proc->deleteLater();
// Write database in compressed form, encoded in Base64 format
writeFile(localLibraryDatabasePath, qCompress(jsonDocument.toJson()).toBase64());
}
// Read library database from file
QFile database(localLibraryDatabasePath);
QByteArray data;
if(database.open(QIODevice::ReadOnly)) {
data = database.readAll();
database.close();
}
else {
QString function = __func__; log(function + ": Failed to open local library database file for reading at '" + database.fileName() + "'", className);
}
// Uncompress data from Base64 encoding
databaseJsonDocument = QJsonDocument::fromJson(qUncompress(QByteArray::fromBase64(data)));
// Parse JSON data
databaseJsonObject = databaseJsonDocument.object();
databaseJsonArrayList = databaseJsonObject["database"].toArray();
}
void localLibraryWidget::setupBooksList(int pageNumber) {
idList->clear();
int in = 1;
for(int i = (1 * pageNumber * buttonsNumber) - (buttonsNumber - 1); i <= (1 * pageNumber * buttonsNumber); i++) {
// Read database info for each book and display the corresponding information on each button
QJsonObject jsonObject = databaseJsonArrayList.at(i - 1).toObject();
QString bookTitle = jsonObject["Title"].toString();
QString bookAuthor = jsonObject["Author"].toString();
QString coverPath = jsonObject["CoverPath"].toString();
QString bookID = jsonObject["BookID"].toString();
if(!coverPath.isEmpty()) {
QPixmap pixmap(coverPath);
bookIconArray[in]->setPixmap(pixmap);
}
idList->append(bookID.toInt());
bookBtnArray[in]->setText("<b>" + bookTitle + "</b>" + "<br>" + bookAuthor);
in++;
}
ui->pageNumberLabel->setText("Page " + QString::number(pageNumber) + " <i>of</i> " + "10");
}
void localLibraryWidget::on_previousPageBtn_clicked()
{
currentPageNumber--;
setupBooksList(currentPageNumber);
}
void localLibraryWidget::on_nextPageBtn_clicked()
{
currentPageNumber++;
setupBooksList(currentPageNumber);
}
void localLibraryWidget::openBook(int bookID) {
QJsonObject jsonObject = databaseJsonArrayList.at(bookID - 1).toObject();
QString bookPath = jsonObject["BookPath"].toString();
log("Opening book with ID " + QString::number(bookID) + ", path '" + bookPath + "'", className);
emit openBookSignal(bookPath, false);
}
void localLibraryWidget::btnOpenBook(int buttonNumber) {
int id = idList->at(buttonNumber - 1);
openBook(id);
// localLibraryWidget::close();
} }

View file

@ -24,14 +24,27 @@ public:
int sH; int sH;
int stdIconWidth; int stdIconWidth;
int stdIconHeight; int stdIconHeight;
QJsonDocument databaseJsonDocument;
QJsonObject databaseJsonObject;
QJsonArray databaseJsonArrayList;
int currentPageNumber = 1;
QList<int> idList[4];
private slots: private slots:
void setupBooksList(); void setupDatabase();
void setupBooksList(int pageNumber);
void on_previousPageBtn_clicked();
void on_nextPageBtn_clicked();
void openBook(int id);
void btnOpenBook(int buttonNumber);
private: private:
Ui::localLibraryWidget * ui; Ui::localLibraryWidget * ui;
QLabel * bookIconArray[10]; QLabel * bookIconArray[4];
QClickableLabel * bookBtnArray[10]; QClickableLabel * bookBtnArray[4];
signals:
void openBookSignal(QString bookFile, bool relativePath);
}; };
#endif // LOCALLIBRARYWIDGET_H #endif // LOCALLIBRARYWIDGET_H

View file

@ -33,12 +33,50 @@
<number>0</number> <number>0</number>
</property> </property>
<item> <item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="3">
<widget class="QLabel" name="pageNumberLabel">
<property name="text">
<string>Page</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="localLibraryLabel"> <widget class="QLabel" name="localLibraryLabel">
<property name="text"> <property name="text">
<string>&lt;b&gt;Local library&lt;/b&gt;</string> <string>&lt;b&gt;Local library&lt;/b&gt;</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="2">
<widget class="QPushButton" name="previousPageBtn">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="0" column="1">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="4">
<widget class="QPushButton" name="nextPageBtn">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item> <item>
<layout class="QVBoxLayout" name="booksVerticalLayout"> <layout class="QVBoxLayout" name="booksVerticalLayout">
<property name="sizeConstraint"> <property name="sizeConstraint">

View file

@ -934,7 +934,7 @@ void MainWindow::on_libraryButton_clicked()
ui->libraryButton->setIcon(QIcon(":/resources/online-library-inverted.png")); ui->libraryButton->setIcon(QIcon(":/resources/online-library-inverted.png"));
// Create widget // Create widget
libraryWidgetWindow = new libraryWidget(); libraryWidget * libraryWidgetWindow = new libraryWidget();
connect(libraryWidgetWindow, SIGNAL(destroyed(QObject*)), SLOT(resetFullWindow())); connect(libraryWidgetWindow, SIGNAL(destroyed(QObject*)), SLOT(resetFullWindow()));
libraryWidgetWindow->setAttribute(Qt::WA_DeleteOnClose); libraryWidgetWindow->setAttribute(Qt::WA_DeleteOnClose);
ui->stackedWidget->insertWidget(3, libraryWidgetWindow); ui->stackedWidget->insertWidget(3, libraryWidgetWindow);
@ -996,8 +996,9 @@ void MainWindow::resetWifiIconClickedWhileReconnecting() {
} }
void MainWindow::setupLocalLibraryWidget() { void MainWindow::setupLocalLibraryWidget() {
localLibraryWidgetWindow = new localLibraryWidget(); localLibraryWidget * localLibraryWidgetWindow = new localLibraryWidget();
libraryWidgetWindow->setAttribute(Qt::WA_DeleteOnClose); connect(localLibraryWidgetWindow, SIGNAL(openBookSignal(QString, bool)), SLOT(openBookFile(QString, bool)));
localLibraryWidgetWindow->setAttribute(Qt::WA_DeleteOnClose);
ui->homeStackedWidget->insertWidget(1, localLibraryWidgetWindow); ui->homeStackedWidget->insertWidget(1, localLibraryWidgetWindow);
ui->homeStackedWidget->setCurrentIndex(1); ui->homeStackedWidget->setCurrentIndex(1);
} }

View file

@ -9,10 +9,11 @@ QClickableLabel::~QClickableLabel() {}
void QClickableLabel::mousePressEvent(QMouseEvent * event) { void QClickableLabel::mousePressEvent(QMouseEvent * event) {
emit clicked(); emit clicked();
QClickableLabel::setStyleSheet("color: white; background-color: black; border-radius: 10px; padding: 20px"); QClickableLabel::setStyleSheet("color: white; background-color: black; border-radius: 10px; padding: 10px");
} }
void QClickableLabel::mouseReleaseEvent(QMouseEvent * event) { void QClickableLabel::mouseReleaseEvent(QMouseEvent * event) {
emit unclicked(); emit unclicked();
QClickableLabel::setStyleSheet("color: black; background-color: white; border-radius: 10px; padding: 20px"); emit bookID(objectName().toInt());
QClickableLabel::setStyleSheet("color: black; background-color: white; border-radius: 10px; padding: 10px");
} }

View file

@ -15,6 +15,7 @@ public:
signals: signals:
void clicked(); void clicked();
void unclicked(); void unclicked();
void bookID(int id);
protected: protected:
void mousePressEvent(QMouseEvent * event); void mousePressEvent(QMouseEvent * event);

View file

@ -822,9 +822,18 @@ void settings::on_showSystemInfoBtn_clicked()
// Show a system info dialog // Show a system info dialog
log("Showing system info dialog", className); log("Showing system info dialog", className);
generalDialogWindow = new generalDialog(); generalDialogWindow = new generalDialog();
if(global::deviceID == "n306\n") { if(global::deviceID == "n705\n" or global::deviceID == "n905\n") {
generalDialogWindow->yIncrease = 2;
}
else if(global::deviceID == "n613\n" or global::deviceID == "n236\n" or global::deviceID == "n306\n") {
generalDialogWindow->yIncrease = 2.6; generalDialogWindow->yIncrease = 2.6;
} }
else if(global::deviceID == "n437\n" or global::deviceID == "n873\n") {
generalDialogWindow->yIncrease = 3;
}
else {
generalDialogWindow->yIncrease = 2;
}
generalDialogWindow->increaseSize(); generalDialogWindow->increaseSize();
generalDialogWindow->setAttribute(Qt::WA_DeleteOnClose); generalDialogWindow->setAttribute(Qt::WA_DeleteOnClose);
} }