Skip to content
reader.cpp 54 KiB
Newer Older
#include "reader.h"
#include "ui_reader.h"
#include <QProcess>
#include <QFileDialog>
#include <QDir>
#include <QTimer>
#include <QTime>
#include <QMessageBox>
#include <QFont>
#include <QIcon>
#include <QSize>
#include <QDesktopWidget>
#include <QScreen>
#include <QDirIterator>

using namespace std;

reader::reader(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::reader)
{
    // Variables
    global::battery::showLowBatteryDialog = true;
    global::battery::showCriticalBatteryAlert = true;
    if(global::reader::bookIsEpub == true) {
        is_epub = true;
    }
    wordwidgetLock = false;
    ui->setupUi(this);
    ui->previousBtn->setProperty("type", "borderless");
    ui->nextBtn->setProperty("type", "borderless");
    ui->hideOptionsBtn->setProperty("type", "borderless");
    ui->optionsBtn->setProperty("type", "borderless");
    ui->brightnessDecBtn->setProperty("type", "borderless");
    ui->brightnessIncBtn->setProperty("type", "borderless");
    ui->homeBtn->setProperty("type", "borderless");
    ui->aboutBtn->setProperty("type", "borderless");
    ui->alignLeftBtn->setProperty("type", "borderless");
    ui->alignRightBtn->setProperty("type", "borderless");
    ui->alignCenterBtn->setProperty("type", "borderless");
    ui->alignLeftBtn->setProperty("type", "borderless");
    ui->alignJustifyBtn->setProperty("type", "borderless");
    ui->infoCloseBtn->setProperty("type", "borderless");
    ui->saveWordBtn->setProperty("type", "borderless");
    ui->previousDefinitionBtn->setProperty("type", "borderless");
    ui->nextDefinitionBtn->setProperty("type", "borderless");
    ui->nightModeBtn->setProperty("type", "borderless");
    ui->searchBtn->setProperty("type", "borderless");
    ui->gotoBtn->setProperty("type", "borderless");

    // Icons
    ui->alignLeftBtn->setText("");
    ui->alignLeftBtn->setIcon(QIcon(":/resources/align-left.png"));
    ui->alignRightBtn->setText("");
    ui->alignRightBtn->setIcon(QIcon(":/resources/align-right.png"));
    ui->alignCenterBtn->setText("");
    ui->alignCenterBtn->setIcon(QIcon(":/resources/align-center.png"));
    ui->alignJustifyBtn->setText("");
    ui->alignJustifyBtn->setIcon(QIcon(":/resources/align-justify.png"));
    ui->infoCloseBtn->setText("");
    ui->infoCloseBtn->setIcon(QIcon(":/resources/close.png"));
    ui->saveWordBtn->setText("");
    ui->saveWordBtn->setIcon(QIcon(":/resources/star.png"));
    ui->previousDefinitionBtn->setText("");
    ui->previousDefinitionBtn->setIcon(QIcon(":/resources/chevron-left.png"));
    ui->nextDefinitionBtn->setText("");
    ui->nextDefinitionBtn->setIcon(QIcon(":/resources/chevron-right.png"));
    ui->brightnessDecBtn->setText("");
    ui->brightnessDecBtn->setIcon(QIcon(":/resources/minus.png"));
    ui->brightnessIncBtn->setText("");
    ui->brightnessIncBtn->setIcon(QIcon(":/resources/plus.png"));
    ui->homeBtn->setText("");
    ui->homeBtn->setIcon(QIcon(":/resources/home.png"));
    ui->aboutBtn->setText("");
    ui->aboutBtn->setIcon(QIcon(":/resources/info.png"));
    ui->searchBtn->setText("");
    ui->searchBtn->setIcon(QIcon(":/resources/search.png"));
    // Style misc.
    ui->bookInfoLabel->setStyleSheet("font-style: italic");

    // Making text selectable
    ui->text->setTextInteractionFlags(Qt::TextSelectableByMouse);

    // Font misc.
    int id = QFontDatabase::addApplicationFont(":/resources/fonts/CrimsonPro-Italic.ttf");
    QString family = QFontDatabase::applicationFontFamilies(id).at(0);
    QFont crimson(family);
    int id_1 = QFontDatabase::addApplicationFont(":/resources/fonts/CrimsonPro-Bold.ttf");
    QString family_1 = QFontDatabase::applicationFontFamilies(id).at(0);
    QFont crimson_1(family_1);
    // Custom settings
    // Font
    string_checkconfig(".config/04-book/font");
    if(checkconfig_str_val == "") {
        ui->fontChooser->setCurrentText("Source Serif Pro");
Nicolas Mailloux's avatar
Nicolas Mailloux committed
        ui->text->setFont(QFont("Source Serif Pro"));
        if(checkconfig_str_val == "Crimson Pro") {
            int id = QFontDatabase::addApplicationFont(":/resources/fonts/CrimsonPro-Regular.ttf");
            QString family = QFontDatabase::applicationFontFamilies(id).at(0);
            QFont crimson(family);
            ui->text->setFont(crimson);
            ui->fontChooser->setCurrentText(checkconfig_str_val);
        }
        else {
            QFont config_font(checkconfig_str_val);
            ui->text->setFont(config_font);
            ui->fontChooser->setCurrentText(checkconfig_str_val);
        }
    // Night mode
    if(checkconfig(".config/10-dark_mode/config") == true) {
        string_writeconfig("/tmp/invertScreen", "y");
        ui->nightModeBtn->setText("");
        ui->nightModeBtn->setIcon(QIcon(":/resources/nightmode-full.png"));
        isNightModeActive = true;
    }
    else {
        string_writeconfig("/tmp/invertScreen", "n");
        ui->nightModeBtn->setText("");
        ui->nightModeBtn->setIcon(QIcon(":/resources/nightmode-empty.png"));
        isNightModeActive = false;
    }

    // Stylesheet + misc.
    QFile stylesheetFile(":/resources/eink.qss");
    stylesheetFile.open(QFile::ReadOnly);
    this->setStyleSheet(stylesheetFile.readAll());
    stylesheetFile.close();

    ui->sizeValueLabel->setStyleSheet("font-size: 9pt");
    ui->homeBtn->setStyleSheet("font-size: 9pt; padding: 5px");
    ui->aboutBtn->setStyleSheet("font-size: 9pt; padding: 5px");
    ui->fontChooser->setStyleSheet("font-size: 9pt");
    ui->gotoBtn->setStyleSheet("font-size: 9pt; padding: 9px; font-weight: bold; background: lightGrey");
    ui->pageNumberLabel->setFont(QFont("Source Serif Pro"));
    // Hiding the menubar + definition widget + brightness widget
    ui->hideOptionsBtn->hide();
    ui->brightnessWidget->setVisible(false);
    ui->menuBarWidget->setVisible(false);
    ui->wordWidget->setVisible(false);
    if(checkconfig(".config/11-menubar/sticky") == true) {
        ui->statusBarWidget->setVisible(true);
        ui->statusBarWidget->setVisible(false);
    ui->pageWidget->hide();
    // Topbar widget / book info
    ui->topbarStackedWidget->setVisible(true);
    showTopbarWidget = true;
    ui->bookInfoLabel->setFont(crimson);
    // Getting brightness level
    int brightness_value;
    if(global::isN705 == true or global::isN905C == true) {
        brightness_value = get_brightness();
    }
    else if(global::isN613 == true) {
        setDefaultWorkDir();
        brightness_value = brightness_checkconfig(".config/03-brightness/config");
    }
    else {
        brightness_value = get_brightness();
    ui->brightnessStatus->setValue(brightness_value);

    // Defining pixmaps
    // Getting the screen's size
    float sW = QGuiApplication::screens()[0]->size().width();
    float sH = QGuiApplication::screens()[0]->size().height();
    // Defining what the icons' size will be
    if(checkconfig("/opt/inkbox_genuine") == true) {
        string_checkconfig_ro("/opt/inkbox_device");
        if(checkconfig_str_val == "n705\n" or checkconfig_str_val == "n905\n" or checkconfig_str_val == "n613\n") {
            float stdIconWidth = sW / 16;
            float stdIconHeight = sW / 16;
            QPixmap chargingPixmap(":/resources/battery_charging.png");
            scaledChargingPixmap = chargingPixmap.scaled(stdIconWidth, stdIconHeight, Qt::KeepAspectRatio);
            QPixmap fullPixmap(":/resources/battery_full.png");
            scaledFullPixmap = fullPixmap.scaled(stdIconWidth, stdIconHeight, Qt::KeepAspectRatio);
            QPixmap halfPixmap(":/resources/battery_half.png");
            scaledHalfPixmap = halfPixmap.scaled(stdIconWidth, stdIconHeight, Qt::KeepAspectRatio);
            QPixmap emptyPixmap(":/resources/battery_empty.png");
            scaledEmptyPixmap = emptyPixmap.scaled(stdIconWidth, stdIconHeight, Qt::KeepAspectRatio);
        }
        else {
            float stdIconWidth = sW / 19;
            float stdIconHeight = sH / 19;
            QPixmap chargingPixmap(":/resources/battery_charging.png");
            scaledChargingPixmap = chargingPixmap.scaled(stdIconWidth, stdIconHeight, Qt::KeepAspectRatio);
            QPixmap fullPixmap(":/resources/battery_full.png");
            scaledFullPixmap = fullPixmap.scaled(stdIconWidth, stdIconHeight, Qt::KeepAspectRatio);
            QPixmap halfPixmap(":/resources/battery_half.png");
            scaledHalfPixmap = halfPixmap.scaled(stdIconWidth, stdIconHeight, Qt::KeepAspectRatio);
            QPixmap emptyPixmap(":/resources/battery_empty.png");
            scaledEmptyPixmap = emptyPixmap.scaled(stdIconWidth, stdIconHeight, Qt::KeepAspectRatio);
        }
    }
    else {
        float stdIconWidth = sW / 19;
        float stdIconHeight = sH / 19;
        QPixmap chargingPixmap(":/resources/battery_charging.png");
        scaledChargingPixmap = chargingPixmap.scaled(stdIconWidth, stdIconHeight, Qt::KeepAspectRatio);
        QPixmap fullPixmap(":/resources/battery_full.png");
        scaledFullPixmap = fullPixmap.scaled(stdIconWidth, stdIconHeight, Qt::KeepAspectRatio);
        QPixmap halfPixmap(":/resources/battery_half.png");
        scaledHalfPixmap = halfPixmap.scaled(stdIconWidth, stdIconHeight, Qt::KeepAspectRatio);
        QPixmap emptyPixmap(":/resources/battery_empty.png");
        scaledEmptyPixmap = emptyPixmap.scaled(stdIconWidth, stdIconHeight, Qt::KeepAspectRatio);
    }

    // Checking if there is a page refresh setting set
    string_checkconfig(".config/04-book/refresh");
    if(checkconfig_str_val == "") {
        // Writing the default, refresh every 3 pages
        string_writeconfig(".config/04-book/refresh", "3");
        string_checkconfig(".config/04-book/refresh");
    }
    else {
        // A config option was set, continuing after the Else statement...
        ;
    }
    pageRefreshSetting = checkconfig_str_val.toInt();
    // Checking if that config option was set to "Never refresh"...
    if(pageRefreshSetting == -1) {
        neverRefresh = true;
    }
    else {
        // Safety measure
        neverRefresh = false;
    }

    // Clock setting to show seconds + battery level
    if(checkconfig(".config/02-clock/config") == true) {
        QTimer *t = new QTimer(this);
        t->setInterval(500);
        connect(t, &QTimer::timeout, [&]() {
           QString time = QTime::currentTime().toString("hh:mm:ss");
           get_battery_level();
           ui->batteryLabel->setText(batt_level);
           ui->timeLabel->setText(time);
        } );
        t->start();
    }
    else {
        QTimer *t = new QTimer(this);
        t->setInterval(500);
        connect(t, &QTimer::timeout, [&]() {
           QString time = QTime::currentTime().toString("hh:mm");
           get_battery_level();
           ui->batteryLabel->setText(batt_level);
           ui->timeLabel->setText(time);
        } );
        t->start();
    }

    // We have to get the file's path
Nicolas Mailloux's avatar
Nicolas Mailloux committed
    if(global::reader::skipOpenDialog == true) {
        if(checkconfig("/tmp/suspendBook") == true) {
            wakeFromSleep = true;
            // Prevent from opening the Reader framework next time unless the condition is reset
            string_writeconfig("/tmp/suspendBook", "false");
            book_file = "/inkbox/book/book.txt";
        else {
            if(global::reader::bookNumber == 1) {
                string_checkconfig(".config/08-recent_books/1");
                book_file = checkconfig_str_val;
            }
            if(global::reader::bookNumber == 2) {
                string_checkconfig(".config/08-recent_books/2");
                book_file = checkconfig_str_val;
            }
            if(global::reader::bookNumber == 3) {
                string_checkconfig(".config/08-recent_books/3");
                book_file = checkconfig_str_val;
            }
            if(global::reader::bookNumber == 4) {
                string_checkconfig(".config/08-recent_books/4");
                book_file = checkconfig_str_val;
            }
        }
    }
    else {
        if(checkconfig("/opt/inkbox_genuine") == true) {
            QDir::setCurrent("/mnt/onboard/onboard");
            QFileDialog *dialog = new QFileDialog(this);
            // https://forum.qt.io/topic/29471/solve-how-to-show-qfiledialog-at-center-position-screen/4
            QDesktopWidget desk;
            QRect screenres = desk.screenGeometry(0); dialog->setGeometry(QRect(screenres.width()/4,screenres.height() /4,screenres.width()/2,screenres.height()/2));
            stylesheetFile.open(QFile::ReadOnly);
            dialog->setStyleSheet(stylesheetFile.readAll());
            stylesheetFile.close();
            book_file = dialog->getOpenFileName(dialog, tr("Open File"), QDir::currentPath());
Nicolas Mailloux's avatar
Nicolas Mailloux committed
                setDefaultWorkDir();
            }
            else {
                // User clicked "Cancel" button
Nicolas Mailloux's avatar
Nicolas Mailloux committed
                setDefaultWorkDir();
        }
        else {
            QDir::setCurrent("/mnt/onboard");
            QFileDialog *dialog = new QFileDialog(this);
            // https://forum.qt.io/topic/29471/solve-how-to-show-qfiledialog-at-center-position-screen/4
            QDesktopWidget desk;
            QRect screenres = desk.screenGeometry(0); dialog->setGeometry(QRect(screenres.width()/4,screenres.height() /4,screenres.width()/2,screenres.height()/2));
            stylesheetFile.open(QFile::ReadOnly);
            dialog->setStyleSheet(stylesheetFile.readAll());
            stylesheetFile.close();
            book_file = dialog->getOpenFileName(dialog, tr("Open File"), QDir::currentPath());
Nicolas Mailloux's avatar
Nicolas Mailloux committed
                setDefaultWorkDir();
            }
            else {
                // User clicked "Cancel" button
Nicolas Mailloux's avatar
Nicolas Mailloux committed
                setDefaultWorkDir();
    // Checking if we're waking from sleep; if so, do nothing there because the book should already have been parsed
    if(wakeFromSleep != true) {
        // Remount tmpfs
        string_writeconfig("/inkbox/remount", "true");

        // Counting number of parsed files
        split_total = setup_book(book_file, 0, true);
        split_files_number = split_total;
        split_total = split_total - 1;

        writeconfig_pagenumber();
    }
    else {
Nicolas Mailloux's avatar
Nicolas Mailloux committed
        // Retrieve split_total from tmpfs
        string_checkconfig("/tmp/inkboxPageNumber");
        split_total = checkconfig_str_val.toInt();
        setup_book(book_file, 0, true);
Nicolas Mailloux's avatar
Nicolas Mailloux committed
    // Get text; no need to do it multiple times for ePUB books
    if(is_epub != true) {
        setDefaultWorkDir();
        setup_book(book_file, split_total, true);
    }

    // Display text
    // Checking saved font size if any
    string_checkconfig(".config/04-book/size");
    if(checkconfig_str_val == "0") {
        checkconfig_str_val = "6";
        ui->sizeSlider->setValue(0);
        ui->sizeValueLabel->setText("1");
    }
    if(checkconfig_str_val == "1") {
        checkconfig_str_val = "10";
        ui->sizeSlider->setValue(1);
        ui->sizeValueLabel->setText("2");
    }
    if(checkconfig_str_val == "2") {
        checkconfig_str_val = "14";
        ui->sizeSlider->setValue(2);
        ui->sizeValueLabel->setText("3");
    }
    if(checkconfig_str_val == "3") {
        checkconfig_str_val = "18";
        ui->sizeSlider->setValue(3);
        ui->sizeValueLabel->setText("4");
    }
    if(checkconfig_str_val == "4") {
        checkconfig_str_val = "22";
        ui->sizeSlider->setValue(4);
        ui->sizeValueLabel->setText("5");
    }
    if(checkconfig_str_val == "") {
        checkconfig_str_val = "10";
        ui->sizeSlider->setValue(1);
        ui->sizeValueLabel->setText("2");
    }
    QString font_size = "font-size: ";
    font_size = font_size.append(checkconfig_str_val);
    font_size = font_size.append("pt");
    ui->text->setStyleSheet(font_size);

    // If needed, show scroll bar when rendering engine isn't doing its job properly
    if(checkconfig(".config/14-reader_scrollbar/config") == true) {
        ui->text->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        ui->text->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    }
    else {
        ui->text->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        ui->text->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    }

    // Wheeee!
    if(is_epub != true) {
        ui->text->setText(ittext);
    }
    else {
        ui->text->setText(epubPageContent);
    }
    // Alignment
    string_checkconfig(".config/04-book/alignment");
    if (checkconfig_str_val == "") {
        ;
    }
    else {
        if(checkconfig_str_val == "Left") {
                textAlignment = 0;
                alignText(0);
        }
        if(checkconfig_str_val == "Center") {
                textAlignment = 1;
                alignText(1);
        }
        if(checkconfig_str_val == "Right") {
                textAlignment = 2;
                alignText(2);
        }
        if(checkconfig_str_val == "Justify") {
                textAlignment = 3;
                alignText(3);
        }
    }

    // Topbar info widget
    if(is_epub == true) {
        QString bookCreator = findEpubMetadata(book_file, "creator");
        QString bookTitle = findEpubMetadata(book_file, "title");
        bookCreator = bookCreator.trimmed();
        bookTitle = bookTitle.trimmed();

        QString infoLabelContent = bookCreator;
        infoLabelContent.append(" ― ");
        infoLabelContent.append(bookTitle);
        int infoLabelLength = infoLabelContent.length();
        int infoLabelDefinedLength;
        string_checkconfig_ro("/opt/inkbox_device");
        if(checkconfig_str_val == "n705\n") {
            infoLabelDefinedLength = 35;
        }
        if(checkconfig_str_val == "n905\n") {
            infoLabelDefinedLength = 50;
        }

        if(infoLabelLength <= infoLabelDefinedLength) {
            ui->bookInfoLabel->setWordWrap(false);
        }
        else {
            ui->bookInfoLabel->setWordWrap(true);
        }
        ui->bookInfoLabel->setText(infoLabelContent);
    }
    else {
Nicolas Mailloux's avatar
Nicolas Mailloux committed
        QString bookReadRelativePath;
        if(wakeFromSleep == true) {
            string_checkconfig_ro("/tmp/inkboxBookPath");
            bookReadRelativePath = checkconfig_str_val.split("/").last();
        }
        else {
            bookReadRelativePath = book_file.split("/").last();
        }
        ui->bookInfoLabel->setText(bookReadRelativePath);
    }

    // Clean up
    string_writeconfig("/inkbox/remount", "true");

    // Way to tell shell scripts that we're in the Reader framework
    string_writeconfig("/tmp/inkboxReading", "true");

    // Saving the book opened in the favorites list
    string_checkconfig(".config/08-recent_books/1");
    book_1 = checkconfig_str_val;
    string str_book_1 = book_1.toStdString();
    string_checkconfig(".config/08-recent_books/2");
    book_2 = checkconfig_str_val;
    string str_book_2 = book_2.toStdString();
    string_checkconfig(".config/08-recent_books/3");
    book_3 = checkconfig_str_val;
    string str_book_3 = book_3.toStdString();
    string_checkconfig(".config/08-recent_books/4");
    book_4 = checkconfig_str_val;
    std::string str_book_4 = book_4.toStdString();

    // Don't mess up "Recently read books" with random "book.txt" buttons...
    if(wakeFromSleep == true) {
        string_checkconfig("/tmp/inkboxBookPath");
        book_file_str = checkconfig_str_val.toStdString();
    }
    else {
        book_file_str = book_file.toStdString();
        string_writeconfig("/tmp/inkboxBookPath", book_file_str);
    }

    if(book_1 == book_file) {
        ;
    }
    else {
        // Moves old items to the right and puts the new one at the left side
        string_writeconfig(".config/08-recent_books/1", book_file_str);
        string_writeconfig(".config/08-recent_books/2", str_book_1);
        string_writeconfig(".config/08-recent_books/3", str_book_2);
        string_writeconfig(".config/08-recent_books/4", str_book_3);
    }
Nicolas Mailloux's avatar
Nicolas Mailloux committed
    // USB mass storage prompt
    if(global::reader::startUsbmsPrompt == true) {
        QTimer *usbmsPrompt = new QTimer(this);
        usbmsPrompt->setInterval(500);
        connect(usbmsPrompt, &QTimer::timeout, [&]() {
            if(checkconfig("/opt/inkbox_genuine") == true) {
                if(global::usbms::showUsbmsDialog != true) {
                    string_checkconfig_ro("/sys/devices/platform/pmic_battery.1/power_supply/mc13892_bat/status");
                    if(usbmsStatus != checkconfig_str_val) {
                        global::usbms::showUsbmsDialog = true;
                    }
                }
                else {
                    string_checkconfig_ro("/sys/devices/platform/pmic_battery.1/power_supply/mc13892_bat/status");
                    usbmsStatus = checkconfig_str_val;
                    if(usbmsStatus != "Charging\n") {
                        // Loop again...
                        ;
                    }
                    else {
                        // An USB cable is connected!
                        openUsbmsDialog();
                    }
                }
            }
            else {
                // Do nothing, we're running along with Nickel & friends...
                ;
            }
        } );
        usbmsPrompt->start();
    }

    // Battery watchdog
    if(global::reader::startBatteryWatchdog == true) {
        QTimer *t = new QTimer(this);
        t->setInterval(2000);
        connect(t, &QTimer::timeout, [&]() {
            // Checking if battery level is low
            if(global::battery::showCriticalBatteryAlert != true) {
                ;
            }
            else {
                if(isBatteryCritical() == true) {
                    qDebug() << "Warning! Battery is at a critical charge level!";
                    openCriticalBatteryAlertWindow();
                }
            }

            if(global::battery::showLowBatteryDialog != true) {
                // Do nothing, since a dialog should already have been displayed and (probably) dismissed
                ;
            }
            else {
                if(isBatteryLow() == true) {
                    if(global::battery::batteryAlertLock == true) {
                        ;
                    }
                    else {
                        qDebug() << "Warning! Battery is low!";
                        string_checkconfig_ro("/sys/devices/platform/pmic_battery.1/power_supply/mc13892_bat/status");
                        if(checkconfig_str_val == "Charging\n") {
                            ;
                        }
                        else {
                            openLowBatteryDialog();
                        }
                    }
                }
            }
        } );
        t->start();
    }

    // Pages number info label
    if(is_epub == true) {
        getTotalEpubPagesNumber();
    }
    setupPageWidget();
}

reader::~reader()
{
    delete ui;
}

Nicolas Mailloux's avatar
Nicolas Mailloux committed
int reader::setup_book(QString book, int i, bool run_parser) {
    // Parse ebook
    if(remount != false) {
        QString mount_prog ("sh");
        QStringList mount_args;
        mount_args << "split.sh";
        QProcess *mount_proc = new QProcess();
        mount_proc->start(mount_prog, mount_args);
        mount_proc->waitForFinished();
        remount = false;
    }
    else {
        string_writeconfig("/inkbox/remount", "false");
        QString mount_prog ("sh");
        QStringList mount_args;
        mount_args << "split.sh";
        QProcess *mount_proc = new QProcess();
        mount_proc->start(mount_prog, mount_args);
        mount_proc->waitForFinished();
    }

    if(filematch_ran != true) {
Nicolas Mailloux's avatar
Nicolas Mailloux committed
        if(epub_file_match(book) == true) {
Nicolas Mailloux's avatar
Nicolas Mailloux committed
            QFile::remove("/run/book.epub");
            QFile::copy(book, "/run/book.epub");

            // Parsing ePUBs with `mutool'
Nicolas Mailloux's avatar
Nicolas Mailloux committed
            QString epubProg ("sh");
            QStringList epubArgs;
            convertMuPdfVars();
            epubArgs << "/mnt/onboard/.adds/inkbox/epub.sh" << mupdf::fontSize_qstr << mupdf::width_qstr << mupdf::height_qstr << mupdf::epubPageNumber_qstr;
Nicolas Mailloux's avatar
Nicolas Mailloux committed
            QProcess *epubProc = new QProcess();
            epubProc->start(epubProg, epubArgs);
            epubProc->waitForFinished();

            filematch_ran = true;
Nicolas Mailloux's avatar
Nicolas Mailloux committed
            is_epub = true;
Nicolas Mailloux's avatar
Nicolas Mailloux committed
            // This is likely not an ePUB.
            // Copying book specified in the function call
            QFile::copy(book, "/inkbox/book/book.txt");

            filematch_ran = true;
Nicolas Mailloux's avatar
Nicolas Mailloux committed
            is_epub = false;
        }
    }

    // Checking whether the user has defined an option for the number of words per page; if not, then setting the default.
    // NOTE: This is only for plain text files.
Nicolas Mailloux's avatar
Nicolas Mailloux committed
    setDefaultWorkDir();
Nicolas Mailloux's avatar
Nicolas Mailloux committed
    string_checkconfig(".config/07-words_number/config");
    if(checkconfig_str_val == "") {
        string_writeconfig(".config/07-words_number/config", "100");
        string_checkconfig(".config/07-words_number/config");
    }

    // Parsing file
    if(is_epub == true) {
        if(run_parser == true) {
Nicolas Mailloux's avatar
Nicolas Mailloux committed
            if(filematch_ran != false) {
                QString epubProg ("sh");
                QStringList epubArgs;
                convertMuPdfVars();
                epubArgs << "/mnt/onboard/.adds/inkbox/epub.sh" << mupdf::fontSize_qstr << mupdf::width_qstr << mupdf::height_qstr << mupdf::epubPageNumber_qstr;
                QProcess *epubProc = new QProcess();
                epubProc->start(epubProg, epubArgs);
                epubProc->waitForFinished();
            }
            else {
                ;
            }
Nicolas Mailloux's avatar
Nicolas Mailloux committed
        }
        else {
Nicolas Mailloux's avatar
Nicolas Mailloux committed
        QString parse_prog ("python3");
        QStringList parse_args;
        parse_args << "split-txt.py" << checkconfig_str_val;
        QProcess *parse_proc = new QProcess();
        parse_proc->start(parse_prog, parse_args);
        parse_proc->waitForFinished();
Nicolas Mailloux's avatar
Nicolas Mailloux committed
    }

    // Reading files
    if(is_epub != true) {
        if(run_parser == true) {
            QDirIterator it("/inkbox/book/split");
            while (it.hasNext()) {
                  QFile f(it.next());
                  f.open(QIODevice::ReadOnly);
                  content << f.readAll();
                  f.close();
            }
Nicolas Mailloux's avatar
Nicolas Mailloux committed
            ittext = content[i];
            return content.size();
        }
        else {
            ittext = content[i];
Nicolas Mailloux's avatar
Nicolas Mailloux committed
        }
    }
    else {
        QFile epubPage("/inkbox/book/page");
        epubPage.open(QIODevice::ReadOnly);
        QTextStream in(&epubPage);
        epubPageContent = in.readAll();
        epubPage.close();
Nicolas Mailloux's avatar
Nicolas Mailloux committed
    }
    return 0;
}

void reader::checkwords() {
    QFile words_list(".config/06-words/config");
    words_list.open(QIODevice::ReadWrite);
    QTextStream in (&words_list);
    words = in.readAll();
    words_list.close();
}

bool reader::epub_file_match(QString file) {
    QString fileExt = file.right(4);

    if(fileExt == "epub" or fileExt == "EPUB") {
Nicolas Mailloux's avatar
Nicolas Mailloux committed
        string_writeconfig("/inkbox/bookIsEpub", "true");
Nicolas Mailloux's avatar
Nicolas Mailloux committed
        string_writeconfig("/inkbox/bookIsEpub", "false");
        return false;
    }
}

void reader::dictionary_lookup(string word, QString first_letter, int position) {
    ofstream fhandler;
    fhandler.open("/inkbox/dictionary/word");
    fhandler << word;
    fhandler.close();

    QDir::setCurrent("dictionary");
    QDir::setCurrent(first_letter);
    QString lookup_prog ("sh");
    QStringList lookup_args;
    QString position_str = QString::number(position);
    lookup_args << "../scripts/lookup.sh" << position_str;
    QProcess *lookup_proc = new QProcess();
    lookup_proc->start(lookup_prog, lookup_args);
    lookup_proc->waitForFinished();

    QFile definition_file("/inkbox/dictionary/definition");
    definition_file.open(QIODevice::ReadWrite);
    QTextStream in (&definition_file);
    definition = in.readAll();
    definition = definition.remove(QRegExp("[\n]"));
    if(definition == "No definition found.") {
        nextdefinition_lock = true;
    }
    else {
        nextdefinition_lock = false;
    }
    definition_file.close();

Nicolas Mailloux's avatar
Nicolas Mailloux committed
    setDefaultWorkDir();
}

void reader::save_word(string word, bool remove) {
    if(remove == false) {
        QFile words(".config/06-words/config");
        words.open(QIODevice::ReadWrite);
        QTextStream in (&words);
        QString words_list = in.readAll();
        string words_list_str = words_list.toStdString();
        words.close();

        ofstream fhandler;
        fhandler.open(".config/06-words/config");
        fhandler << words_list_str << word << "\n";
        fhandler.close();
    }
    else {
        ofstream fhandler;
        fhandler.open(".config/06-words/config");
        fhandler << word;
        fhandler.close();
    }
}

void reader::on_nextBtn_clicked()
{
    if(is_epub != true) {
        if(split_total - 1 == 1 or split_total - 1 == 0) {
            QMessageBox::critical(this, tr("Invalid argument"), tr("You've reached the end of the document."));
        }
        else {
            split_total = split_total - 1;

            setup_book(book_file, split_total, false);
            ui->text->setText("");
            ui->text->setText(ittext);

            pagesTurned = pagesTurned + 1;
            writeconfig_pagenumber();
        }
        if(mupdf::epubPageNumber + 1 > totalPagesInt) {
            QMessageBox::critical(this, tr("Invalid argument"), tr("You've reached the end of the document."));
        }
        else {
            mupdf::epubPageNumber = mupdf::epubPageNumber + 1;
            setup_book(book_file, mupdf::epubPageNumber, true);
            ui->text->setText("");
            ui->text->setText(epubPageContent);
            pagesTurned = pagesTurned + 1;
            writeconfig_pagenumber();
        }
    alignText(textAlignment);
    refreshScreen();
}

void reader::on_previousBtn_clicked()
{
    if(is_epub != true) {
    // Making sure we won't encounter a "List index out of range" error ;)
        if(split_total >= split_files_number - 1) {
            QMessageBox::critical(this, tr("Invalid argument"), tr("No previous page."));
            split_total = split_total + 1;
            setup_book(book_file, split_total, false);
            ui->text->setText("");
            ui->text->setText(ittext);

            // We always increment pagesTurned regardless whether we press the Previous or Next button
            pagesTurned = pagesTurned + 1;
            writeconfig_pagenumber();
        if(mupdf::epubPageNumber - 1 <= 0) {
            QMessageBox::critical(this, tr("Invalid argument"), tr("No previous page."));
        }
        else {
            mupdf::epubPageNumber = mupdf::epubPageNumber - 1;
            setup_book(book_file, mupdf::epubPageNumber, true);
            ui->text->setText("");
            ui->text->setText(epubPageContent);
            // We always increment pagesTurned regardless whether we press the Previous or Next button
            pagesTurned = pagesTurned + 1;
            writeconfig_pagenumber();
        }
    alignText(textAlignment);
void reader::refreshScreen() {
    if(neverRefresh == true) {
        // Do nothing; "Never refresh" was set
        ;
    }
    else {
        if(pagesTurned >= pageRefreshSetting) {
            // Refreshing the screen
            this->repaint();
            // Reset count
            pagesTurned = 0;
        }
    }
}

void reader::on_optionsBtn_clicked()
{
    menubar_show();
    this->repaint();
}

void reader::on_hideOptionsBtn_clicked()
{
    menubar_hide();
    this->repaint();
}

void reader::on_brightnessDecBtn_clicked()
{
    int bval;
    if(global::isN705 == true or global::isN905C == true) {
        bval = get_brightness();
    }
    else if(global::isN613 == true) {
        setDefaultWorkDir();
        bval = brightness_checkconfig(".config/03-brightness/config");
    }
    else {
        bval = get_brightness();
    int set_bval = bval - 1;
    if(set_bval < 0) {
        set_bval = 0;
    }
    pre_set_brightness(set_bval);
    brightness_writeconfig(set_bval);

    ui->brightnessStatus->setValue(set_bval);
}

void reader::on_brightnessIncBtn_clicked()
{
    int bval;
    if(global::isN705 == true or global::isN905C == true) {
        bval = get_brightness();
    }
    else if(global::isN613 == true) {
        setDefaultWorkDir();
        bval = brightness_checkconfig(".config/03-brightness/config");
    }
    else {
        bval = get_brightness();
    int set_bval = bval + 1;
    if(set_bval > 100) {
        set_bval = 100;
    }
    pre_set_brightness(set_bval);
    brightness_writeconfig(set_bval);

    ui->brightnessStatus->setValue(set_bval);
}

void reader::on_aboutBtn_clicked()
{
    if(checkconfig("/opt/inkbox_genuine") == true) {
        QString aboutmsg = "InkBox is an open-source, Qt-based eBook reader. It aims to bring you the latest Qt features while being also fast and responsive.";
        string_checkconfig_ro("/external_root/opt/isa/version");
        aboutmsg.append("\n\nInkBox ");
        aboutmsg.append(checkconfig_str_val);
        QMessageBox::information(this, tr("Information"), aboutmsg);
    }
    else {
Nicolas Mailloux's avatar
Nicolas Mailloux committed
        QMessageBox::information(this, tr("About"), tr("InkBox is an open-source Qt-based eBook reader. It aims to bring you the latest Qt features while being also fast and responsive."));
    }
}

void reader::on_homeBtn_clicked()
{
    // We're leaving reading mode
    string_writeconfig("/tmp/inkboxReading", "false");
    // Remount tmpfs
    string_writeconfig("/inkbox/remount", "true");
}

void reader::on_fontChooser_currentIndexChanged(const QString &arg1)
{
    if(arg1 == "Roboto") {
        QFont roboto("Roboto");
        ui->text->setFont(roboto);
        string_writeconfig(".config/04-book/font", "Roboto");
    }
    if(arg1 == "Inter") {
        QFont inter("Inter");
        ui->text->setFont(inter);
        string_writeconfig(".config/04-book/font", "Inter");
    }
    if(arg1 == "Source Serif Pro") {
        QFont sourceserif("Source Serif Pro");
        ui->text->setFont(sourceserif);
        string_writeconfig(".config/04-book/font", "Source Serif Pro");
    }
    if(arg1 == "Libre Baskerville") {
        QFont librebaskerville("Libre Baskerville");
        ui->text->setFont(librebaskerville);
        string_writeconfig(".config/04-book/font", "Libre Baskerville");
    }
    if(arg1 == "Noto Mono") {
        QFont notomono("Noto Mono");
        ui->text->setFont(notomono);
        string_writeconfig(".config/04-book/font", "Noto Mono");