diff --git a/Cargo.lock b/Cargo.lock index f1cc659e..3dba1d41 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -512,6 +512,26 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "git-version" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad568aa3db0fcbc81f2f116137f263d7304f512a1209b35b85150d3ef88ad19" +dependencies = [ + "git-version-macro", +] + +[[package]] +name = "git-version-macro" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53010ccb100b96a67bc32c0175f0ed1426b31b655d562898e57325f81c023ac0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + [[package]] name = "glib" version = "0.19.7" @@ -965,6 +985,7 @@ dependencies = [ "futures-channel", "futures-lite", "futures-util", + "git-version", "gtk4", "humansize", "itertools", diff --git a/Cargo.toml b/Cargo.toml index 30efe28e..e9b76c84 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,6 +47,7 @@ lrumap = "0.1.0" memmap2 = "0.9.4" page_size = "0.6.0" anyhow = { version = "1.0.79", features = ["backtrace"] } +git-version = "0.3.9" [dev-dependencies] serde = { version = "1.0.196", features = ["derive"] } diff --git a/src/main.rs b/src/main.rs index b0ff0312..137bd317 100644 --- a/src/main.rs +++ b/src/main.rs @@ -52,7 +52,9 @@ fn have_argument(name: &str) -> bool { } fn main() { - if have_argument("--test-cynthion") { + if have_argument("--version") { + println!("Packetry version {}", git_version::git_version!()) + } else if have_argument("--test-cynthion") { let save_captures = have_argument("--save-captures"); test_cynthion::run_test(save_captures); } else { diff --git a/src/ui.rs b/src/ui.rs index 94d0dd3d..9e9f67af 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -11,10 +11,11 @@ use std::sync::Mutex; use anyhow::{Context as ErrorContext, Error, bail}; -use gtk::gio::ListModel; +use gtk::gio::{ActionEntry, ListModel, Menu, MenuItem, SimpleActionGroup}; use gtk::glib::{Object, SignalHandlerId}; use gtk::{ prelude::*, + AboutDialog, Align, Application, ApplicationWindow, @@ -22,9 +23,11 @@ use gtk::{ DropDown, InfoBar, Label, + License, ListItem, ColumnView, ColumnViewColumn, + MenuButton, MessageType, ProgressBar, ResponseType, @@ -370,6 +373,19 @@ pub fn activate(application: &Application) -> Result<(), Error> { let selector = DeviceSelector::new()?; capture_button.set_sensitive(selector.device_available()); + let menu = Menu::new(); + let about_item = MenuItem::new(Some("About..."), Some("actions.about")); + menu.append_item(&about_item); + let menu_button = MenuButton::builder() + .menu_model(&menu) + .build(); + let action_group = SimpleActionGroup::new(); + let action_about = ActionEntry::builder("about") + .activate(|_, _, _| display_error(show_about())) + .build(); + action_group.add_action_entries([action_about]); + window.insert_action_group("actions", Some(&action_group)); + action_bar.pack_start(&open_button); action_bar.pack_start(&save_button); action_bar.pack_start(>k::Separator::new(Orientation::Vertical)); @@ -377,6 +393,7 @@ pub fn activate(application: &Application) -> Result<(), Error> { action_bar.pack_start(&capture_button); action_bar.pack_start(&stop_button); action_bar.pack_start(&selector.container); + action_bar.pack_end(&menu_button); let warning = DeviceWarning::new(); warning.update(selector.device_unusable()); @@ -977,6 +994,32 @@ pub fn stop_cynthion() -> Result<(), Error> { }) } +fn show_about() -> Result<(), Error> { + const GIT_VERSION: &str = git_version::git_version!(); + const LICENSE: &str = include_str!("../LICENSE"); + let about = AboutDialog::builder() + .program_name("Packetry") + .version(format!("Version: {GIT_VERSION}")) + .comments("A fast, intuitive USB 2.0 protocol analysis application") + .copyright("© 2022-2024 Great Scott Gadgets. All rights reserved.") + .license_type(License::Bsd3) + .license(LICENSE) + .website("https://github.com/greatscottgadgets/packetry/") + .website_label("https://github.com/greatscottgadgets/packetry/") + .system_information(format!( + "OS: {}\n\ + Architecture: {}\n\ + GTK version: {}.{}.{}", + std::env::consts::OS, + std::env::consts::ARCH, + gtk::major_version(), + gtk::minor_version(), + gtk::micro_version())) + .build(); + about.present(); + Ok(()) +} + pub fn display_error(result: Result<(), Error>) { #[cfg(not(test))] if let Err(e) = result {