diff --git a/Cargo.toml b/Cargo.toml index 3b57399..9f4cb6a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -gtk = { version = "0.8.1", package = "gtk4", features = ["v4_12"] } +gtk = { version = "0.8.1", package = "gtk4", features = ["v4_8"] } rand = "0.8.5" rusqlite = "0.31.0" diff --git a/src/main.rs b/src/main.rs index 66a9c35..68bafee 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,6 @@ +// There's no way to pack an appinage with gtk 4.12 as there's no way to put glibc inside an appimage according to https://github.com/AppImageCommunity/pkg2appimage/blob/master/excludelist +// The only way to do that is rollback to gtk 4.8 and rewrite neccesary parts of the program. + #![windows_subsystem = "windows"] mod db; diff --git a/src/ui/cards/edit/imp.rs b/src/ui/cards/edit/imp.rs index 73d1d84..baf6037 100644 --- a/src/ui/cards/edit/imp.rs +++ b/src/ui/cards/edit/imp.rs @@ -4,25 +4,26 @@ use std::fs; use std::sync::{Arc, Mutex}; use std::io::ErrorKind; -use std::path::Path; +use std::path::{Path, PathBuf}; use std::rc::Rc; - use crate::card::Card; use crate::db::*; use crate::ui::cards::new::*; use crate::widgets::card_entry::CardEntry; use glib::subclass::InitializingObject; +use gtk::ffi::GtkFileChooserDialog; use gtk::gio::ListStore; +use gtk::glib::closure::IntoClosureReturnValue; use gtk::glib::object::ObjectExt; use gtk::glib::{clone, closure_local, Object}; use gtk::prelude::WidgetExt; +use gtk::prelude::*; use gtk::subclass::prelude::*; use gtk::{ - gio, glib, Button, CompositeTemplate, ListView, NoSelection, ScrolledWindow, SearchEntry, - Switch, Window, + gio, glib, ApplicationWindow, Button, CompositeTemplate, FileChooserAction, ListView, + NoSelection, ResponseType, ScrolledWindow, SearchEntry, Switch, Window, }; -use gtk::{prelude::*, FileDialog}; use gtk::{ListItem, SignalListItemFactory}; use rusqlite::Connection; use sha256::try_digest; @@ -217,7 +218,6 @@ impl MemoryCardsEditScene { } pub fn query_cards(&self, options: Option) { - let conn = Connection::open(get_db_path()).unwrap(); let selector = match options { @@ -229,29 +229,33 @@ impl MemoryCardsEditScene { "SELECT imagename, hieroglyph, reading, translation, is_learning FROM cards {selector}" ); - let mut stmt = conn.prepare(sql.as_str()).unwrap(); + let mut stmt = conn.prepare(sql.as_str()).unwrap(); let cards_iter = stmt - .query_map([], |row| { - let image_path: String = match row.get(0) { - Ok(path) => path, - Err(_) => String::from(""), - }; - let c = Card::new( - Some(get_images_store_path() + &image_path), - Some(row.get(1).unwrap()), - Some(row.get(2).unwrap()), - Some(row.get(3).unwrap()), - Some(row.get(4).unwrap()), + .query_map([], |row| { + let image_path: String = match row.get(0) { + Ok(path) => path, + Err(_) => String::from(""), + }; + let c = Card::new( + Some(get_images_store_path() + &image_path), + Some(row.get(1).unwrap()), + Some(row.get(2).unwrap()), + Some(row.get(3).unwrap()), + Some(row.get(4).unwrap()), ); - let entry = CardEntry::new(Some(&c)); - entry.update_state(); - Ok(entry) - }) - .unwrap(); + let entry = CardEntry::new(Some(&c)); + entry.update_state(); + Ok(entry) + }) + .unwrap(); self.displaying_cards.lock().unwrap().borrow_mut().clear(); for c in cards_iter { - self.displaying_cards.lock().unwrap().borrow_mut().push(c.unwrap()); + self.displaying_cards + .lock() + .unwrap() + .borrow_mut() + .push(c.unwrap()); } } } @@ -262,46 +266,68 @@ async fn new_card_setup>(window: Rc) { .unwrap(); // Weird casting from &Window as passed in func to &MemoryCardsNewScene let picture_widget = w.get_picture_widget(); - - let dialog: FileDialog = gtk::FileDialog::builder().build(); - let answer = dialog.open_future(Some(&*window)).await; - let path = match answer { - Ok(p) => p, - Err(_) => return, - } - .path() - .unwrap(); - let path: String = path.as_path().to_str().unwrap().to_owned(); - - picture_widget.set_file(Some(&gio::File::for_path(&path))); - - let images_store_path = get_program_home_path() + "/images"; - - match fs::create_dir_all(&images_store_path) { - Ok(_) => {} - Err(error) => match error.kind() { - ErrorKind::AlreadyExists => {} - _ => panic!("Could not create directory for storing images!"), - }, - }; - - w.get_done_button().connect_closure( - "clicked", - false, - closure_local!(@strong w, @strong path => move |_b: &Button| { - let hash = try_digest(&path).unwrap(); - let extenstion = Path::new(path.as_str()).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"); - - let hieroglyph = w.get_hieroglyph_input(); - let conn = Connection::open(get_db_path()).unwrap(); - - conn.execute("UPDATE cards SET imagename = ?1 WHERE hieroglyph = ?2", (&new_filename, &hieroglyph)).unwrap(); - conn.execute("UPDATE cards SET is_learning = TRUE WHERE hieroglyph = ?1", [&hieroglyph]).unwrap(); - }), + let dialog = gtk::FileChooserDialog::new( + Some("Open File"), + Some(Into::<&Window>::into(w.upcast_ref())), + FileChooserAction::Open, + &[ + ("_Cancel", ResponseType::Cancel), + ("_Open", ResponseType::Accept), + ], ); + + let path = RefCell::new(String::from("")); + dialog.run_async(clone!( @strong path, @strong w, @strong picture_widget => move |a, _b| { + let c = a.file().unwrap().path().unwrap().as_os_str().to_owned().to_str().unwrap().to_string(); + println!("{c}"); + *path.borrow_mut() = c; + a.close(); + + picture_widget.set_file(Some(&gio::File::for_path(Path::new(path.borrow().as_str())))); + + let images_store_path = get_program_home_path() + "/images"; + + match fs::create_dir_all(&images_store_path) { + Ok(_) => {} + Err(error) => match error.kind() { + ErrorKind::AlreadyExists => {} + _ => panic!("Could not create directory for storing images!"), + }, + }; + + w.get_done_button().connect_closure( + "clicked", + false, + closure_local!(@strong w, @strong path => move |_b: &Button| { + let p = path.borrow(); + let p = p.as_str(); + let hash = try_digest(path.borrow().as_str()).unwrap(); + let extenstion = Path::new(p).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(&p, stored_image_path).expect("Error copying image to store"); + + let hieroglyph = w.get_hieroglyph_input(); + let conn = Connection::open(get_db_path()).unwrap(); + + conn.execute("UPDATE cards SET imagename = ?1 WHERE hieroglyph = ?2", (&new_filename, &hieroglyph)).unwrap(); + conn.execute("UPDATE cards SET is_learning = TRUE WHERE hieroglyph = ?1", [&hieroglyph]).unwrap(); + }), + ); + })); + + + // let dialog: FileDialog = gtk::FileDialog::builder().build(); + // let answer = Ok(""); + // let answer = dialog.open_future(Some(&*window)).await; + // let path = match answer { + // Ok(p) => p, + // Err(_) => return, + // }; + // .path() + // .unwrap(); + // let path: String = path.as_path().to_str().unwrap().to_owned(); + } impl WidgetImpl for MemoryCardsEditScene {}