From 09c08b2b6f771208921aec9c738b57165cd593f8 Mon Sep 17 00:00:00 2001 From: yggverse Date: Fri, 11 Oct 2024 04:37:06 +0300 Subject: [PATCH] implement tab restore feature --- src/app/browser/window.rs | 2 +- src/app/browser/window/tab.rs | 34 ++++++--------------- src/app/browser/window/tab/item.rs | 31 +++++++++---------- src/app/browser/window/tab/item/database.rs | 27 +++++++++++----- src/app/browser/window/tab/item/page.rs | 19 +++--------- src/app/browser/window/tab/item/widget.rs | 13 +++++--- src/app/browser/window/tab/widget.rs | 4 +-- 7 files changed, 58 insertions(+), 72 deletions(-) diff --git a/src/app/browser/window.rs b/src/app/browser/window.rs index caa67e79..328bc5f3 100644 --- a/src/app/browser/window.rs +++ b/src/app/browser/window.rs @@ -11,7 +11,7 @@ use widget::Widget; use std::sync::Arc; -use gtk::{gio::SimpleAction, glib::GString, Box}; +use gtk::{gio::SimpleAction, Box}; pub struct Window { //header: Arc
, diff --git a/src/app/browser/window/tab.rs b/src/app/browser/window/tab.rs index b72ccefb..57203148 100644 --- a/src/app/browser/window/tab.rs +++ b/src/app/browser/window/tab.rs @@ -10,7 +10,6 @@ use adw::TabView; use gtk::{ gio::SimpleAction, glib::{GString, Propagation}, - prelude::{ActionExt, WidgetExt}, }; use sqlite::Transaction; use std::{cell::RefCell, collections::HashMap, sync::Arc}; @@ -46,7 +45,7 @@ impl Tab { let widget = Arc::new(Widget::new()); // Init events - widget.gobject().connect_close_page(move |_, tab_page| { + widget.gobject().connect_close_page(move |_, _| { /* @TODO // Cleanup HashMap index let id = tab_page.widget_name(); @@ -203,9 +202,6 @@ impl Tab { for item in items { // Register dynamically created tab item in the HashMap index self.index.borrow_mut().insert(item.id(), item.clone()); - - // Append new page - self.append(); } // Append just one blank page if nothing to restore @@ -233,25 +229,15 @@ impl Tab { // Delegate save action to childs let id = Database::last_insert_id(transaction); - // At least one active page wanted to continue - /* @TODO - if let Some(current_page) = self.widget.gobject().current_page() { - // Read collected HashMap index - for (_, item) in self.index.borrow().iter() { - // Get page number as HashMap does not keep order, no page_reorder listener also - match self.widget.gobject().page_num(item.page()) { - Some(page_number) => { - item.save( - transaction, - &id, - &page_number, - &(current_page == page_number), - )?; - } - None => panic!(), // page number expected at this point @TODO Err? - } - } - }; */ + // Read collected HashMap index + for (_, item) in self.index.borrow().iter() { + item.save( + transaction, + &id, + &self.widget.gobject().page_position(item.gobject()), + &item.gobject().is_selected(), + )?; + } } Err(e) => return Err(e.to_string()), } diff --git a/src/app/browser/window/tab/item.rs b/src/app/browser/window/tab/item.rs index ce6a9601..2e0f57df 100644 --- a/src/app/browser/window/tab/item.rs +++ b/src/app/browser/window/tab/item.rs @@ -6,11 +6,10 @@ use database::Database; use page::Page; use widget::Widget; -use adw::TabView; +use adw::{TabPage, TabView}; use gtk::{ gio::SimpleAction, glib::{uuid_string_random, GString}, - Box, }; use sqlite::Transaction; use std::sync::Arc; @@ -35,7 +34,7 @@ impl Item { action_tab_page_navigation_reload: Arc, action_update: Arc, // Options - is_selected_page: bool, + is_selected: bool, ) -> Arc { // Generate unique ID for new page components let id = uuid_string_random(); @@ -50,7 +49,7 @@ impl Item { action_update.clone(), ); - let widget = Widget::new_arc(tab_view, page.gobject(), Some("New page"), is_selected_page); // @TODO + let widget = Widget::new_arc(tab_view, page.gobject(), None, is_selected); // @TODO // Return struct Arc::new(Self { id, page, widget }) @@ -138,7 +137,7 @@ impl Item { action_tab_page_navigation_reload.clone(), action_update.clone(), // Options - true, + record.is_selected, ); // Delegate restore action to the item childs @@ -160,9 +159,15 @@ impl Item { &self, transaction: &Transaction, app_browser_window_tab_id: &i64, - page_number: &u32, + page_position: &i32, + is_selected: &bool, ) -> Result<(), String> { - match Database::add(transaction, app_browser_window_tab_id, page_number) { + match Database::add( + transaction, + app_browser_window_tab_id, + page_position, + is_selected, + ) { Ok(_) => { let id = Database::last_insert_id(transaction); @@ -182,16 +187,8 @@ impl Item { self.id.clone() } - pub fn gobject(&self) -> &Box { - &self.page.gobject() - } - - pub fn page_title(&self) -> Option { - self.page.title() - } - - pub fn page_description(&self) -> Option { - self.page.description() + pub fn gobject(&self) -> &TabPage { + &self.widget.gobject() } // Tools diff --git a/src/app/browser/window/tab/item/database.rs b/src/app/browser/window/tab/item/database.rs index 8694f744..2611c2ae 100644 --- a/src/app/browser/window/tab/item/database.rs +++ b/src/app/browser/window/tab/item/database.rs @@ -3,6 +3,7 @@ use sqlite::{Error, Transaction}; pub struct Table { pub id: i64, // pub app_browser_window_tab_id: i64, not in use + pub is_selected: bool, } pub struct Database { @@ -16,7 +17,8 @@ impl Database { ( `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `app_browser_window_tab_id` INTEGER NOT NULL, - `page_number` INTEGER NOT NULL + `page_position` INTEGER NOT NULL, + `is_selected` INTEGER NOT NULL )", [], ) @@ -25,29 +27,38 @@ impl Database { pub fn add( tx: &Transaction, app_browser_window_tab_id: &i64, - page_number: &u32, + page_position: &i32, + is_selected: &bool, ) -> Result { tx.execute( "INSERT INTO `app_browser_window_tab_item` ( `app_browser_window_tab_id`, - `page_number` - ) VALUES (?, ?)", - [app_browser_window_tab_id, &(*page_number as i64)], + `page_position`, + `is_selected` + ) VALUES (?, ?, ?)", + [ + app_browser_window_tab_id, + &(*page_position as i64), + &(*is_selected as i64), + ], ) } pub fn records(tx: &Transaction, app_browser_window_tab_id: &i64) -> Result, Error> { let mut stmt = tx.prepare( "SELECT `id`, - `app_browser_window_tab_id` FROM `app_browser_window_tab_item` - WHERE `app_browser_window_tab_id` = ? - ORDER BY `page_number` ASC", // just order by, no store in struct wanted + `app_browser_window_tab_id`, + `is_selected` + FROM `app_browser_window_tab_item` + WHERE `app_browser_window_tab_id` = ? + ORDER BY `page_position` ASC", // just order by, no store in struct wanted )?; let result = stmt.query_map([app_browser_window_tab_id], |row| { Ok(Table { id: row.get(0)?, // app_browser_window_tab_id: row.get(1)?, not in use + is_selected: row.get(2)?, }) })?; diff --git a/src/app/browser/window/tab/item/page.rs b/src/app/browser/window/tab/item/page.rs index 216b5882..a003357a 100644 --- a/src/app/browser/window/tab/item/page.rs +++ b/src/app/browser/window/tab/item/page.rs @@ -9,16 +9,13 @@ use navigation::Navigation; use widget::Widget; use gtk::{ - gio::{ - Cancellable, SimpleAction, SimpleActionGroup, SocketClient, SocketProtocol, - TlsCertificateFlags, - }, + gio::{Cancellable, SimpleAction, SocketClient, SocketProtocol, TlsCertificateFlags}, glib::{gformat, GString, Priority, Regex, RegexCompileFlags, RegexMatchFlags, Uri, UriFlags}, prelude::{ - ActionExt, ActionMapExt, BoxExt, IOStreamExt, InputStreamExtManual, OutputStreamExtManual, - SocketClientExt, StaticVariantType, ToVariant, WidgetExt, + ActionExt, IOStreamExt, InputStreamExtManual, OutputStreamExtManual, SocketClientExt, + StaticVariantType, ToVariant, }, - Box, Orientation, + Box, }; use std::{cell::RefCell, path::Path, sync::Arc}; @@ -466,14 +463,6 @@ impl Page { } // Getters - pub fn title(&self) -> Option { - self.meta.borrow().title.clone() - } - - pub fn description(&self) -> Option { - self.meta.borrow().description.clone() - } - pub fn gobject(&self) -> &Box { &self.widget.gobject() } diff --git a/src/app/browser/window/tab/item/widget.rs b/src/app/browser/window/tab/item/widget.rs index 72a51564..7668fd03 100644 --- a/src/app/browser/window/tab/item/widget.rs +++ b/src/app/browser/window/tab/item/widget.rs @@ -2,6 +2,8 @@ use adw::{TabPage, TabView}; use gtk::Box; use std::sync::Arc; +const DEFAULT_TITLE: &str = "New page"; + pub struct Widget { gobject: TabPage, } @@ -12,15 +14,16 @@ impl Widget { tab_view: &TabView, page: &Box, title: Option<&str>, - is_selected_page: bool, + is_selected: bool, ) -> Arc { let gobject = tab_view.append(page); - if let Some(value) = title { - gobject.set_title(value); - } + gobject.set_title(match title { + Some(value) => value, + None => DEFAULT_TITLE, + }); - if is_selected_page { + if is_selected { tab_view.set_selected_page(&gobject); } diff --git a/src/app/browser/window/tab/widget.rs b/src/app/browser/window/tab/widget.rs index 8e03a806..1cbdc0c1 100644 --- a/src/app/browser/window/tab/widget.rs +++ b/src/app/browser/window/tab/widget.rs @@ -1,5 +1,5 @@ -use adw::{TabPage, TabView}; -use gtk::{glib::GString, Box}; +use adw::TabView; +use gtk::glib::GString; pub struct Widget { gobject: TabView,