cards preview are now displaying, some improvements and renaming
This commit is contained in:
parent
8d17e4e474
commit
fa260bb8f5
18
cards.drawio
18
cards.drawio
|
@ -1,6 +1,6 @@
|
||||||
<mxfile host="app.diagrams.net" modified="2024-04-05T10:44:42.193Z" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36" etag="npSfEZ8StWjAv_rJHnvl" version="24.2.2" type="device">
|
<mxfile host="app.diagrams.net" modified="2024-04-05T22:47:36.373Z" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36" etag="5XWwemJAtwHYlzdHloKA" version="24.2.2" type="device">
|
||||||
<diagram id="R2lEEEUBdFMjLlhIrx00" name="Page-1">
|
<diagram id="R2lEEEUBdFMjLlhIrx00" name="Page-1">
|
||||||
<mxGraphModel dx="989" dy="516" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0" extFonts="Permanent Marker^https://fonts.googleapis.com/css?family=Permanent+Marker">
|
<mxGraphModel dx="1434" dy="748" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0" extFonts="Permanent Marker^https://fonts.googleapis.com/css?family=Permanent+Marker">
|
||||||
<root>
|
<root>
|
||||||
<mxCell id="0" />
|
<mxCell id="0" />
|
||||||
<mxCell id="1" parent="0" />
|
<mxCell id="1" parent="0" />
|
||||||
|
@ -28,33 +28,33 @@
|
||||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||||
</mxGeometry>
|
</mxGeometry>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="C-vyLk0tnHw3VtMMgP7b-29" value="image_hash CHAR(64)" style="shape=partialRectangle;overflow=hidden;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;" parent="C-vyLk0tnHw3VtMMgP7b-27" vertex="1">
|
<mxCell id="C-vyLk0tnHw3VtMMgP7b-29" value="imagename CHAR(64)" style="shape=partialRectangle;overflow=hidden;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;" parent="C-vyLk0tnHw3VtMMgP7b-27" vertex="1">
|
||||||
<mxGeometry x="30" width="300" height="30" as="geometry">
|
<mxGeometry x="30" width="300" height="30" as="geometry">
|
||||||
<mxRectangle width="300" height="30" as="alternateBounds" />
|
<mxRectangle width="300" height="30" as="alternateBounds" />
|
||||||
</mxGeometry>
|
</mxGeometry>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="B8Iv1AbKk0bG_LbG7-Me-11" value="" style="shape=partialRectangle;collapsible=0;dropTarget=0;pointerEvents=0;fillColor=none;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;" vertex="1" parent="C-vyLk0tnHw3VtMMgP7b-23">
|
<mxCell id="B8Iv1AbKk0bG_LbG7-Me-11" value="" style="shape=partialRectangle;collapsible=0;dropTarget=0;pointerEvents=0;fillColor=none;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;" parent="C-vyLk0tnHw3VtMMgP7b-23" vertex="1">
|
||||||
<mxGeometry y="90" width="330" height="30" as="geometry" />
|
<mxGeometry y="90" width="330" height="30" as="geometry" />
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="B8Iv1AbKk0bG_LbG7-Me-12" value=" " style="shape=partialRectangle;overflow=hidden;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;" vertex="1" parent="B8Iv1AbKk0bG_LbG7-Me-11">
|
<mxCell id="B8Iv1AbKk0bG_LbG7-Me-12" value=" " style="shape=partialRectangle;overflow=hidden;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;" parent="B8Iv1AbKk0bG_LbG7-Me-11" vertex="1">
|
||||||
<mxGeometry width="30" height="30" as="geometry">
|
<mxGeometry width="30" height="30" as="geometry">
|
||||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||||
</mxGeometry>
|
</mxGeometry>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="B8Iv1AbKk0bG_LbG7-Me-13" value="hieroglyph VARCHAR(2)" style="shape=partialRectangle;overflow=hidden;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;" vertex="1" parent="B8Iv1AbKk0bG_LbG7-Me-11">
|
<mxCell id="B8Iv1AbKk0bG_LbG7-Me-13" value="hieroglyph VARCHAR(2)" style="shape=partialRectangle;overflow=hidden;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;" parent="B8Iv1AbKk0bG_LbG7-Me-11" vertex="1">
|
||||||
<mxGeometry x="30" width="300" height="30" as="geometry">
|
<mxGeometry x="30" width="300" height="30" as="geometry">
|
||||||
<mxRectangle width="300" height="30" as="alternateBounds" />
|
<mxRectangle width="300" height="30" as="alternateBounds" />
|
||||||
</mxGeometry>
|
</mxGeometry>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="B8Iv1AbKk0bG_LbG7-Me-14" value="" style="shape=partialRectangle;collapsible=0;dropTarget=0;pointerEvents=0;fillColor=none;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;" vertex="1" parent="C-vyLk0tnHw3VtMMgP7b-23">
|
<mxCell id="B8Iv1AbKk0bG_LbG7-Me-14" value="" style="shape=partialRectangle;collapsible=0;dropTarget=0;pointerEvents=0;fillColor=none;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;top=0;left=0;right=0;bottom=0;" parent="C-vyLk0tnHw3VtMMgP7b-23" vertex="1">
|
||||||
<mxGeometry y="120" width="330" height="30" as="geometry" />
|
<mxGeometry y="120" width="330" height="30" as="geometry" />
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="B8Iv1AbKk0bG_LbG7-Me-15" value="" style="shape=partialRectangle;overflow=hidden;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;" vertex="1" parent="B8Iv1AbKk0bG_LbG7-Me-14">
|
<mxCell id="B8Iv1AbKk0bG_LbG7-Me-15" value="" style="shape=partialRectangle;overflow=hidden;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;" parent="B8Iv1AbKk0bG_LbG7-Me-14" vertex="1">
|
||||||
<mxGeometry width="30" height="30" as="geometry">
|
<mxGeometry width="30" height="30" as="geometry">
|
||||||
<mxRectangle width="30" height="30" as="alternateBounds" />
|
<mxRectangle width="30" height="30" as="alternateBounds" />
|
||||||
</mxGeometry>
|
</mxGeometry>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="B8Iv1AbKk0bG_LbG7-Me-16" value="translation VARCHAR(128)" style="shape=partialRectangle;overflow=hidden;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;" vertex="1" parent="B8Iv1AbKk0bG_LbG7-Me-14">
|
<mxCell id="B8Iv1AbKk0bG_LbG7-Me-16" value="reading VARCHAR(128)" style="shape=partialRectangle;overflow=hidden;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;align=left;spacingLeft=6;" parent="B8Iv1AbKk0bG_LbG7-Me-14" vertex="1">
|
||||||
<mxGeometry x="30" width="300" height="30" as="geometry">
|
<mxGeometry x="30" width="300" height="30" as="geometry">
|
||||||
<mxRectangle width="300" height="30" as="alternateBounds" />
|
<mxRectangle width="300" height="30" as="alternateBounds" />
|
||||||
</mxGeometry>
|
</mxGeometry>
|
||||||
|
|
|
@ -32,14 +32,15 @@
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkScrolledWindow" id="cards">
|
<object class="GtkScrolledWindow" id="cards_scrolled_window">
|
||||||
<property name="halign">GTK_ALIGN_FILL</property>
|
<property name="halign">GTK_ALIGN_FILL</property>
|
||||||
<property name="valign">GTK_ALIGN_FILL</property>
|
<property name="valign">GTK_ALIGN_FILL</property>
|
||||||
<property name="vexpand">true</property>
|
<property name="vexpand">true</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="CardEntry" id="first">
|
<object class="GtkBox" id="cards">
|
||||||
<property name="hieroglyph">ka</property>
|
<property name="orientation">vertical</property>
|
||||||
<property name="translation">tr</property>
|
<property name="halign">GTK_ALIGN_FILL</property>
|
||||||
|
<property name="valign">GTK_ALIGN_FILL</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
|
|
|
@ -10,10 +10,9 @@
|
||||||
<property name="halign">GTK_ALIGN_CENTER</property>
|
<property name="halign">GTK_ALIGN_CENTER</property>
|
||||||
<property name="valign">GTK_ALIGN_CENTER</property>
|
<property name="valign">GTK_ALIGN_CENTER</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkPicture" id="image">
|
<object class="GtkPicture" id="picture">
|
||||||
<property name="halign">GTK_ALIGN_CENTER</property>
|
<property name="halign">GTK_ALIGN_CENTER</property>
|
||||||
<property name="valign">GTK_ALIGN_CENTER</property>
|
<property name="valign">GTK_ALIGN_CENTER</property>
|
||||||
<property name="file">/home/leca/Downloads/2648 - SoyBooru.png</property>
|
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<interface>
|
<interface>
|
||||||
<template class="CardEntry" parent="GtkWidget">
|
<template class="CardEntry" parent="GtkWidget">
|
||||||
<property name="image_hash"></property>
|
<property name="imagepath"></property>
|
||||||
<property name="hieroglyph"></property>
|
<property name="hieroglyph"></property>
|
||||||
<property name="translation"></property>
|
<property name="reading"></property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkPicture" id="picture">
|
<object class="GtkPicture" id="picture">
|
||||||
<property name="halign">GTK_ALIGN_CENTER</property>
|
<property name="halign">GTK_ALIGN_CENTER</property>
|
||||||
|
@ -17,7 +17,7 @@
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel" id="translation_label">
|
<object class="GtkLabel" id="reading_label">
|
||||||
<property name="halign">GTK_ALIGN_START</property>
|
<property name="halign">GTK_ALIGN_START</property>
|
||||||
<property name="valign">GTK_ALIGN_START</property>
|
<property name="valign">GTK_ALIGN_START</property>
|
||||||
</object>
|
</object>
|
||||||
|
|
55
src/db.rs
55
src/db.rs
|
@ -1,43 +1,62 @@
|
||||||
use rusqlite::Connection;
|
use rusqlite::Connection;
|
||||||
|
|
||||||
use std::{sync::RwLock, path::PathBuf, process::Command};
|
use std::{fs, io::ErrorKind, path::PathBuf, sync::RwLock};
|
||||||
|
|
||||||
pub static PROGRAM_HOME_PATH: RwLock<std::string::String> = RwLock::new(String::new());
|
pub static PROGRAM_HOME_PATH: RwLock<std::string::String> = RwLock::new(String::new());
|
||||||
|
pub static DB_PATH: RwLock<std::string::String> = RwLock::new(String::new());
|
||||||
|
pub static IMAGES_STORE_PATH: RwLock<std::string::String> = RwLock::new(String::new());
|
||||||
|
|
||||||
pub fn init() {
|
pub fn init() {
|
||||||
let program_home_path = if cfg!(target_os = "windows") {
|
let program_home_path = if cfg!(target_os = "windows") {
|
||||||
let binding = std::env::var("APP_DATA").expect("No APP_DATA directory");
|
let binding = std::env::var("APP_DATA").expect("No APP_DATA directory");
|
||||||
let mut appdata = PathBuf::from(&binding);
|
let appdata = PathBuf::from(&binding);
|
||||||
|
|
||||||
appdata = appdata.join("learn-hieroglyph");
|
appdata.join("learn-hieroglyph")
|
||||||
Command::new("mkdir").arg(&appdata).spawn().expect(&format!("Cannot create program's home: {}", &appdata.to_str().unwrap())).wait().unwrap();
|
|
||||||
|
|
||||||
appdata
|
|
||||||
} else {
|
} else {
|
||||||
let binding = std::env::var("HOME").expect("No HOME directory");
|
let binding = std::env::var("HOME").expect("No HOME directory");
|
||||||
let mut home = PathBuf::from(&binding);
|
let home = PathBuf::from(&binding);
|
||||||
|
|
||||||
home = home.join(".config/learn-hieroglyph");
|
home.join(".config/learn-hieroglyph")
|
||||||
Command::new("mkdir").args(["-p", &home.to_str().unwrap()]).spawn().expect(&format!("Cannot create program's home: {}", &home.to_str().unwrap())).wait().unwrap();
|
|
||||||
|
|
||||||
home
|
|
||||||
};
|
};
|
||||||
let mut p = PROGRAM_HOME_PATH.write().unwrap();
|
|
||||||
*p = program_home_path.as_path().to_str().unwrap().to_string();
|
match fs::create_dir_all(&program_home_path) {
|
||||||
|
Ok(_) => {},
|
||||||
|
Err(error) => match error.kind() {
|
||||||
|
ErrorKind::AlreadyExists => {},
|
||||||
|
_ => panic!("Could not create app home folder: {}", &program_home_path.to_str().unwrap())
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut binding = PROGRAM_HOME_PATH.write().unwrap();
|
||||||
|
*binding = program_home_path.as_path().to_str().unwrap().to_string();
|
||||||
|
|
||||||
let db_path = program_home_path.join("db.sqlite");
|
let db_path = program_home_path.join("db.sqlite");
|
||||||
|
let mut binding = DB_PATH.write().unwrap();
|
||||||
|
*binding = db_path.as_path().to_str().unwrap().to_string();
|
||||||
|
|
||||||
|
let images_store_path = program_home_path.join("images/");
|
||||||
|
let mut binding = IMAGES_STORE_PATH.write().unwrap();
|
||||||
|
*binding = images_store_path.as_path().to_str().unwrap().to_string();
|
||||||
|
|
||||||
let connection = Connection::open(db_path).unwrap();
|
let connection = Connection::open(db_path).unwrap();
|
||||||
|
|
||||||
connection.execute("CREATE TABLE IF NOT EXISTS cards (
|
connection.execute("CREATE TABLE IF NOT EXISTS cards (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
image_hash CHAR(64),
|
imagename CHAR(64),
|
||||||
hieroglyph VARCHAR(2),
|
hieroglyph VARCHAR(2),
|
||||||
translation VARCHAR(128)
|
reading VARCHAR(128)
|
||||||
)",()).unwrap();
|
)",()).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_program_home_path() -> &'static RwLock<String> {
|
|
||||||
&PROGRAM_HOME_PATH
|
pub fn get_program_home_path() -> String {
|
||||||
}
|
(*PROGRAM_HOME_PATH.read().unwrap()).clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_db_path() -> String {
|
||||||
|
(*DB_PATH.read().unwrap()).clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_images_store_path() -> String {
|
||||||
|
(*IMAGES_STORE_PATH.read().unwrap()).clone()
|
||||||
|
}
|
||||||
|
|
|
@ -1,15 +1,18 @@
|
||||||
use rusqlite::Connection;
|
use std::fs;
|
||||||
use std::path::{Path, PathBuf};
|
use std::io::ErrorKind;
|
||||||
|
use std::path::Path;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
use crate::db::*;
|
||||||
use crate::ui::cards::new::*;
|
use crate::ui::cards::new::*;
|
||||||
use crate::widgets::card_entry::CardEntry;
|
use crate::widgets::card_entry::CardEntry;
|
||||||
use glib::subclass::InitializingObject;
|
use glib::subclass::InitializingObject;
|
||||||
use gtk::glib::object::ObjectExt;
|
use gtk::glib::object::ObjectExt;
|
||||||
use gtk::glib::{clone, closure_local};
|
use gtk::glib::{clone, closure_local};
|
||||||
use gtk::subclass::prelude::*;
|
use gtk::subclass::prelude::*;
|
||||||
use gtk::{gio, glib, Button, CompositeTemplate, ScrolledWindow, SearchEntry, Window};
|
use gtk::{gio, glib, Box, Button, CompositeTemplate, ScrolledWindow, SearchEntry, Window};
|
||||||
use gtk::{prelude::*, FileDialog};
|
use gtk::{prelude::*, FileDialog};
|
||||||
|
use rusqlite::Connection;
|
||||||
use sha256::try_digest;
|
use sha256::try_digest;
|
||||||
|
|
||||||
#[derive(CompositeTemplate, Default)]
|
#[derive(CompositeTemplate, Default)]
|
||||||
|
@ -20,9 +23,9 @@ pub struct MemoryCardsEditScene {
|
||||||
#[template_child]
|
#[template_child]
|
||||||
pub add_button: TemplateChild<Button>,
|
pub add_button: TemplateChild<Button>,
|
||||||
#[template_child]
|
#[template_child]
|
||||||
pub first: TemplateChild<CardEntry>,
|
pub cards: TemplateChild<Box>,
|
||||||
#[template_child]
|
#[template_child]
|
||||||
pub cards: TemplateChild<ScrolledWindow>,
|
pub cards_scrolled_window: TemplateChild<ScrolledWindow>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[glib::object_subclass]
|
#[glib::object_subclass]
|
||||||
|
@ -55,14 +58,45 @@ impl ObjectImpl for MemoryCardsEditScene {
|
||||||
}));
|
}));
|
||||||
new_win.present();
|
new_win.present();
|
||||||
}));
|
}));
|
||||||
|
self.update_card_list();
|
||||||
|
}
|
||||||
|
|
||||||
let c: &ScrolledWindow = self.cards.as_ref();
|
}
|
||||||
c.set_child(glib::bitflags::__private::core::option::Option::Some(
|
|
||||||
&CardEntry::new(&"a".to_string(), &"a".to_string()),
|
impl MemoryCardsEditScene {
|
||||||
));
|
pub fn update_card_list(&self) {
|
||||||
|
let c: &Box = self.cards.as_ref();
|
||||||
|
|
||||||
|
while c.first_child() != None {
|
||||||
|
c.remove(&c.first_child().unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
let conn = Connection::open(get_db_path()).unwrap();
|
||||||
|
let mut stmt = conn
|
||||||
|
.prepare("SELECT imagename, hieroglyph, reading FROM cards")
|
||||||
|
.unwrap();
|
||||||
|
let cards_iter = stmt
|
||||||
|
.query_map([], |row| {
|
||||||
|
let a: String = row.get(0).unwrap();
|
||||||
|
let b: String = row.get(1).unwrap();
|
||||||
|
let c: String = row.get(2).unwrap();
|
||||||
|
let entry = CardEntry::new(&a, &b, &c);
|
||||||
|
Ok(entry)
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
for card in cards_iter {
|
||||||
|
let card_binding = card.unwrap();
|
||||||
|
let path = get_images_store_path() + &card_binding.imagepath();
|
||||||
|
card_binding.set_imagepath(&*path);
|
||||||
|
card_binding.get_picture_widget().set_file(Some(&gio::File::for_path(&path)));
|
||||||
|
c.append(&card_binding);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async fn file_choose_dialog<W: IsA<gtk::Window>>(window: Rc<W>) {
|
async fn file_choose_dialog<W: IsA<gtk::Window>>(window: Rc<W>) {
|
||||||
let dialog: FileDialog = gtk::FileDialog::builder().build();
|
let dialog: FileDialog = gtk::FileDialog::builder().build();
|
||||||
let answer = dialog.open_future(Some(&*window)).await;
|
let answer = dialog.open_future(Some(&*window)).await;
|
||||||
|
@ -71,21 +105,40 @@ async fn file_choose_dialog<W: IsA<gtk::Window>>(window: Rc<W>) {
|
||||||
let w: &MemoryCardsNewScene = Into::<&Window>::into(window.upcast_ref())
|
let w: &MemoryCardsNewScene = Into::<&Window>::into(window.upcast_ref())
|
||||||
.downcast_ref()
|
.downcast_ref()
|
||||||
.unwrap(); // Weird casting from &Window as passed in func to &MemoryCardsNewScene
|
.unwrap(); // Weird casting from &Window as passed in func to &MemoryCardsNewScene
|
||||||
// w.get_image_widget().set_file(Some(path));
|
|
||||||
w.get_image_widget().set_file(Some(&gio::File::for_path(path)));
|
|
||||||
let binding = Path::new(path);
|
|
||||||
let hash = try_digest(binding).unwrap();
|
|
||||||
|
|
||||||
w.get_done_button().connect_closure("clicked", false, closure_local!(@strong w => move |_b: &Button| {
|
w.get_picture_widget()
|
||||||
let hieroglyph = w.get_hieroglyph_input();
|
.set_file(Some(&gio::File::for_path(path)));
|
||||||
let reading = w.get_reading_input();
|
|
||||||
let program_home_path = &*crate::db::get_program_home_path().read().unwrap().clone();
|
|
||||||
let conn = Connection::open(PathBuf::new().join(program_home_path).join("db.sqlite")).unwrap();
|
|
||||||
|
|
||||||
let query = "INSERT INTO cards (image_hash, hieroglyph, translation) VALUES(?1, ?2, ?3)";
|
let images_store_path = get_program_home_path() + "/images";
|
||||||
conn.execute(query, (&hash, &hieroglyph, &reading)).unwrap();
|
|
||||||
w.close();
|
match fs::create_dir_all(&images_store_path) {
|
||||||
}));
|
Ok(_) => {}
|
||||||
|
Err(error) => match error.kind() {
|
||||||
|
ErrorKind::AlreadyExists => {}
|
||||||
|
_ => panic!("Could not create directory for storing pictures!"),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let hash = try_digest(path).unwrap();
|
||||||
|
let extenstion = Path::new(path).extension().unwrap().to_str().unwrap();
|
||||||
|
let new_filename: String = hash.as_str().to_owned() + "." + extenstion;
|
||||||
|
let stored_image_path = Path::new(&images_store_path).join(&new_filename);
|
||||||
|
fs::copy(path, stored_image_path).expect("Error copying image to store");
|
||||||
|
|
||||||
|
w.get_done_button().connect_closure(
|
||||||
|
"clicked",
|
||||||
|
false,
|
||||||
|
closure_local!(@strong w => move |_b: &Button| {
|
||||||
|
let hieroglyph = w.get_hieroglyph_input();
|
||||||
|
let reading = w.get_reading_input();
|
||||||
|
let conn = Connection::open(get_db_path()).unwrap();
|
||||||
|
|
||||||
|
let query = "INSERT INTO cards (imagename, hieroglyph, reading) VALUES(?1, ?2, ?3)";
|
||||||
|
conn.execute(query, (&new_filename, &hieroglyph, &reading)).unwrap();
|
||||||
|
w.close();
|
||||||
|
|
||||||
|
}),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WidgetImpl for MemoryCardsEditScene {}
|
impl WidgetImpl for MemoryCardsEditScene {}
|
||||||
|
|
|
@ -6,7 +6,7 @@ use gtk::{glib, Button, CompositeTemplate, Entry, Picture};
|
||||||
#[template(resource = "/org/foxarmy/learn-hieroglyph/cards/new/ui.xml")]
|
#[template(resource = "/org/foxarmy/learn-hieroglyph/cards/new/ui.xml")]
|
||||||
pub struct MemoryCardsNewScene {
|
pub struct MemoryCardsNewScene {
|
||||||
#[template_child]
|
#[template_child]
|
||||||
pub image: TemplateChild<Picture>,
|
pub picture: TemplateChild<Picture>,
|
||||||
#[template_child]
|
#[template_child]
|
||||||
pub file_choose_button: TemplateChild<Button>,
|
pub file_choose_button: TemplateChild<Button>,
|
||||||
#[template_child]
|
#[template_child]
|
||||||
|
|
|
@ -21,8 +21,8 @@ impl MemoryCardsNewScene {
|
||||||
self.imp().file_choose_button.as_ref()
|
self.imp().file_choose_button.as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_image_widget(&self) -> &Picture {
|
pub fn get_picture_widget(&self) -> &Picture {
|
||||||
self.imp().image.as_ref()
|
self.imp().picture.as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_hieroglyph_input(&self) -> String {
|
pub fn get_hieroglyph_input(&self) -> String {
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
use glib::subclass::InitializingObject;
|
use glib::subclass::InitializingObject;
|
||||||
use glib::Properties;
|
use glib::Properties;
|
||||||
|
use gtk::gio::File;
|
||||||
use gtk::subclass::prelude::*;
|
use gtk::subclass::prelude::*;
|
||||||
use gtk::{glib, prelude::*, Button, CompositeTemplate, Label, Picture};
|
use gtk::{glib, prelude::*, Button, CompositeTemplate, Label, Picture};
|
||||||
|
|
||||||
|
@ -14,16 +16,15 @@ pub struct CardEntry {
|
||||||
#[template_child]
|
#[template_child]
|
||||||
pub hieroglyph_label: TemplateChild<Label>,
|
pub hieroglyph_label: TemplateChild<Label>,
|
||||||
#[template_child]
|
#[template_child]
|
||||||
pub translation_label: TemplateChild<Label>,
|
pub reading_label: TemplateChild<Label>,
|
||||||
#[template_child]
|
#[template_child]
|
||||||
pub edit_button: TemplateChild<Button>,
|
pub edit_button: TemplateChild<Button>,
|
||||||
|
|
||||||
#[property(get, set)]
|
#[property(get, set)]
|
||||||
image_hash: RefCell<String>,
|
imagepath: RefCell<String>,
|
||||||
#[property(get, set)]
|
#[property(get, set)]
|
||||||
hieroglyph: RefCell<String>,
|
hieroglyph: RefCell<String>,
|
||||||
#[property(get, set)]
|
#[property(get, set)]
|
||||||
translation: RefCell<String>,
|
reading: RefCell<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[glib::object_subclass]
|
#[glib::object_subclass]
|
||||||
|
@ -46,15 +47,22 @@ impl ObjectImpl for CardEntry {
|
||||||
fn constructed(&self) {
|
fn constructed(&self) {
|
||||||
self.parent_constructed();
|
self.parent_constructed();
|
||||||
|
|
||||||
|
let picture_binding: &Picture = self.picture.as_ref();
|
||||||
|
let picture_file: File =
|
||||||
|
File::for_path(Path::new(&String::from(&*self.imagepath.borrow())));
|
||||||
|
picture_binding.set_file(glib::bitflags::__private::core::option::Option::Some(
|
||||||
|
&picture_file,
|
||||||
|
));
|
||||||
|
|
||||||
let hieroglyph_label_binding: &Label = self.hieroglyph_label.as_ref();
|
let hieroglyph_label_binding: &Label = self.hieroglyph_label.as_ref();
|
||||||
self.obj()
|
self.obj()
|
||||||
.bind_property("hieroglyph", hieroglyph_label_binding, "label")
|
.bind_property("hieroglyph", hieroglyph_label_binding, "label")
|
||||||
.sync_create()
|
.sync_create()
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let translation_label_binding: &Label = self.translation_label.as_ref();
|
let reading_label_binding: &Label = self.reading_label.as_ref();
|
||||||
self.obj()
|
self.obj()
|
||||||
.bind_property("translation", translation_label_binding, "label")
|
.bind_property("reading", reading_label_binding, "label")
|
||||||
.sync_create()
|
.sync_create()
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
mod imp;
|
mod imp;
|
||||||
|
|
||||||
use glib::Object;
|
use glib::Object;
|
||||||
use gtk::{gio, glib};
|
use gtk::{gio, glib::{self, subclass::types::ObjectSubclassIsExt}, Picture};
|
||||||
|
|
||||||
glib::wrapper! {
|
glib::wrapper! {
|
||||||
pub struct CardEntry(ObjectSubclass<imp::CardEntry>)
|
pub struct CardEntry(ObjectSubclass<imp::CardEntry>)
|
||||||
|
@ -11,7 +11,15 @@ glib::wrapper! {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CardEntry {
|
impl CardEntry {
|
||||||
pub fn new(hieroglyph: &String, translation: &String) -> Self {
|
pub fn new(image_path: &String, hieroglyph: &String, reading: &String) -> Self {
|
||||||
Object::builder().property("hieroglyph", hieroglyph).property("translation", translation).build()
|
Object::builder()
|
||||||
|
.property("imagepath", image_path)
|
||||||
|
.property("hieroglyph", hieroglyph)
|
||||||
|
.property("reading", reading)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_picture_widget(&self) -> &Picture {
|
||||||
|
self.imp().picture.as_ref()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue