mod content;
mod database;
mod input;
mod navigation;
mod search;
use super::{Action as ItemAction, Profile, TabAction, WindowAction};
use adw::TabPage;
use anyhow::Result;
use content::Content;
use gtk::prelude::{EditableExt, EntryExt, WidgetExt};
use input::Input;
use navigation::Navigation;
use search::Search;
use sqlite::Transaction;
use std::rc::Rc;
pub struct Page {
pub profile: Rc<Profile>,
pub item_action: Rc<ItemAction>,
pub window_action: Rc<WindowAction>,
pub content: Rc<Content>,
pub input: Rc<Input>,
pub navigation: Rc<Navigation>,
pub search: Rc<Search>,
tab_page: TabPage,
}
impl Page {
pub fn build(
profile: &Rc<Profile>,
(window_action, tab_action, item_action): (
&Rc<WindowAction>,
&Rc<TabAction>,
&Rc<ItemAction>,
),
tab_page: &TabPage,
) -> Self {
let content = Rc::new(Content::build((window_action, tab_action, item_action)));
let search = Rc::new(Search::new());
let navigation = Rc::new(Navigation::build(
profile,
(window_action, tab_action, item_action),
));
let input = Rc::new(Input::new());
Self {
profile: profile.clone(),
tab_page: tab_page.clone(),
item_action: item_action.clone(),
window_action: window_action.clone(),
content,
input,
navigation,
search,
}
}
pub fn bookmark(&self) {
self.navigation.bookmark(Some(&self.title()))
}
pub fn escape(&self) {
use gtk::prelude::RootExt;
self.search.hide();
self.navigation.escape();
self.content
.g_box
.root()
.unwrap()
.set_focus(gtk::Window::NONE);
}
pub fn find(&self) {
self.search.show()
}
pub fn snap_history(&self) {
self.item_action
.history
.add(self.navigation.request.entry.text(), true);
self.profile
.history
.open(self.navigation.request.entry.text(), Some(self.title()))
}
pub fn clean(
&self,
transaction: &Transaction,
app_browser_window_tab_item_id: i64,
) -> Result<()> {
for record in database::select(transaction, app_browser_window_tab_item_id)? {
database::delete(transaction, record.id)?;
self.navigation.clean(transaction, &record.id)?;
}
Ok(())
}
pub fn restore(
&self,
transaction: &Transaction,
app_browser_window_tab_item_id: i64,
) -> Result<()> {
for record in database::select(transaction, app_browser_window_tab_item_id)? {
if let Some(title) = record.title {
self.set_title(title.as_str());
}
self.set_needs_attention(record.is_needs_attention);
self.navigation.restore(transaction, &record.id)?;
self.profile
.history
.open(self.navigation.request.entry.text(), Some(self.title()));
}
Ok(())
}
pub fn save(
&self,
transaction: &Transaction,
app_browser_window_tab_item_id: i64,
) -> Result<()> {
let title = self.tab_page.title();
let id = database::insert(
transaction,
app_browser_window_tab_item_id,
self.tab_page.needs_attention(),
match title.is_empty() {
true => None,
false => Some(title.as_str()),
},
)?;
self.navigation.save(transaction, &id)?;
Ok(())
}
pub fn set_title(&self, title: &str) {
self.tab_page.set_title(title)
}
pub fn set_needs_attention(&self, is_needs_attention: bool) {
self.tab_page.set_needs_attention(is_needs_attention)
}
pub fn set_progress(&self, progress_fraction: f64) {
self.navigation
.request
.entry
.set_progress_fraction(progress_fraction);
self.tab_page.set_loading(progress_fraction > 0.0)
}
pub fn title(&self) -> gtk::glib::GString {
self.tab_page.title()
}
}
pub fn migrate(tx: &Transaction) -> Result<()> {
database::init(tx)?;
navigation::migrate(tx)?;
Ok(())
}