summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2022-04-23 22:02:06 +0200
committerBent Bisballe Nyeng <deva@aasimon.org>2022-05-26 18:41:20 +0200
commite5d35d6b643dbb8ecbd3ece2a0d84ec93cadbfc1 (patch)
treecedeebe12a5062e1c7d4c644a54297203e29e59e
parent54860b9c436f31cce71afd180e03b4bf93512b58 (diff)
First contact
-rw-r--r--.gitmodules3
-rwxr-xr-xbootstrap.sh3
-rw-r--r--ctor.cc39
m---------libctor0
-rw-r--r--src/database.cc127
-rw-r--r--src/database.h48
-rw-r--r--src/mainwindow.cc111
-rw-r--r--src/mainwindow.h48
-rw-r--r--src/qookie.cc45
-rw-r--r--src/recipe.h47
-rwxr-xr-xtools/add_file64
11 files changed, 535 insertions, 0 deletions
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..4ed319c
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "libctor"]
+ path = libctor
+ url = git://git.ctor.cc/ctor.git
diff --git a/bootstrap.sh b/bootstrap.sh
new file mode 100755
index 0000000..2b62fd9
--- /dev/null
+++ b/bootstrap.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+g++ -std=c++20 ctor.cc -Llibctor/build -lctor -Ilibctor/src -pthread -o ctor
+./ctor configure --ctor-includedir=libctor/src --ctor-libdir=libctor/build
diff --git a/ctor.cc b/ctor.cc
new file mode 100644
index 0000000..a00b2fb
--- /dev/null
+++ b/ctor.cc
@@ -0,0 +1,39 @@
+// -*- c++ -*-
+#include <libctor.h>
+
+namespace
+{
+BuildConfigurations myConfigs()
+{
+ return
+ {
+ {
+ .target = "qookie", // output filename
+ .sources = {
+ "src/qookie.cc",
+ "src/database.cc",
+ "src/mainwindow.cc",
+ "src/moc_mainwindow.cc",
+ },
+ .flags = {
+ .cxxflags = {
+ "-I/usr/include/qt5",
+ "-I/usr/include/qt5/QtCore",
+ "-I/usr/include/qt5/QtGui",
+ "-I/usr/include/qt5/QtWidgets",
+ "-fPIC",
+ },
+ .ldflags = {
+ "-lQt5Core",
+ "-lQt5Gui",
+ "-lQt5Widgets",
+ "-lsqlite3",
+ }
+ },
+ }
+ };
+}
+}
+
+// Register callback
+REG(myConfigs);
diff --git a/libctor b/libctor
new file mode 160000
+Subproject 4b6c99baaef78580375a2575c32ce1b6c30bf8c
diff --git a/src/database.cc b/src/database.cc
new file mode 100644
index 0000000..5ae045a
--- /dev/null
+++ b/src/database.cc
@@ -0,0 +1,127 @@
+/* -*- c++ -*- */
+/***************************************************************************
+ * database.cc
+ *
+ * Sat Apr 23 19:09:12 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 2 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 "database.h"
+
+#include <sqlite3.h>
+#include <iostream>
+
+// https://www.tutorialspoint.com/sqlite/sqlite_c_cpp.htm
+
+Database::Database(const std::string& file)
+{
+ auto rc = sqlite3_open(file.data(), &db); // https://sqlite.org/c3ref/open.html
+ if(rc)
+ {
+ std::cerr << "Can't open database: " << sqlite3_errmsg(db) << '\n';
+ return;
+ }
+ else
+ {
+ std::cout << "Opened database successfully\n";
+ }
+}
+
+Database::~Database()
+{
+ sqlite3_close(db);
+}
+
+std::deque<RecipeItem> Database::getRecipes()
+{
+ std::deque<RecipeItem> items;
+
+ std::string sql = "select id, title, image from recipe";
+ sqlite3_stmt *statement;
+ if(sqlite3_prepare_v2(db, sql.data(), sql.length(), &statement, 0) != SQLITE_OK)
+ {
+ std::cerr << "Open database failed\n";
+ return {};
+ }
+
+ int result = 0;
+ while(true)
+ {
+ RecipeItem item;
+ result = sqlite3_step(statement);
+
+ if(result == SQLITE_ROW)
+ {
+ 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);
+ }
+ else
+ {
+ break;
+ }
+ items.push_back(item);
+ }
+
+ return items;
+}
+
+Recipe Database::getRecipe(int id)
+{
+ // TODO
+
+ 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 {};
+ }
+
+ int result = 0;
+ while(true)
+ {
+ Recipe item;
+ result = sqlite3_step(statement);
+
+ if(result == SQLITE_ROW)
+ {
+ 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);
+ }
+ else
+ {
+ break;
+ }
+ return item;
+ }
+
+ return {}; // Not found
+}
diff --git a/src/database.h b/src/database.h
new file mode 100644
index 0000000..1235551
--- /dev/null
+++ b/src/database.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- */
+/***************************************************************************
+ * database.h
+ *
+ * Sat Apr 23 19:09:12 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 2 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 <string>
+#include <deque>
+#include <string>
+
+#include "recipe.h"
+
+struct sqlite3;
+
+class Database
+{
+public:
+ Database(const std::string& file);
+ ~Database();
+
+ std::deque<RecipeItem> getRecipes();
+ Recipe getRecipe(int id);
+
+private:
+ sqlite3 *db{nullptr};
+};
diff --git a/src/mainwindow.cc b/src/mainwindow.cc
new file mode 100644
index 0000000..c1b05f7
--- /dev/null
+++ b/src/mainwindow.cc
@@ -0,0 +1,111 @@
+/* -*- c++ -*- */
+/***************************************************************************
+ * mainwindow.cc
+ *
+ * Sat Apr 23 18:59:48 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 2 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 "mainwindow.h"
+
+#include <QToolBar>
+#include <QDockWidget>
+#include <QLabel>
+#include <QPixmap>
+#include <QListWidget>
+
+#include "database.h"
+
+MainWindow::MainWindow(Database& db)
+ : db(db)
+{
+ //connect(document, SIGNAL(documentStatusChanged(bool)), this, SLOT(updateDocumentStatus(bool)));
+ //updateDocumentStatus(document->hasChanged());
+
+ //
+ // Create the toolbar
+ //
+ QToolBar *toolbar = new QToolBar("A toolbar");
+
+ QAction *act_load = toolbar->addAction("Load");
+ // connect(act_load, SIGNAL(triggered()), &document, SLOT(load()));
+
+ QAction *act_save = toolbar->addAction("Save");
+ // connect(act_save, SIGNAL(triggered()), &document, SLOT(save()));
+
+ //
+ // Create the browser docking widget
+ //
+ QDockWidget *browser = new QDockWidget("Browser");
+ listWidget = new QListWidget(this);
+ listWidget->setIconSize({128, 128});
+ browser->setWidget(listWidget);
+
+ //
+ // Create the 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
+
+ readDatabase();
+}
+
+MainWindow::~MainWindow()
+{
+}
+
+//void MainWindow::updateDocumentStatus(bool changed)
+//{
+// setWindowTitle(QString("foo bar") + (changed?"*":""));
+//}
+
+void MainWindow::readDatabase()
+{
+ auto items = db.getRecipes();
+ for(const auto& item : items)
+ {
+ QListWidgetItem* listItem = new QListWidgetItem();
+ listItem->setText(QString::fromUtf8(item.title.data()));
+ if(!item.image.empty())
+ {
+ QIcon icon;
+ QImage image = QImage::fromData((const uchar*)item.image.data(), item.image.size());
+ 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);
+//}
diff --git a/src/mainwindow.h b/src/mainwindow.h
new file mode 100644
index 0000000..210bf5e
--- /dev/null
+++ b/src/mainwindow.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- */
+/***************************************************************************
+ * mainwindow.h
+ *
+ * Sat Apr 23 18:59:48 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 2 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 <QMainWindow>
+class QListWidget;
+class Database;
+
+class MainWindow :
+ public QMainWindow
+{
+Q_OBJECT
+public:
+ MainWindow(Database& db);
+ ~MainWindow();
+
+public slots:
+// void updateDocumentStatus(bool changed);
+
+private:
+ void readDatabase();
+ QListWidget *listWidget;
+ Database& db;
+};
diff --git a/src/qookie.cc b/src/qookie.cc
new file mode 100644
index 0000000..2a75a63
--- /dev/null
+++ b/src/qookie.cc
@@ -0,0 +1,45 @@
+/* -*- c++ -*- */
+/***************************************************************************
+ * qookie.cc
+ *
+ * Sat Apr 23 18:40:39 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 2 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 <QApplication>
+
+#include <iostream>
+
+#include "mainwindow.h"
+#include "database.h"
+
+int main(int argc, char *argv[])
+{
+ QApplication qapp(argc, argv);
+
+ Database db("/mnt/atuin/docs/tine/Fritid/Mad/recipes.db");
+ //Database db("/mnt/atuin/docs/tine/Fritid/Mad/krecipes.krecdb");
+
+ MainWindow mainwindow(db);
+ mainwindow.show();
+
+ return qapp.exec();
+}
diff --git a/src/recipe.h b/src/recipe.h
new file mode 100644
index 0000000..8e4b579
--- /dev/null
+++ b/src/recipe.h
@@ -0,0 +1,47 @@
+/* -*- c++ -*- */
+/***************************************************************************
+ * recipe.h
+ *
+ * Sat Apr 23 21:29:02 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 2 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 <string>
+
+struct RecipeItem
+{
+ int id;
+ std::string title;
+ std::string image;
+};
+
+struct Recipe
+{
+ int id;
+ std::string title;
+ std::string image;
+
+ // .
+ // .
+ // .
+};
diff --git a/tools/add_file b/tools/add_file
new file mode 100755
index 0000000..d64275a
--- /dev/null
+++ b/tools/add_file
@@ -0,0 +1,64 @@
+#!/bin/bash
+PROJECT="Qookie"
+
+function allfile() {
+ WHO="`whoami`"
+
+ echo "/* -*- c++ -*- */" > $1;
+ echo "/***************************************************************************" >> $1;
+ echo " * $1" >> $1;
+ echo " *" >> $1 ;
+ echo " * `date`" >> $1;
+ echo -n " * Copyright " >> $1
+ echo -n `date +%Y | xargs` >> $1
+ if [ "$WHO" == "deva" ];
+ then
+ echo " Bent Bisballe Nyeng" >> $1;
+ echo " * deva@aasimon.org" >> $1;
+ fi
+ echo " ****************************************************************************/" >> $1;
+ echo "" >> $1;
+ echo "/*" >> $1;
+ echo " * This file is part of $PROJECT." >> $1;
+ echo " *" >> $1;
+ echo " * $PROJECT is free software; you can redistribute it and/or modify" >> $1;
+ echo " * it under the terms of the GNU General Public License as published by" >> $1;
+ echo " * the Free Software Foundation; either version 2 of the License, or" >> $1;
+ echo " * (at your option) any later version." >> $1;
+ echo " *" >> $1;
+ echo " * $PROJECT is distributed in the hope that it will be useful," >> $1;
+ echo " * but WITHOUT ANY WARRANTY; without even the implied warranty of" >> $1;
+ echo " * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the" >> $1;
+ echo " * GNU General Public License for more details." >> $1;
+ echo " *" >> $1;
+ echo " * You should have received a copy of the GNU General Public License" >> $1;
+ echo " * along with $PROJECT; if not, write to the Free Software" >> $1;
+ echo " * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA." >> $1;
+ echo " */" >> $1;
+}
+
+function ccfile() {
+ local hf=`echo -n $1 | cut -d'.' -f1`.h;
+ hfile $hf;
+
+ allfile $1;
+ echo -n '#include "' >> $1;
+ echo -n $hf >> $1;
+ echo '"' >> $1;
+ echo '' >> $1;
+}
+
+function hfile() {
+ allfile $1;
+ echo "#pragma once" >> $1;
+}
+
+if [ "$#" = "1" ]; then
+if [ "CC" = `echo $1 | cut -d'.' -f2 | tr 'a-z' 'A-Z'` ]; then
+ ccfile $1;
+fi;
+if [ "H" = `echo $1 | cut -d'.' -f2 | tr 'a-z' 'A-Z'` ]; then
+ hfile $1;
+fi;
+else echo "Usage: $0 filename";
+fi;