Fixes, edge cases like empty library

This commit is contained in:
Szybet 2022-10-15 16:35:03 +02:00 committed by Nicolas Mailloux
parent 2a51e6a24f
commit 257d509429
3 changed files with 138 additions and 35 deletions

View file

@ -1165,6 +1165,11 @@ namespace {
} }
return false; return false;
} }
QString purgeHtml(QString text) {
// https://stackoverflow.com/questions/2799379/is-there-an-easy-way-to-strip-html-from-a-qstring-in-qt
// This can cause problems if someone names its directory with HTML tags, so stop here. Anki, which is a big project, also doesn't care about this
return text.remove(QRegExp("<[^>]*>"));
}
} }
#endif // FUNCTIONS_H #endif // FUNCTIONS_H

View file

@ -85,36 +85,7 @@ localLibraryWidget::localLibraryWidget(QWidget *parent) :
stdIconHeight = sH / stdIconHeightDivider; stdIconHeight = sH / stdIconHeightDivider;
} }
for(int i = 1; i <= buttonsNumber; i++) { setupButtonsLook();
// Horizontal layout that will contain the book button and its icon
horizontalLayoutArray[i] = new QHBoxLayout(this);
// Book icon label
bookIconArray[i] = new QLabel(this);
bookIconArray[i]->setStyleSheet("padding: 10px");
// Book button
bookBtnArray[i] = new QClickableLabel(this);
bookBtnArray[i]->setObjectName(QString::number(i));
QObject::connect(bookBtnArray[i], &QClickableLabel::bookID, this, &localLibraryWidget::btnOpenBook);
QObject::connect(bookBtnArray[i], &QClickableLabel::longPressInt, this, &localLibraryWidget::openBookOptionsDialog);
bookBtnArray[i]->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
bookBtnArray[i]->setStyleSheet("color: black; background-color: white; border-radius: 10px; padding: 10px");
bookBtnArray[i]->setFont(QFont("u001"));
horizontalLayoutArray[i]->addWidget(bookIconArray[i]);
horizontalLayoutArray[i]->addWidget(bookBtnArray[i]);
ui->booksVerticalLayout->addLayout(horizontalLayoutArray[i]);
// Line
if(i < buttonsNumber) {
lineArray[i] = new QFrame(this);
lineArray[i]->setFrameShape(QFrame::HLine);
lineArray[i]->setFrameShadow(QFrame::Plain);
lineArray[i]->setLineWidth(1);
ui->booksVerticalLayout->addWidget(lineArray[i]);
}
}
if(!QFile::exists(global::localLibrary::databasePath)) { if(!QFile::exists(global::localLibrary::databasePath)) {
global::toast::modalToast = true; global::toast::modalToast = true;
@ -340,14 +311,15 @@ void localLibraryWidget::openBook(int bookID) {
void localLibraryWidget::btnOpenBook(int buttonNumber) { void localLibraryWidget::btnOpenBook(int buttonNumber) {
log("Book/directory button clicked, buttonNumber is " + QString::number(buttonNumber), className); log("Book/directory button clicked, buttonNumber is " + QString::number(buttonNumber), className);
if(mainPathAndItsEmpty == true) {
return void();
}
int id = idList.at(buttonNumber - 1); int id = idList.at(buttonNumber - 1);
if(id == global::localLibrary::folderID) { if(id == global::localLibrary::folderID) {
if(folderFeatureEnabled == true) { if(folderFeatureEnabled == true) {
log("A folder was selected", className); log("A folder was selected", className);
QString directory = bookBtnArray[buttonNumber]->text(); QString directory = purgeHtml(bookBtnArray[buttonNumber]->text());
// https://stackoverflow.com/questions/2799379/is-there-an-easy-way-to-strip-html-from-a-qstring-in-qt
// This can cause problems if someone names its directory with HTML tags, so stop here. Anki, which is a big project, also doesn't care about this
directory.remove(QRegExp("<[^>]*>"));
changePathAndRefresh(directory); changePathAndRefresh(directory);
} }
} }
@ -359,6 +331,10 @@ void localLibraryWidget::btnOpenBook(int buttonNumber) {
} }
void localLibraryWidget::openGoToPageDialog() { void localLibraryWidget::openGoToPageDialog() {
if(mainPathAndItsEmpty == true) {
return void();
}
log("Showing 'Go to page' dialog", className); log("Showing 'Go to page' dialog", className);
global::keyboard::keypadDialog = true; global::keyboard::keypadDialog = true;
generalDialogWindow = new generalDialog(); generalDialogWindow = new generalDialog();
@ -367,6 +343,11 @@ void localLibraryWidget::openGoToPageDialog() {
} }
void localLibraryWidget::goToPage(int page) { void localLibraryWidget::goToPage(int page) {
checkIfMainPathEmpty();
if(mainPathAndItsEmpty == true) {
return void();
}
if(page > pagesNumber or page <= 0) { if(page > pagesNumber or page <= 0) {
log("Page number specified (" + QString::number(page) + ") is out of range", className); log("Page number specified (" + QString::number(page) + ") is out of range", className);
showToast("Request is beyond page range"); showToast("Request is beyond page range");
@ -417,6 +398,10 @@ void localLibraryWidget::showToast(QString messageToDisplay) {
} }
void localLibraryWidget::openBookOptionsDialog(int pseudoBookID) { void localLibraryWidget::openBookOptionsDialog(int pseudoBookID) {
if(mainPathAndItsEmpty == true) {
return void();
}
// Determine book ID from the book's button number // Determine book ID from the book's button number
// pseudoBookID represents the button's number // pseudoBookID represents the button's number
int bookID = ((currentPageNumber * buttonsNumber) - (buttonsNumber - 1)) + (pseudoBookID - 1); int bookID = ((currentPageNumber * buttonsNumber) - (buttonsNumber - 1)) + (pseudoBookID - 1);
@ -428,7 +413,7 @@ void localLibraryWidget::openBookOptionsDialog(int pseudoBookID) {
if(folderFeatureEnabled == true) { if(folderFeatureEnabled == true) {
bookID = id; bookID = id;
log("Opening options dialog for directory", className); log("Opening options dialog for directory", className);
QString directoryPath = bookBtnArray[pseudoBookID]->text(); QString directoryPath = purgeHtml(bookBtnArray[pseudoBookID]->text());
log("Directory path is '" + directoryPath + "'", className); log("Directory path is '" + directoryPath + "'", className);
global::localLibrary::bookOptionsDialog::isFolder = true; global::localLibrary::bookOptionsDialog::isFolder = true;
global::localLibrary::bookOptionsDialog::folderPath = pathForFolders + directoryPath; global::localLibrary::bookOptionsDialog::folderPath = pathForFolders + directoryPath;
@ -484,6 +469,14 @@ void localLibraryWidget::setupBooksListFolders(int pageNumber) {
QStringList dirList = QDir(pathForFolders).entryList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name); QStringList dirList = QDir(pathForFolders).entryList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name);
log("Full directory list: "+ dirList.join(","), className); log("Full directory list: "+ dirList.join(","), className);
// Main path is set and its empty
if(mainPathAndItsEmpty == true) {
ui->pageNumberLabel->setText("0 <i>of</i> 0");
ui->previousPageBtn->setEnabled(false);
ui->nextPageBtn->setEnabled(false);
return void();
}
// This part is calculating which folders to show per page // This part is calculating which folders to show per page
QStringList directoryListFront = dirList; QStringList directoryListFront = dirList;
QStringList directoryListBack = dirList; QStringList directoryListBack = dirList;
@ -634,6 +627,11 @@ void localLibraryWidget::setupBooksListFolders(int pageNumber) {
void localLibraryWidget::calculateMaximumPagesNumberForFolders() { void localLibraryWidget::calculateMaximumPagesNumberForFolders() {
log("Main path is '" + pathForFolders + "'", className); log("Main path is '" + pathForFolders + "'", className);
checkIfMainPathEmpty();
if(mainPathAndItsEmpty == true) {
return void();
}
// Look for books in this path // Look for books in this path
booksListForPathIndex.clear(); booksListForPathIndex.clear();
int count = 0; int count = 0;
@ -664,8 +662,19 @@ void localLibraryWidget::calculateMaximumPagesNumberForFolders() {
directoryListCount = QDir(pathForFolders).entryList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name).count(); directoryListCount = QDir(pathForFolders).entryList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name).count();
log("Directories count in directory: " + QString::number(directoryListCount), className); log("Directories count in directory: " + QString::number(directoryListCount), className);
completeItemsList = booksListForPathIndex.count() + directoryListCount; completeItemsList = booksListForPathIndex.count() + directoryListCount;
log("All items: " + QString::number(completeItemsList), className); log("All items: " + QString::number(completeItemsList), className);
// Fix for bug:
/*
put files in a folder, then delete all files in that folder from the GUI.
Then the bug happens: "page request is out of range" or something like that
*/
if(completeItemsList == 0) {
log("No items in this folder because they were deleted. Going up", className);
goUpFunction();
}
pagesNumber = std::ceil((double)completeItemsList / buttonsNumber); pagesNumber = std::ceil((double)completeItemsList / buttonsNumber);
log("Total pages: " + QString::number(pagesNumber), className); log("Total pages: " + QString::number(pagesNumber), className);
@ -735,6 +744,10 @@ void localLibraryWidget::changePathAndRefresh(QString directory) {
void localLibraryWidget::on_goUpBtn_clicked() void localLibraryWidget::on_goUpBtn_clicked()
{ {
goUpFunction();
}
void localLibraryWidget::goUpFunction() {
if(pathForFolders != "/mnt/onboard/onboard/") { if(pathForFolders != "/mnt/onboard/onboard/") {
log("Changing path; going back", className); log("Changing path; going back", className);
// This can't be a one-liner // This can't be a one-liner
@ -767,3 +780,82 @@ void localLibraryWidget::refreshFolders() {
bookIndexVector = 0; bookIndexVector = 0;
goToPage(1); goToPage(1);
} }
void localLibraryWidget::checkIfMainPathEmpty() {
if(folderFeatureEnabled == true) {
// If the main path is empty, prevent it from well, freezing and using the cpu for 100% because of a while loop
if(pathForFolders == "/mnt/onboard/onboard/") {
bool isDirEmpty = QDir(pathForFolders).entryList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot).isEmpty();
log("Main path is empty: " + QVariant(isDirEmpty).toString(), className);
if(isDirEmpty == true) {
// To clean things out after a deletion
cleanButtons();
booksListForPathIndex.clear();
directoryListCount = 0;
completeItemsList = 0;
pagesNumber = 0;
firstPageForBooks = 0;
lastPageFolderCount = 0;
mainPathAndItsEmpty = true;
showToast("The library is empty");
return void();
}
else {
mainPathAndItsEmpty = false;
}
}
}
}
void localLibraryWidget::setupButtonsLook() {
for(int i = 1; i <= buttonsNumber; i++) {
// Horizontal layout that will contain the book button and its icon
horizontalLayoutArray[i] = new QHBoxLayout(this);
// Book icon label
bookIconArray[i] = new QLabel(this);
bookIconArray[i]->setStyleSheet("padding: 10px");
// Book button
bookBtnArray[i] = new QClickableLabel(this);
bookBtnArray[i]->setObjectName(QString::number(i));
QObject::connect(bookBtnArray[i], &QClickableLabel::bookID, this, &localLibraryWidget::btnOpenBook);
QObject::connect(bookBtnArray[i], &QClickableLabel::longPressInt, this, &localLibraryWidget::openBookOptionsDialog);
bookBtnArray[i]->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
bookBtnArray[i]->setStyleSheet("color: black; background-color: white; border-radius: 10px; padding: 10px");
bookBtnArray[i]->setFont(QFont("u001"));
horizontalLayoutArray[i]->addWidget(bookIconArray[i]);
horizontalLayoutArray[i]->addWidget(bookBtnArray[i]);
ui->booksVerticalLayout->addLayout(horizontalLayoutArray[i]);
// Line
if(i < buttonsNumber) {
lineArray[i] = new QFrame(this);
lineArray[i]->setFrameShape(QFrame::HLine);
lineArray[i]->setFrameShadow(QFrame::Plain);
lineArray[i]->setLineWidth(1);
ui->booksVerticalLayout->addWidget(lineArray[i]);
}
}
}
void localLibraryWidget::cleanButtons() {
log("Hiding items", className);
for(int i = 1; i <= buttonsNumber; i++) {
if(bookIconArray[i]->isHidden() == false) {
bookIconArray[i]->hide();
}
if(bookBtnArray[i]->isHidden() == false) {
bookBtnArray[i]->hide();
}
// I like it with those empty lines, like empty book shelves
/*
if(i < buttonsNumber) {
if(lineArray[i]->isHidden() == false) {
lineArray[i]->hide();
}
}
*/
}
}

View file

@ -53,6 +53,8 @@ public:
int fileListCount; int fileListCount;
int directoryListCount; int directoryListCount;
int completeItemsList; int completeItemsList;
// if the path is set to /mnt/onboard/onboard/, and its empty, this will be true
bool mainPathAndItsEmpty = false;
private slots: private slots:
@ -70,11 +72,15 @@ private slots:
void openBookOptionsDialog(int pseudoBookID); void openBookOptionsDialog(int pseudoBookID);
void handlePossibleBookDeletion(); void handlePossibleBookDeletion();
void openLocalBookInfoDialog(); void openLocalBookInfoDialog();
void setupButtonsLook();
void cleanButtons();
// For folder feature // For folder feature
void setupBooksListFolders(int pageNumber); void setupBooksListFolders(int pageNumber);
void setupBooksListToggle(int pageNumber); void setupBooksListToggle(int pageNumber);
void calculateMaximumPagesNumberForFolders(); void calculateMaximumPagesNumberForFolders();
void calculateIndexForPage(int pageNumber); void calculateIndexForPage(int pageNumber);
void goUpFunction();
void checkIfMainPathEmpty();
// Dir without "/" at the end and begining // Dir without "/" at the end and begining
void changePathAndRefresh(QString directory); void changePathAndRefresh(QString directory);
void refreshFolders(); void refreshFolders();