Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
373 changes: 194 additions & 179 deletions Cargo.lock

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ cursive = { version = "0.21", default-features = false }
flate2 = "1"
gettext = "0.4"
git2 = "0.21"
glib = "0.20"
glib-build-tools = "0.20"
glib = "0.22"
glib-build-tools = "0.22"
glob = "0.3"
gpgme = "0.11"
gtk4 = "0.9"
gtk4 = "0.11"
hex = "0.4"
libadwaita = "0.7"
libadwaita = "0.9"
locale_config = "0.3"
man = "0.3"
once_cell = "1"
Expand Down
4 changes: 2 additions & 2 deletions crates/ripasso-gtk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ edition.workspace = true

[dependencies]
ripasso = { workspace = true }
gtk4 = { workspace = true, features = ["v4_6"] }
libadwaita.workspace = true
gtk4 = { workspace = true, features = ["v4_14"] }
libadwaita = { workspace = true, features = ["v1_5"] }
glib.workspace = true
once_cell.workspace = true
hex.workspace = true
Expand Down
6 changes: 3 additions & 3 deletions crates/ripasso-gtk/src/collection_object/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,23 +50,23 @@ impl CollectionObject {
.clone()
}

pub fn git_pull(&self, parent_window: &impl IsA<gtk4::Window>) {
pub fn git_pull(&self, parent_window: &impl IsA<gtk4::Widget>) {
let res = ripasso::git::pull(&self.imp().store.borrow().as_ref().lock().unwrap());

if let Err(e) = res {
error_dialog(&e, parent_window);
}
}

pub fn git_push(&self, parent_window: &impl IsA<gtk4::Window>) {
pub fn git_push(&self, parent_window: &impl IsA<gtk4::Widget>) {
let res = ripasso::git::push(&self.imp().store.borrow().as_ref().lock().unwrap());

if let Err(e) = res {
error_dialog(&e, parent_window);
}
}

pub fn pgp_download(&self, parent_window: &impl IsA<gtk4::Window>) {
pub fn pgp_download(&self, parent_window: &impl IsA<gtk4::Widget>) {
let res = ripasso::pass::pgp_pull(
&mut self.imp().store.borrow_mut().lock().unwrap(),
&self.imp().user_config_dir.borrow(),
Expand Down
2 changes: 1 addition & 1 deletion crates/ripasso-gtk/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,5 @@ fn setup_shortcuts(app: &libadwaita::Application) {
fn build_ui(app: &libadwaita::Application) {
// Create a new custom window and show it
let window = Window::new(app);
window.show();
window.present();
}
163 changes: 75 additions & 88 deletions crates/ripasso-gtk/src/resources/window.ui
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@
<property name="title" translatable="yes">Ripasso</property>
<property name="default_width">650</property>
<property name="default_height">550</property>
<child>
<object class="AdwBreakpoint">
<condition>max-width: 500sp</condition>
<setter object="split_view" property="collapsed">True</setter>
</object>
</child>
<property name="content">
<object class="GtkStack" id="stack">
<property name="transition-type">crossfade</property>
Expand Down Expand Up @@ -74,111 +80,92 @@
<object class="GtkStackPage">
<property name="name">main</property>
<property name="child">
<object class="AdwLeaflet" id="leaflet">
<property name="can-navigate-back">True</property>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="width-request">200</property>
<child>
<object class="AdwHeaderBar">
<binding name="show-end-title-buttons">
<lookup name="folded">leaflet</lookup>
</binding>
<child type="start">
<object class="GtkToggleButton">
<property name="icon-name">list-add-symbolic</property>
<property name="tooltip-text" translatable="yes">New Collection</property>
<property name="action-name">win.new-collection</property>
<object class="AdwNavigationSplitView" id="split_view">
<property name="sidebar">
<object class="AdwNavigationPage">
<property name="title" translatable="yes">Collections</property>
<property name="child">
<object class="AdwToolbarView">
<child type="top">
<object class="AdwHeaderBar">
<child type="start">
<object class="GtkToggleButton">
<property name="icon-name">list-add-symbolic</property>
<property name="tooltip-text" translatable="yes">New Collection</property>
<property name="action-name">win.new-collection</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="vexpand">True</property>
<property name="child">
<object class="GtkListBox" id="collections_list">
<style>
<class name="navigation-sidebar" />
</style>
<property name="content">
<object class="GtkScrolledWindow">
<property name="vexpand">True</property>
<property name="child">
<object class="GtkListBox" id="collections_list">
<style>
<class name="navigation-sidebar" />
</style>
</object>
</property>
</object>
</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwLeafletPage">
<property name="navigatable">False</property>
<property name="child">
<object class="GtkSeparator" />
</property>
</object>
</child>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="hexpand">True</property>
<property name="width-request">250</property>
<child>
<object class="AdwHeaderBar">
<property name="title-widget">
<object class="AdwWindowTitle" />
</property>
<child type="start">
<object class="GtkButton" id="back_button">
<binding name="visible">
<lookup name="folded">leaflet</lookup>
</binding>
<property name="icon-name">go-previous-symbolic</property>
<property name="tooltip-text" translatable="yes">Back</property>
</object>
</child>
<child type="end">
<object class="GtkMenuButton">
<property name="icon-name">open-menu-symbolic</property>
<property name="menu-model">main-menu</property>
<property name="tooltip-text" translatable="yes">Main Menu</property>
</property>
<property name="content">
<object class="AdwNavigationPage">
<property name="title" translatable="yes">Passwords</property>
<property name="child">
<object class="AdwToolbarView">
<child type="top">
<object class="AdwHeaderBar">
<child type="end">
<object class="GtkMenuButton">
<property name="icon-name">open-menu-symbolic</property>
<property name="menu-model">main-menu</property>
<property name="tooltip-text" translatable="yes">Main Menu</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="vexpand">True</property>
<property name="child">
<object class="AdwClamp">
<property name="content">
<object class="GtkScrolledWindow">
<property name="vexpand">True</property>
<property name="child">
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="margin-top">12</property>
<property name="margin-bottom">12</property>
<property name="margin-start">12</property>
<property name="margin-end">12</property>
<property name="spacing">12</property>
<child>
<object class="GtkEntry" id="entry">
<property name="placeholder-text" translatable="yes">Filter list</property>
<object class="AdwClamp">
<property name="child">
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="margin-top">12</property>
<property name="margin-bottom">12</property>
<property name="margin-start">12</property>
<property name="margin-end">12</property>
<property name="spacing">12</property>
<child>
<object class="GtkEntry" id="entry">
<property name="placeholder-text" translatable="yes">Filter list</property>
</object>
</child>
<child>
<object class="GtkListBox" id="passwords_list">
<property name="visible">False</property>
<property name="selection-mode">none</property>
<style>
<class name="boxed-list" />
</style>
</object>
</child>
</object>
</child>
<child>
<object class="GtkListBox" id="passwords_list">
<property name="visible">False</property>
<property name="selection-mode">none</property>
<style>
<class name="boxed-list" />
</style>
</object>
</child>
</property>
</object>
</property>
</object>
</property>
</object>
</child>
</property>
</object>
</child>
</property>
</object>
</property>
</object>
Expand Down
50 changes: 23 additions & 27 deletions crates/ripasso-gtk/src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,42 +1,38 @@
use std::sync::{Arc, Mutex};

use gtk4::{MessageDialog, prelude::IsA};
use libadwaita::prelude::{DialogExt, GtkWindowExt, WidgetExt};
use gtk4::prelude::{Cast, IsA};
use libadwaita::{AlertDialog, prelude::*};
use ripasso::pass::{Error, PasswordStore};

#[derive(Clone, glib::SharedBoxed)]
#[shared_boxed_type(name = "PasswordStoreBoxed")]
pub struct PasswordStoreBoxed(pub Arc<Mutex<PasswordStore>>);

pub fn error_dialog(error: &Error, transient_for: &impl IsA<gtk4::Window>) {
let dialog = MessageDialog::builder()
.buttons(gtk4::ButtonsType::Ok)
.title("Application Error")
.use_header_bar(0)
.transient_for(transient_for)
.secondary_text(format!("{error}"))
pub fn error_dialog(error: &Error, transient_for: &impl IsA<gtk4::Widget>) {
let dialog = AlertDialog::builder()
.heading("Application Error")
.body(format!("{error}"))
.build();
dialog.add_response("ok", "OK");
dialog.set_default_response(Some("ok"));
dialog.set_close_response("ok");

dialog.connect_response(move |dialog, _| {
// Destroy dialog
dialog.destroy();
});

dialog.show();
dialog.present(Some(transient_for));
}

pub fn error_dialog_standalone(error: &Error) {
let dialog = MessageDialog::builder()
.buttons(gtk4::ButtonsType::Ok)
.title("Application Error")
.use_header_bar(0)
.secondary_text(format!("{error}"))
let dialog = AlertDialog::builder()
.heading("Application Error")
.body(format!("{error}"))
.build();

dialog.connect_response(move |dialog, _| {
// Destroy dialog
dialog.destroy();
});

dialog.show();
dialog.add_response("ok", "OK");
dialog.set_default_response(Some("ok"));
dialog.set_close_response("ok");

// No explicit parent is available here, so present the dialog relative to
// the application's active window if there is one.
let parent = gtk4::gio::Application::default()
.and_then(|app| app.downcast::<libadwaita::Application>().ok())
.and_then(|app| app.active_window());
dialog.present(parent.as_ref());
}
9 changes: 3 additions & 6 deletions crates/ripasso-gtk/src/window/imp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@ use std::{cell::RefCell, path::PathBuf};

use glib::{Propagation, subclass::InitializingObject};
use gtk4::{
Button, CompositeTemplate, Entry, FilterListModel, ListBox, Stack, gio, glib,
glib::SignalHandlerId,
CompositeTemplate, Entry, FilterListModel, ListBox, Stack, gio, glib, glib::SignalHandlerId,
};
use libadwaita::{Leaflet, subclass::prelude::*};
use libadwaita::{NavigationSplitView, subclass::prelude::*};
use once_cell::sync::OnceCell;

use crate::collection_object::CollectionObject;
Expand All @@ -22,11 +21,9 @@ pub struct Window {
#[template_child]
pub collections_list: TemplateChild<ListBox>,
#[template_child]
pub leaflet: TemplateChild<Leaflet>,
pub split_view: TemplateChild<NavigationSplitView>,
#[template_child]
pub stack: TemplateChild<Stack>,
#[template_child]
pub back_button: TemplateChild<Button>,
pub collections: OnceCell<gio::ListStore>,
pub current_collection: RefCell<Option<CollectionObject>>,
pub current_filter_model: RefCell<Option<FilterListModel>>,
Expand Down
Loading
Loading