From 60cacb4babb46ae2ab22ae0b7b7357012887460d Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Sun, 24 Apr 2022 15:44:35 +0200 Subject: Better viewer. Set license to GPL 3. --- src/database.cc | 108 +++++++++++++++++++++++++++++++++++++++++------------- src/database.h | 2 +- src/mainwindow.cc | 38 ++++++++++++------- src/mainwindow.h | 12 ++++-- src/qookie.cc | 3 +- src/recipe.h | 16 +++++--- src/viewer.cc | 96 ++++++++++++++++++++++++++++++++++++++++++++++++ src/viewer.h | 46 +++++++++++++++++++++++ 8 files changed, 272 insertions(+), 49 deletions(-) create mode 100644 src/viewer.cc create mode 100644 src/viewer.h (limited to 'src') diff --git a/src/database.cc b/src/database.cc index 5ae045a..9e34a09 100644 --- a/src/database.cc +++ b/src/database.cc @@ -12,7 +12,7 @@ * * Qookie is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Qookie is distributed in the hope that it will be useful, @@ -58,7 +58,7 @@ std::deque Database::getRecipes() sqlite3_stmt *statement; if(sqlite3_prepare_v2(db, sql.data(), sql.length(), &statement, 0) != SQLITE_OK) { - std::cerr << "Open database failed\n"; + std::cerr << "sqlite3_prepare_v2 failed: " << sqlite3_errmsg(db) << '\n'; return {}; } @@ -73,10 +73,12 @@ std::deque Database::getRecipes() item.id = sqlite3_column_int(statement, 0); int title_size = sqlite3_column_bytes(statement, 1); - item.title.append((const char*)sqlite3_column_blob(statement, 1), title_size); + item.title.append((const char*)sqlite3_column_blob(statement, 1), + title_size); int image_size = sqlite3_column_bytes(statement, 2); - item.image.append((const char*)sqlite3_column_blob(statement, 2), image_size); + item.image.append((const char*)sqlite3_column_blob(statement, 2), + image_size); } else { @@ -90,38 +92,92 @@ std::deque Database::getRecipes() Recipe Database::getRecipe(int id) { - // TODO + bool found{false}; + Recipe recipe; - std::string sql = "select id, title, image from recipe where id=" + id; - sqlite3_stmt *statement; - if(sqlite3_prepare_v2(db, sql.data(), sql.length(), &statement, 0) != SQLITE_OK) { - std::cerr << "Open database failed\n"; - return {}; + std::string sql = + "select id, title, image, instructions from recipe where id=" + + std::to_string(id); + sqlite3_stmt *statement; + if(sqlite3_prepare_v2(db, sql.data(), sql.length(), &statement, 0) != SQLITE_OK) + { + std::cerr << "sqlite3_prepare_v2 failed: " << sqlite3_errmsg(db) << '\n'; + return {}; + } + + int result = 0; + while(true) + { + result = sqlite3_step(statement); + + if(result == SQLITE_ROW) + { + recipe.id = sqlite3_column_int(statement, 0); + + int title_size = sqlite3_column_bytes(statement, 1); + recipe.title.append((const char*)sqlite3_column_blob(statement, 1), + title_size); + + int image_size = sqlite3_column_bytes(statement, 2); + recipe.image.append((const char*)sqlite3_column_blob(statement, 2), + image_size); + + int instructions_size = sqlite3_column_bytes(statement, 3); + recipe.instructions.append((const char*)sqlite3_column_blob(statement, 3), + instructions_size); +} + else + { + break; + } + found = true; + } } - int result = 0; - while(true) + if(!found) { - Recipe item; - result = sqlite3_step(statement); + std::cerr << "id " << id << " not found\n"; + return {}; + } - if(result == SQLITE_ROW) + { + std::string sql = + "select amount, unit, item from ingredients where recipe_id=" + + std::to_string(id);// + " order by position asc"; + sqlite3_stmt *statement; + if(sqlite3_prepare_v2(db, sql.data(), sql.length(), &statement, 0) != SQLITE_OK) { - item.id = sqlite3_column_int(statement, 0); - - int title_size = sqlite3_column_bytes(statement, 1); - item.title.append((const char*)sqlite3_column_blob(statement, 1), title_size); - - int image_size = sqlite3_column_bytes(statement, 2); - item.image.append((const char*)sqlite3_column_blob(statement, 2), image_size); + std::cerr << "sqlite3_prepare_v2 failed: " << sqlite3_errmsg(db) << '\n'; + return {}; } - else + + int result = 0; + while(true) { - break; + Ingredient ingredient; + result = sqlite3_step(statement); + + if(result == SQLITE_ROW) + { + ingredient.amount = sqlite3_column_double(statement, 0); + + int unit_size = sqlite3_column_bytes(statement, 1); + ingredient.unit.append((const char*)sqlite3_column_blob(statement, 1), + unit_size); + + int item_size = sqlite3_column_bytes(statement, 2); + ingredient.item.append((const char*)sqlite3_column_blob(statement, 2), + item_size); + + recipe.ingredients.push_back(ingredient); + } + else + { + break; + } } - return item; } - return {}; // Not found + return recipe; } diff --git a/src/database.h b/src/database.h index 1235551..449f40e 100644 --- a/src/database.h +++ b/src/database.h @@ -12,7 +12,7 @@ * * Qookie is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Qookie is distributed in the hope that it will be useful, diff --git a/src/mainwindow.cc b/src/mainwindow.cc index c1b05f7..eae86d0 100644 --- a/src/mainwindow.cc +++ b/src/mainwindow.cc @@ -12,7 +12,7 @@ * * Qookie is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Qookie is distributed in the hope that it will be useful, @@ -26,6 +26,8 @@ */ #include "mainwindow.h" +#include + #include #include #include @@ -33,6 +35,7 @@ #include #include "database.h" +#include "viewer.h" MainWindow::MainWindow(Database& db) : db(db) @@ -56,21 +59,22 @@ MainWindow::MainWindow(Database& db) // QDockWidget *browser = new QDockWidget("Browser"); listWidget = new QListWidget(this); - listWidget->setIconSize({128, 128}); + listWidget->setIconSize({64, 64}); browser->setWidget(listWidget); // // Create the viewer // -// viewer = new Viewer(); -// setCentralWidget(viewer); + viewer = new Viewer(); + setCentralWidget(viewer); addToolBar(Qt::TopToolBarArea, toolbar); addDockWidget(Qt::LeftDockWidgetArea, browser); -// connect signal: -// void itemChanged(QListWidgetItem *item) in listWidget to itemchanged slot + QObject::connect(listWidget, &QListWidget::currentRowChanged, + this, &MainWindow::itemChanged); + listWidget->setSortingEnabled(true); readDatabase(); } @@ -97,15 +101,23 @@ void MainWindow::readDatabase() icon.addPixmap(QPixmap::fromImage(image)); listItem->setIcon(icon); } + else + { + QIcon icon; + QImage image(QSize({1,1}), QImage::Format_RGBA8888); + image.fill(0); + icon.addPixmap(QPixmap::fromImage(image)); + listItem->setIcon(icon); + } listItem->setData(Qt::UserRole, item.id); - //listItem->setSizeHint({200,200}); listWidget->addItem(listItem); } } -//itemchanged slot(item*) -//{ -// id = item->data(Qt::UserRole); -// auto recipe = db.getRecipe(id); -// viewer->show(recipe); -//} +void MainWindow::itemChanged(int row) +{ + auto item = listWidget->currentItem(); + auto id = item->data(Qt::UserRole).toInt(); + auto recipe = db.getRecipe(id); + viewer->show(recipe); +} diff --git a/src/mainwindow.h b/src/mainwindow.h index 210bf5e..05474f2 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -12,7 +12,7 @@ * * Qookie is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Qookie is distributed in the hope that it will be useful, @@ -27,11 +27,15 @@ #pragma once #include +#include + class QListWidget; +class QListWidgetItem; class Database; +class Viewer; -class MainWindow : - public QMainWindow +class MainWindow + : public QMainWindow { Q_OBJECT public: @@ -40,9 +44,11 @@ public: public slots: // void updateDocumentStatus(bool changed); + void itemChanged(int row); private: void readDatabase(); QListWidget *listWidget; Database& db; + Viewer* viewer{nullptr}; }; diff --git a/src/qookie.cc b/src/qookie.cc index 2a75a63..a6b48b0 100644 --- a/src/qookie.cc +++ b/src/qookie.cc @@ -12,7 +12,7 @@ * * Qookie is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Qookie is distributed in the hope that it will be useful, @@ -39,6 +39,7 @@ int main(int argc, char *argv[]) //Database db("/mnt/atuin/docs/tine/Fritid/Mad/krecipes.krecdb"); MainWindow mainwindow(db); + mainwindow.resize(1280, 768); mainwindow.show(); return qapp.exec(); diff --git a/src/recipe.h b/src/recipe.h index 8e4b579..3b6ef3e 100644 --- a/src/recipe.h +++ b/src/recipe.h @@ -12,7 +12,7 @@ * * Qookie is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Qookie is distributed in the hope that it will be useful, @@ -27,6 +27,7 @@ #pragma once #include +#include struct RecipeItem { @@ -35,13 +36,18 @@ struct RecipeItem std::string image; }; +struct Ingredient +{ + std::string unit; + double amount; + std::string item; +}; + struct Recipe { int id; std::string title; std::string image; - - // . - // . - // . + std::string instructions; + std::vector ingredients; }; diff --git a/src/viewer.cc b/src/viewer.cc new file mode 100644 index 0000000..9ed0dba --- /dev/null +++ b/src/viewer.cc @@ -0,0 +1,96 @@ +/* -*- c++ -*- */ +/*************************************************************************** + * viewer.cc + * + * Sun Apr 24 09:04:57 CEST 2022 + * Copyright 2022 Bent Bisballe Nyeng + * deva@aasimon.org + ****************************************************************************/ + +/* + * This file is part of Qookie. + * + * Qookie is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Qookie is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Qookie; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#include "viewer.h" + +#include + +#include +#include + +#include "recipe.h" + +Viewer::Viewer() +{ + setLayout(new QHBoxLayout()); + textEdit = new QTextEdit(); + layout()->addWidget(textEdit); + textEdit->setReadOnly(true); +} + +void Viewer::show(const Recipe& recipe) +{ + auto instructions = QString::fromUtf8(recipe.instructions.data()); + instructions.replace("\n", "
"); + + QString ingredients; + for(const auto& ingredient : recipe.ingredients) + { + if(ingredient.amount > 0) + { + ingredients += + "
  • " + + QString::number(ingredient.amount) + " " + + QString::fromUtf8(ingredient.unit.data()) + " " + + QString::fromUtf8(ingredient.item.data()) + + "
  • "; + } + else + { + ingredients += + "
  • " + + QString::fromUtf8(ingredient.item.data()) + + "
  • "; + } + } + + QByteArray image(recipe.image.data(), recipe.image.size()); + if(recipe.image.substr(0, 4) == "/9j/") // Image is base64 encoded + { + image = QByteArray::fromBase64(image); + } + + QString html = + "
    " + QString::fromUtf8(recipe.title.data()) + "

    " + "

    " + "" + "

    " + "

    " + QString::fromUtf8(recipe.description.data()) + "

    " + "

    " + "Source: " + QString::fromUtf8(recipe.source.data()) + "
    " + "Cuisine: " + QString::fromUtf8(recipe.cuisine.data()) + "
    " + "Cooktime: " + QString::number(recipe.cooktime / 60) + "min
    " + "Preptime: " + QString::number(recipe.preptime / 60) + "min
    " + "Yields: " + QString::number(recipe.yields) + " " + QString::fromUtf8(recipe.yield_unit.data()) + "
    " + "Tags: " + QString::fromUtf8(recipe.tags[0].data()) + "" + "

    " + "

    Ingredients

    " + "
      " + ingredients + "
    " + "

    Instructions

    " + "

    " + instructions + "

    " + ; + textEdit->setHtml(html); +} diff --git a/src/viewer.h b/src/viewer.h new file mode 100644 index 0000000..f65a53d --- /dev/null +++ b/src/viewer.h @@ -0,0 +1,46 @@ +/* -*- c++ -*- */ +/*************************************************************************** + * viewer.h + * + * Sun Apr 24 09:04:57 CEST 2022 + * Copyright 2022 Bent Bisballe Nyeng + * deva@aasimon.org + ****************************************************************************/ + +/* + * This file is part of Qookie. + * + * Qookie is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Qookie is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Qookie; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#pragma once + +#include + +#include "recipe.h" + +class QTextEdit; + +class Viewer + : public QWidget +{ +Q_OBJECT +public: + Viewer(); + + void show(const Recipe& recipe); + +private: + QTextEdit* textEdit{nullptr}; +}; -- cgit v1.2.3