Add status page when no updates

This commit is contained in:
Ward from fusion-voyager-3 2024-07-11 10:51:01 +03:00
parent e252712a7e
commit ada5153524
11 changed files with 456 additions and 267 deletions

View File

@ -2,7 +2,7 @@
<project version="4"> <project version="4">
<component name="ProjectModuleManager"> <component name="ProjectModuleManager">
<modules> <modules>
<module fileurl="file://$PROJECT_DIR$/.idea/pikman-update-manager.iml" filepath="$PROJECT_DIR$/.idea/pikman-update-manager.iml" /> <module fileurl="file://$PROJECT_DIR$/.idea/pkg-pikman-update-manager.iml" filepath="$PROJECT_DIR$/.idea/pkg-pikman-update-manager.iml" />
</modules> </modules>
</component> </component>
</project> </project>

View File

@ -59,13 +59,13 @@
&quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;, &quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;,
&quot;RunOnceActivity.rust.reset.selective.auto.import&quot;: &quot;true&quot;, &quot;RunOnceActivity.rust.reset.selective.auto.import&quot;: &quot;true&quot;,
&quot;git-widget-placeholder&quot;: &quot;main&quot;, &quot;git-widget-placeholder&quot;: &quot;main&quot;,
&quot;last_opened_file_path&quot;: &quot;/home/ward/RustroverProjects/pikman-update-manager&quot;, &quot;last_opened_file_path&quot;: &quot;/home/ward/RustroverProjects/pkg-pikman-update-manager&quot;,
&quot;node.js.detected.package.eslint&quot;: &quot;true&quot;, &quot;node.js.detected.package.eslint&quot;: &quot;true&quot;,
&quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;, &quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;,
&quot;nodejs_package_manager_path&quot;: &quot;npm&quot;, &quot;nodejs_package_manager_path&quot;: &quot;npm&quot;,
&quot;org.rust.cargo.project.model.PROJECT_DISCOVERY&quot;: &quot;true&quot;, &quot;org.rust.cargo.project.model.PROJECT_DISCOVERY&quot;: &quot;true&quot;,
&quot;org.rust.cargo.project.model.impl.CargoExternalSystemProjectAware.subscribe.first.balloon&quot;: &quot;&quot;, &quot;org.rust.cargo.project.model.impl.CargoExternalSystemProjectAware.subscribe.first.balloon&quot;: &quot;&quot;,
&quot;org.rust.disableDetachedFileInspection/home/ward/RustroverProjects/pikman-update-manager/src/apt_update_progress_socket/lib.rs&quot;: &quot;true&quot;, &quot;org.rust.disableDetachedFileInspection/home/ward/RustroverProjects/pkg-pikman-update-manager/src/apt_update_progress_socket/lib.rs&quot;: &quot;true&quot;,
&quot;org.rust.first.attach.projects&quot;: &quot;true&quot; &quot;org.rust.first.attach.projects&quot;: &quot;true&quot;
} }
}</component> }</component>

View File

@ -52,5 +52,6 @@
"apt_upgrade_dialog_status_failed": "APT Upgrade Transaction Failed!", "apt_upgrade_dialog_status_failed": "APT Upgrade Transaction Failed!",
"banner_text_no_internet": "Warning: No Internet Connection!", "banner_text_no_internet": "Warning: No Internet Connection!",
"refresh_button_tooltip_text": "Refresh Opened Page", "refresh_button_tooltip_text": "Refresh Opened Page",
"apt_update_page_title": "Native Updates (APT)" "apt_update_page_title": "Native Updates (APT)",
"packages_no_viewport_page_title": "All Native APT Packages are Up to date!"
} }

View File

@ -14,8 +14,9 @@ fn main() {
if std::path::Path::new(json_file_path).exists() { if std::path::Path::new(json_file_path).exists() {
let data = std::fs::read_to_string(json_file_path).expect("Unable to read file"); let data = std::fs::read_to_string(json_file_path).expect("Unable to read file");
let json: serde_json::Value = serde_json::from_str(&data).expect("JSON was not well-formatted"); let json: serde_json::Value =
serde_json::from_str(&data).expect("JSON was not well-formatted");
if let serde_json::Value::Array(exclusions) = &json["exclusions"] { if let serde_json::Value::Array(exclusions) = &json["exclusions"] {
for exclusion in exclusions { for exclusion in exclusions {
match exclusion["package"].as_str() { match exclusion["package"].as_str() {

View File

@ -1,7 +1,7 @@
use pika_unixsocket_tools::apt_update_progress_socket::AptUpdateProgressSocket; use pika_unixsocket_tools::apt_update_progress_socket::AptUpdateProgressSocket;
use pika_unixsocket_tools::pika_unixsocket_tools::*; use pika_unixsocket_tools::pika_unixsocket_tools::*;
use rust_apt::new_cache; use rust_apt::new_cache;
use rust_apt::progress::{AcquireProgress}; use rust_apt::progress::AcquireProgress;
use tokio::runtime::Runtime; use tokio::runtime::Runtime;
fn main() { fn main() {

View File

@ -78,24 +78,46 @@ impl ObjectImpl for AptPackageRow {
let expandable_box = Box::new(Orientation::Vertical, 0); let expandable_box = Box::new(Orientation::Vertical, 0);
obj.connect_package_name_notify(clone!(#[weak] prefix_box, #[weak] expandable_box, #[strong] obj, move |_| { obj.connect_package_name_notify(clone!(
remove_all_children_from_box(&prefix_box); #[weak]
remove_all_children_from_box(&expandable_box); prefix_box,
// #[weak]
let package_name = obj.package_name(); expandable_box,
let package_arch = obj.package_arch(); #[strong]
let package_installed_version= obj.package_installed_version(); obj,
let package_candidate_version= obj.package_candidate_version(); move |_| {
let package_description = obj.package_description(); remove_all_children_from_box(&prefix_box);
let package_source_uri = obj.package_source_uri(); remove_all_children_from_box(&expandable_box);
let package_maintainer = obj.package_maintainer(); //
let package_size = obj.package_size(); let package_name = obj.package_name();
let package_installed_size= obj.package_installed_size(); let package_arch = obj.package_arch();
// let package_installed_version = obj.package_installed_version();
create_prefix_content(&prefix_box, &package_name, &package_arch, &package_installed_version, &package_candidate_version); let package_candidate_version = obj.package_candidate_version();
// let package_description = obj.package_description();
create_expandable_content(&obj, &expandable_box, package_description, package_source_uri, package_maintainer, package_size, package_installed_size); let package_source_uri = obj.package_source_uri();
})); let package_maintainer = obj.package_maintainer();
let package_size = obj.package_size();
let package_installed_size = obj.package_installed_size();
//
create_prefix_content(
&prefix_box,
&package_name,
&package_arch,
&package_installed_version,
&package_candidate_version,
);
//
create_expandable_content(
&obj,
&expandable_box,
package_description,
package_source_uri,
package_maintainer,
package_size,
package_installed_size,
);
}
));
obj.add_prefix(&prefix_box); obj.add_prefix(&prefix_box);
obj.add_row(&expandable_box); obj.add_row(&expandable_box);
@ -108,13 +130,19 @@ impl ObjectImpl for AptPackageRow {
.vexpand(false) .vexpand(false)
.build(); .build();
suffix_toggle.connect_toggled(clone!( #[weak] obj, #[weak] suffix_toggle, move |_| { suffix_toggle.connect_toggled(clone!(
if suffix_toggle.is_active() { #[weak]
obj.emit_by_name::<()>("checkbutton-toggled", &[]); obj,
} else { #[weak]
obj.emit_by_name::<()>("checkbutton-untoggled", &[]); suffix_toggle,
move |_| {
if suffix_toggle.is_active() {
obj.emit_by_name::<()>("checkbutton-toggled", &[]);
} else {
obj.emit_by_name::<()>("checkbutton-untoggled", &[]);
}
} }
})); ));
obj.add_suffix(&suffix_toggle); obj.add_suffix(&suffix_toggle);
@ -183,10 +211,7 @@ fn create_version_badge(installed_version: &str, candidate_version: &str) -> Lis
installed_version_box.append(&installed_version_base_version_label.clone()); installed_version_box.append(&installed_version_base_version_label.clone());
installed_version_box.append(&installed_diff_label); installed_version_box.append(&installed_diff_label);
let label_separator = Separator::builder() let label_separator = Separator::builder().margin_start(5).margin_end(5).build();
.margin_start(5)
.margin_end(5)
.build();
let candidate_version_box = Box::builder() let candidate_version_box = Box::builder()
.halign(Align::Start) .halign(Align::Start)
@ -343,37 +368,65 @@ fn create_expandable_content(
// //
let expandable_bin = Bin::builder().hexpand(true).vexpand(true).build(); let expandable_bin = Bin::builder().hexpand(true).vexpand(true).build();
// //
description_page_button.connect_clicked( description_page_button.connect_clicked(clone!(
clone!(#[strong] expandable_bin, #[strong] description_page_button, move |_|{ #[strong]
expandable_bin,
#[strong]
description_page_button,
move |_| {
if description_page_button.is_active() { if description_page_button.is_active() {
expandable_bin.set_child(Some(&description_stack_page(&package_description))); expandable_bin.set_child(Some(&description_stack_page(&package_description)));
} }
}),
);
extra_info_page_button.connect_clicked(clone!(#[strong] expandable_bin, #[strong] extra_info_page_button, move |_|{
if extra_info_page_button.is_active() {
expandable_bin.set_child(Some(&extra_info_stack_page(&package_maintainer, package_size, package_installed_size)));
} }
})); ));
uris_page_button.connect_clicked( extra_info_page_button.connect_clicked(clone!(
clone!(#[strong] expandable_bin, #[strong] uris_page_button, move |_|{ #[strong]
if uris_page_button.is_active() { expandable_bin,
expandable_bin.set_child(Some(&uris_stack_page(&package_source_uri))); #[strong]
extra_info_page_button,
move |_| {
if extra_info_page_button.is_active() {
expandable_bin.set_child(Some(&extra_info_stack_page(
&package_maintainer,
package_size,
package_installed_size,
)));
} }
}),
);
apt_package_row.connect_expanded_notify(clone!(#[strong] expandable_bin, #[strong] expandable_box, #[strong] apt_package_row, #[strong] description_page_button, move |_| {
if apt_package_row.property("expanded") {
description_page_button.set_active(true);
description_page_button.emit_by_name::<()>("clicked", &[]);
expandable_box.append(&expandable_bin)
} else {
expandable_box.remove(&expandable_bin)
} }
})); ));
uris_page_button.connect_clicked(clone!(
#[strong]
expandable_bin,
#[strong]
uris_page_button,
move |_| {
if uris_page_button.is_active() {
expandable_bin.set_child(Some(&uris_stack_page(&package_source_uri)));
}
}
));
apt_package_row.connect_expanded_notify(clone!(
#[strong]
expandable_bin,
#[strong]
expandable_box,
#[strong]
apt_package_row,
#[strong]
description_page_button,
move |_| {
if apt_package_row.property("expanded") {
description_page_button.set_active(true);
description_page_button.emit_by_name::<()>("clicked", &[]);
expandable_box.append(&expandable_bin)
} else {
expandable_box.remove(&expandable_bin)
}
}
));
//expandable_bin.add_named(&extra_info_stack_page(package_maintainer, package_size, package_installed_size), Some("extra_info_page")); //expandable_bin.add_named(&extra_info_stack_page(package_maintainer, package_size, package_installed_size), Some("extra_info_page"));
// //
} }

View File

@ -1,7 +1,7 @@
mod process; mod process;
use crate::apt_package_row::AptPackageRow; use crate::apt_package_row::AptPackageRow;
use adw::gio::{SimpleAction}; use adw::gio::SimpleAction;
use adw::prelude::*; use adw::prelude::*;
use gtk::glib::*; use gtk::glib::*;
use gtk::*; use gtk::*;
@ -12,9 +12,10 @@ use rust_apt::records::RecordField;
use std::cell::RefCell; use std::cell::RefCell;
use std::process::Command; use std::process::Command;
use std::rc::Rc; use std::rc::Rc;
use std::{thread}; use std::thread;
use tokio::runtime::Runtime; use tokio::runtime::Runtime;
#[derive(Clone)]
pub struct AptPackageSocket { pub struct AptPackageSocket {
pub name: String, pub name: String,
pub arch: String, pub arch: String,
@ -58,7 +59,9 @@ pub fn apt_update_page(
thread::spawn(move || { thread::spawn(move || {
let apt_update_command = Command::new("pkexec") let apt_update_command = Command::new("pkexec")
.args(["/home/ward/RustroverProjects/pikman-update-manager/target/debug/apt_update"]) .args([
"/home/ward/RustroverProjects/pkg-pikman-update-manager/target/debug/apt_update",
])
.status() .status()
.unwrap(); .unwrap();
match apt_update_command.code().unwrap() { match apt_update_command.code().unwrap() {
@ -99,7 +102,7 @@ pub fn apt_update_page(
.sensitive(false) .sensitive(false)
.build(); .build();
packages_boxedlist.add_css_class("boxed-list"); packages_boxedlist.add_css_class("boxed-list");
let packages_viewport = ScrolledWindow::builder() let packages_viewport = ScrolledWindow::builder()
.vexpand(true) .vexpand(true)
.hexpand(true) .hexpand(true)
@ -111,15 +114,22 @@ pub fn apt_update_page(
.child(&packages_boxedlist) .child(&packages_boxedlist)
.build(); .build();
let apt_update_dialog_child_box = Box::builder() let packages_no_viewport_page = adw::StatusPage::builder()
.orientation(Orientation::Vertical) .icon_name("emblem-default-symbolic")
.title(t!("packages_no_viewport_page_title"))
.hexpand(true)
.vexpand(true)
.build(); .build();
let apt_update_dialog_progress_bar = ProgressBar::builder() let viewport_bin = adw::Bin::builder()
.show_text(true) .child(&packages_no_viewport_page)
.hexpand(true)
.build(); .build();
let apt_update_dialog_child_box = Box::builder().orientation(Orientation::Vertical).build();
let apt_update_dialog_progress_bar =
ProgressBar::builder().show_text(true).hexpand(true).build();
let apt_update_dialog_spinner = Spinner::builder() let apt_update_dialog_spinner = Spinner::builder()
.hexpand(true) .hexpand(true)
.valign(Align::Start) .valign(Align::Start)
@ -173,17 +183,24 @@ pub fn apt_update_page(
.label(t!("select_button_deselect_all")) .label(t!("select_button_deselect_all"))
.build(); .build();
select_button.connect_clicked(clone!(#[weak] select_button, #[weak] packages_boxedlist, move |_| { select_button.connect_clicked(clone!(
let select_button_label = select_button.label().unwrap(); #[weak]
let value_to_mark = if select_button_label == t!("select_button_select_all").to_string() { select_button,
true #[weak]
} else if select_button_label == t!("select_button_deselect_all").to_string() { packages_boxedlist,
false move |_| {
} else { let select_button_label = select_button.label().unwrap();
panic!("Unexpected label on selection button") let value_to_mark = if select_button_label == t!("select_button_select_all").to_string()
}; {
set_all_apt_row_marks_to(&packages_boxedlist, value_to_mark) true
})); } else if select_button_label == t!("select_button_deselect_all").to_string() {
false
} else {
panic!("Unexpected label on selection button")
};
set_all_apt_row_marks_to(&packages_boxedlist, value_to_mark)
}
));
let update_button = Button::builder() let update_button = Button::builder()
.halign(Align::End) .halign(Align::End)
@ -196,153 +213,228 @@ pub fn apt_update_page(
.build(); .build();
update_button.add_css_class("destructive-action"); update_button.add_css_class("destructive-action");
update_button.connect_clicked( update_button.connect_clicked(clone!(
clone!(#[weak] window, #[weak] retry_signal_action, #[strong] excluded_updates_vec, move |_| { #[weak]
process::apt_process_update(&excluded_updates_vec.borrow(), window, &retry_signal_action); window,
}), #[weak]
); retry_signal_action,
#[strong]
excluded_updates_vec,
move |_| {
process::apt_process_update(
&excluded_updates_vec.borrow(),
window,
&retry_signal_action,
);
}
));
bottom_bar.append(&select_button); bottom_bar.append(&select_button);
bottom_bar.append(&update_button); bottom_bar.append(&update_button);
let update_percent_server_context = MainContext::default(); let update_percent_server_context = MainContext::default();
// The main loop executes the asynchronous block // The main loop executes the asynchronous block
update_percent_server_context.spawn_local(clone!(#[weak] apt_update_dialog_progress_bar, async move { update_percent_server_context.spawn_local(clone!(
while let Ok(state) = update_percent_receiver.recv().await { #[weak]
apt_update_dialog_progress_bar,
async move {
while let Ok(state) = update_percent_receiver.recv().await {
match state.parse::<f64>() { match state.parse::<f64>() {
Ok(p) => apt_update_dialog_progress_bar.set_fraction(p/100.0), Ok(p) => apt_update_dialog_progress_bar.set_fraction(p / 100.0),
Err(_) => {} Err(_) => {}
} }
}
} }
})); ));
let update_status_server_context = MainContext::default(); let update_status_server_context = MainContext::default();
// The main loop executes the asynchronous block // The main loop executes the asynchronous block
update_status_server_context.spawn_local( update_status_server_context.spawn_local(clone!(
clone!(#[weak] apt_update_dialog, #[weak] apt_update_dialog_child_box, async move { #[weak]
while let Ok(state) = update_status_receiver.recv().await { apt_update_dialog,
match state.as_ref() { #[weak]
"FN_OVERRIDE_SUCCESSFUL" => { apt_update_dialog_child_box,
let get_upgradable_sender = get_upgradable_sender.clone(); async move {
thread::spawn(move || { while let Ok(state) = update_status_receiver.recv().await {
// Create upgradable list cache match state.as_ref() {
let upgradable_cache = new_cache!().unwrap(); "FN_OVERRIDE_SUCCESSFUL" => {
// let get_upgradable_sender = get_upgradable_sender.clone();
upgradable_cache.upgrade(Upgrade::FullUpgrade).unwrap(); thread::spawn(move || {
// Create upgradable list cache
let upgradable_cache = new_cache!().unwrap();
//
upgradable_cache.upgrade(Upgrade::FullUpgrade).unwrap();
upgradable_cache.resolve(true).unwrap(); upgradable_cache.resolve(true).unwrap();
let mut upgradeable_iter = upgradable_cache.get_changes(false).peekable(); let mut upgradeable_iter =
while let Some(pkg) = upgradeable_iter.next() { upgradable_cache.get_changes(false).peekable();
while let Some(pkg) = upgradeable_iter.next() {
if !pkg.marked_delete() { if !pkg.marked_delete() {
let candidate_version_pkg = pkg.candidate().unwrap(); let candidate_version_pkg = pkg.candidate().unwrap();
let package_struct = AptPackageSocket { let package_struct = AptPackageSocket {
name: pkg.name().to_string(), name: pkg.name().to_string(),
arch: pkg.arch().to_string(), arch: pkg.arch().to_string(),
installed_version: match pkg.installed() { installed_version: match pkg.installed() {
Some(t) => t.version().to_string(), Some(t) => t.version().to_string(),
_ => {t!("installed_version_to_be_installed").to_string()} _ => {
}, t!("installed_version_to_be_installed").to_string()
candidate_version: candidate_version_pkg.version().to_string(), }
description: match candidate_version_pkg.description() { },
Some(s) => s, candidate_version: candidate_version_pkg
_ => t!("apt_pkg_property_unknown").to_string() .version()
}, .to_string(),
source_uri: candidate_version_pkg.uris().collect::<Vec<String>>().join("\n"), description: match candidate_version_pkg.description() {
maintainer: match candidate_version_pkg.get_record(RecordField::Maintainer) { Some(s) => s,
Some(s) => s, _ => t!("apt_pkg_property_unknown").to_string(),
_ => t!("apt_pkg_property_unknown").to_string() },
}, source_uri: candidate_version_pkg
size: candidate_version_pkg.size(), .uris()
installed_size: candidate_version_pkg.installed_size(), .collect::<Vec<String>>()
is_last: upgradeable_iter.peek().is_none() .join("\n"),
}; maintainer: match candidate_version_pkg
get_upgradable_sender.send_blocking(package_struct).unwrap() .get_record(RecordField::Maintainer)
{
Some(s) => s,
_ => t!("apt_pkg_property_unknown").to_string(),
},
size: candidate_version_pkg.size(),
installed_size: candidate_version_pkg.installed_size(),
is_last: upgradeable_iter.peek().is_none(),
};
get_upgradable_sender.send_blocking(package_struct).unwrap()
} }
} }
}); });
apt_update_dialog.close(); apt_update_dialog.close();
} }
"FN_OVERRIDE_FAILED" => { "FN_OVERRIDE_FAILED" => {
apt_update_dialog_child_box.set_visible(false); apt_update_dialog_child_box.set_visible(false);
apt_update_dialog.set_extra_child(Some(&Image::builder().pixel_size(128).icon_name("dialog-error-symbolic").halign(Align::Center).build())); apt_update_dialog.set_extra_child(Some(
apt_update_dialog.set_title(Some(&t!("apt_update_dialog_status_failed").to_string())); &Image::builder()
apt_update_dialog.set_response_enabled("apt_update_dialog_retry", true); .pixel_size(128)
.icon_name("dialog-error-symbolic")
.halign(Align::Center)
.build(),
));
apt_update_dialog
.set_title(Some(&t!("apt_update_dialog_status_failed").to_string()));
apt_update_dialog.set_response_enabled("apt_update_dialog_retry", true);
}
_ => apt_update_dialog.set_body(&state),
} }
_ => apt_update_dialog.set_body(&state)
} }
} }
}), ));
);
let get_upgradable_server_context = MainContext::default(); let get_upgradable_server_context = MainContext::default();
// The main loop executes the asynchronous block // The main loop executes the asynchronous block
get_upgradable_server_context.spawn_local( get_upgradable_server_context.spawn_local(clone!(
clone!(#[weak] select_button, #[weak] update_button, #[weak] packages_boxedlist, #[strong] excluded_updates_vec, async move { #[strong]
while let Ok(state) = get_upgradable_receiver.recv().await { select_button,
let apt_row = AptPackageRow::new(AptPackageSocket { #[strong]
name: state.name, update_button,
arch: state.arch, #[strong]
installed_version: state.installed_version, packages_boxedlist,
candidate_version: state.candidate_version, #[strong]
description: state.description, packages_viewport,
source_uri: state.source_uri, #[strong]
maintainer: state.maintainer, viewport_bin,
size: state.size, #[strong]
installed_size: state.installed_size, excluded_updates_vec,
is_last: state.is_last async move {
}); while let Ok(state) = get_upgradable_receiver.recv().await {
viewport_bin.set_child(Some(&packages_viewport));
let apt_row = AptPackageRow::new(state.clone());
apt_row.connect_closure( apt_row.connect_closure(
"checkbutton-toggled", "checkbutton-toggled",
false, false,
closure_local!(#[strong] select_button, #[strong] update_button, #[strong] packages_boxedlist, #[strong] excluded_updates_vec, move |apt_row: AptPackageRow| { closure_local!(
if is_widget_select_all_ready(&packages_boxedlist) { #[strong]
select_button.set_label(&t!("select_button_select_all").to_string()); select_button,
} else { #[strong]
select_button.set_label(&t!("select_button_deselect_all").to_string()); update_button,
#[strong]
packages_boxedlist,
#[strong]
excluded_updates_vec,
move |apt_row: AptPackageRow| {
if is_widget_select_all_ready(&packages_boxedlist) {
select_button
.set_label(&t!("select_button_select_all").to_string());
} else {
select_button
.set_label(&t!("select_button_deselect_all").to_string());
}
update_button
.set_sensitive(!is_all_children_unmarked(&packages_boxedlist));
excluded_updates_vec
.borrow_mut()
.retain(|x| x != &apt_row.package_name());
} }
update_button.set_sensitive(!is_all_children_unmarked(&packages_boxedlist)); ),
excluded_updates_vec.borrow_mut().retain(|x| x != &apt_row.package_name());
}),
); );
apt_row.connect_closure( apt_row.connect_closure(
"checkbutton-untoggled", "checkbutton-untoggled",
false, false,
closure_local!(#[strong] select_button, #[strong] update_button, #[strong] packages_boxedlist, #[strong] excluded_updates_vec, move |apt_row: AptPackageRow| { closure_local!(
select_button.set_label(&t!("select_button_select_all").to_string()); #[strong]
update_button.set_sensitive(!is_all_children_unmarked(&packages_boxedlist)); select_button,
excluded_updates_vec.borrow_mut().push(apt_row.package_name()) #[strong]
}), update_button,
#[strong]
packages_boxedlist,
#[strong]
excluded_updates_vec,
move |apt_row: AptPackageRow| {
select_button.set_label(&t!("select_button_select_all").to_string());
update_button
.set_sensitive(!is_all_children_unmarked(&packages_boxedlist));
excluded_updates_vec
.borrow_mut()
.push(apt_row.package_name())
}
),
); );
packages_boxedlist.append(&apt_row); packages_boxedlist.append(&apt_row);
if state.is_last { if state.is_last {
packages_boxedlist.set_sensitive(true); packages_boxedlist.set_sensitive(true);
} }
} }
}),
);
searchbar.connect_search_changed(clone!(#[weak] searchbar, #[weak] packages_boxedlist, move |_| {
let mut counter = packages_boxedlist.first_child();
while let Some(row) = counter {
if row.widget_name() == "AptPackageRow" {
if !searchbar.text().is_empty() {
if row.property::<String>("package-name").to_lowercase().contains(&searchbar.text().to_string().to_lowercase()) {
row.set_property("visible", true);
searchbar.grab_focus();
} else {
row.set_property("visible", false);
}
} else {
row.set_property("visible", true);
}
}
counter = row.next_sibling();
} }
})); ));
searchbar.connect_search_changed(clone!(
#[weak]
searchbar,
#[weak]
packages_boxedlist,
move |_| {
let mut counter = packages_boxedlist.first_child();
while let Some(row) = counter {
if row.widget_name() == "AptPackageRow" {
if !searchbar.text().is_empty() {
if row
.property::<String>("package-name")
.to_lowercase()
.contains(&searchbar.text().to_string().to_lowercase())
{
row.set_property("visible", true);
searchbar.grab_focus();
} else {
row.set_property("visible", false);
}
} else {
row.set_property("visible", true);
}
}
counter = row.next_sibling();
}
}
));
main_box.append(&searchbar); main_box.append(&searchbar);
main_box.append(&packages_viewport); main_box.append(&viewport_bin);
main_box.append(&bottom_bar); main_box.append(&bottom_bar);
apt_update_dialog.present(); apt_update_dialog.present();

View File

@ -10,11 +10,11 @@ use rust_apt::cache::Upgrade;
use rust_apt::new_cache; use rust_apt::new_cache;
use serde::Serialize; use serde::Serialize;
use serde_json::Value; use serde_json::Value;
use std::cell::RefCell;
use std::path::Path; use std::path::Path;
use std::process::Command; use std::process::Command;
use std::{thread};
use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
use std::thread;
use tokio::runtime::Runtime; use tokio::runtime::Runtime;
struct AptChangesInfo { struct AptChangesInfo {
@ -88,11 +88,15 @@ pub fn apt_process_update(
let excluded_updates_alert_dialog_action = let excluded_updates_alert_dialog_action =
SimpleAction::new("excluded_updates_alert_dialog_action", None); SimpleAction::new("excluded_updates_alert_dialog_action", None);
excluded_updates_alert_dialog_action.connect_activate( excluded_updates_alert_dialog_action.connect_activate(clone!(
clone!(#[weak] window, #[weak] retry_signal_action, #[strong] excluded_updates_vec, move |_, _| { #[weak]
apt_confirm_window(&excluded_updates_vec, window, &retry_signal_action) window,
}), #[weak]
); retry_signal_action,
#[strong]
excluded_updates_vec,
move |_, _| { apt_confirm_window(&excluded_updates_vec, window, &retry_signal_action) }
));
if excluded_updates_vec.is_empty() { if excluded_updates_vec.is_empty() {
excluded_updates_alert_dialog_action.activate(None); excluded_updates_alert_dialog_action.activate(None);
@ -136,7 +140,9 @@ fn apt_confirm_window(
pkg.mark_install(true, false); pkg.mark_install(true, false);
} else if change.marked_delete() { } else if change.marked_delete() {
pkg.mark_delete(false); pkg.mark_delete(false);
to_be_removed_packages_vec.borrow_mut().push(pkg.name().to_owned()); to_be_removed_packages_vec
.borrow_mut()
.push(pkg.name().to_owned());
} }
pkg.protect(); pkg.protect();
} }
@ -182,9 +188,7 @@ fn apt_confirm_window(
} }
} }
let apt_confirm_dialog_child_box = Box::builder() let apt_confirm_dialog_child_box = Box::builder().orientation(Orientation::Vertical).build();
.orientation(Orientation::Vertical)
.build();
let apt_update_dialog_badges_size_group = SizeGroup::new(SizeGroupMode::Both); let apt_update_dialog_badges_size_group = SizeGroup::new(SizeGroupMode::Both);
let apt_update_dialog_badges_size_group0 = SizeGroup::new(SizeGroupMode::Both); let apt_update_dialog_badges_size_group0 = SizeGroup::new(SizeGroupMode::Both);
@ -293,21 +297,37 @@ fn apt_confirm_window(
let apt_confirm_start_signal_action = SimpleAction::new("apt_confirm_start", None); let apt_confirm_start_signal_action = SimpleAction::new("apt_confirm_start", None);
apt_confirm_start_signal_action.connect_activate(clone!(#[weak] window, #[strong] retry_signal_action, #[strong] apt_confirm_dialog, move |_, _| { apt_confirm_start_signal_action.connect_activate(clone!(
let retry_signal_action0 = retry_signal_action.clone(); #[weak]
apt_confirm_dialog.clone().choose(None::<&gio::Cancellable>, move |choice| { window,
if choice == "apt_confirm_dialog_confirm" { #[strong]
apt_full_upgrade_from_socket(window, &retry_signal_action0); retry_signal_action,
#[strong]
apt_confirm_dialog,
move |_, _| {
let retry_signal_action0 = retry_signal_action.clone();
apt_confirm_dialog
.clone()
.choose(None::<&gio::Cancellable>, move |choice| {
if choice == "apt_confirm_dialog_confirm" {
apt_full_upgrade_from_socket(window, &retry_signal_action0);
}
});
} }
}); ));
}));
let to_be_removed_packages_borrow = to_be_removed_packages_vec.borrow(); let to_be_removed_packages_borrow = to_be_removed_packages_vec.borrow();
if to_be_removed_packages_borrow.is_empty() { if to_be_removed_packages_borrow.is_empty() {
apt_confirm_start_signal_action.activate(None); apt_confirm_start_signal_action.activate(None);
} else { } else {
let apt_remove_confirm_text_buffer = TextBuffer::builder() let apt_remove_confirm_text_buffer = TextBuffer::builder()
.text(to_be_removed_packages_borrow.iter().map(|x| x.to_string() + "\n").collect::<String>() + "\n") .text(
to_be_removed_packages_borrow
.iter()
.map(|x| x.to_string() + "\n")
.collect::<String>()
+ "\n",
)
.build(); .build();
let apt_remove_confirm_text_view = TextView::builder() let apt_remove_confirm_text_view = TextView::builder()
@ -347,9 +367,9 @@ fn apt_confirm_window(
apt_remove_confirm_dialog.set_close_response("apt_remove_confirm_dialog_cancel"); apt_remove_confirm_dialog.set_close_response("apt_remove_confirm_dialog_cancel");
apt_remove_confirm_dialog.choose(None::<&gio::Cancellable>, move |choice| { apt_remove_confirm_dialog.choose(None::<&gio::Cancellable>, move |choice| {
if choice == "apt_remove_confirm_dialog_confirm" { if choice == "apt_remove_confirm_dialog_confirm" {
apt_confirm_start_signal_action.activate(None); apt_confirm_start_signal_action.activate(None);
} }
}); });
} }
} }
@ -388,7 +408,7 @@ fn apt_full_upgrade_from_socket(
thread::spawn(move || { thread::spawn(move || {
let apt_upgrade_command = Command::new("pkexec") let apt_upgrade_command = Command::new("pkexec")
.args([ .args([
"/home/ward/RustroverProjects/pikman-update-manager/target/debug/apt_full_upgrade", "/home/ward/RustroverProjects/pkg-pikman-update-manager/target/debug/apt_full_upgrade",
]) ])
.status() .status()
.unwrap(); .unwrap();
@ -408,14 +428,10 @@ fn apt_full_upgrade_from_socket(
} }
}); });
let apt_upgrade_dialog_child_box = Box::builder() let apt_upgrade_dialog_child_box = Box::builder().orientation(Orientation::Vertical).build();
.orientation(Orientation::Vertical)
.build();
let apt_upgrade_dialog_progress_bar = ProgressBar::builder() let apt_upgrade_dialog_progress_bar =
.show_text(true) ProgressBar::builder().show_text(true).hexpand(true).build();
.hexpand(true)
.build();
let apt_upgrade_dialog_spinner = Spinner::builder() let apt_upgrade_dialog_spinner = Spinner::builder()
.hexpand(true) .hexpand(true)
@ -441,9 +457,8 @@ fn apt_full_upgrade_from_socket(
&t!("apt_upgrade_dialog_ok_label").to_string(), &t!("apt_upgrade_dialog_ok_label").to_string(),
); );
let apt_upgrade_dialog_child_box_done = Box::builder() let apt_upgrade_dialog_child_box_done =
.orientation(Orientation::Vertical) Box::builder().orientation(Orientation::Vertical).build();
.build();
let apt_upgrade_log_image = Image::builder() let apt_upgrade_log_image = Image::builder()
.pixel_size(128) .pixel_size(128)
@ -467,46 +482,62 @@ fn apt_full_upgrade_from_socket(
let upgrade_percent_server_context = MainContext::default(); let upgrade_percent_server_context = MainContext::default();
// The main loop executes the asynchronous block // The main loop executes the asynchronous block
upgrade_percent_server_context.spawn_local(clone!(#[weak] apt_upgrade_dialog_progress_bar, async move { upgrade_percent_server_context.spawn_local(clone!(
while let Ok(state) = upgrade_percent_receiver.recv().await { #[weak]
match state.as_ref() { apt_upgrade_dialog_progress_bar,
"FN_OVERRIDE_SUCCESSFUL" => {} async move {
_ => { while let Ok(state) = upgrade_percent_receiver.recv().await {
match state.parse::<f64>() { match state.as_ref() {
Ok(p) => apt_upgrade_dialog_progress_bar.set_fraction(p/100.0), "FN_OVERRIDE_SUCCESSFUL" => {}
_ => match state.parse::<f64>() {
Ok(p) => apt_upgrade_dialog_progress_bar.set_fraction(p / 100.0),
Err(_) => {} Err(_) => {}
} },
} }
} }
} }
})); ));
let upgrade_status_server_context = MainContext::default(); let upgrade_status_server_context = MainContext::default();
// The main loop executes the asynchronous block // The main loop executes the asynchronous block
upgrade_status_server_context.spawn_local( upgrade_status_server_context.spawn_local(clone!(
clone!(#[weak] apt_upgrade_dialog, #[weak] apt_upgrade_dialog_child_box, #[strong] apt_upgrade_dialog_child_box_done, #[strong] apt_upgrade_log_image, async move { #[weak]
while let Ok(state) = upgrade_status_receiver.recv().await { apt_upgrade_dialog,
match state.as_ref() { #[weak]
"FN_OVERRIDE_SUCCESSFUL" => { apt_upgrade_dialog_child_box,
#[strong]
apt_upgrade_dialog_child_box_done,
#[strong]
apt_upgrade_log_image,
async move {
while let Ok(state) = upgrade_status_receiver.recv().await {
match state.as_ref() {
"FN_OVERRIDE_SUCCESSFUL" => {
apt_upgrade_dialog_child_box.set_visible(false); apt_upgrade_dialog_child_box.set_visible(false);
apt_upgrade_log_image.set_icon_name(Some("face-cool-symbolic")); apt_upgrade_log_image.set_icon_name(Some("face-cool-symbolic"));
apt_upgrade_dialog.set_extra_child(Some(&apt_upgrade_dialog_child_box_done)); apt_upgrade_dialog
apt_upgrade_dialog.set_title(Some(&t!("apt_upgrade_dialog_status_successful").to_string())); .set_extra_child(Some(&apt_upgrade_dialog_child_box_done));
apt_upgrade_dialog.set_title(Some(
&t!("apt_upgrade_dialog_status_successful").to_string(),
));
apt_upgrade_dialog.set_response_enabled("apt_upgrade_dialog_ok", true); apt_upgrade_dialog.set_response_enabled("apt_upgrade_dialog_ok", true);
} }
"FN_OVERRIDE_FAILED" => { "FN_OVERRIDE_FAILED" => {
apt_upgrade_dialog_child_box.set_visible(false); apt_upgrade_dialog_child_box.set_visible(false);
apt_upgrade_log_image.set_icon_name(Some("dialog-error-symbolic")); apt_upgrade_log_image.set_icon_name(Some("dialog-error-symbolic"));
apt_upgrade_dialog.set_extra_child(Some(&apt_upgrade_dialog_child_box_done)); apt_upgrade_dialog
apt_upgrade_dialog.set_title(Some(&t!("apt_upgrade_dialog_status_failed").to_string())); .set_extra_child(Some(&apt_upgrade_dialog_child_box_done));
apt_upgrade_dialog
.set_title(Some(&t!("apt_upgrade_dialog_status_failed").to_string()));
apt_upgrade_dialog.set_response_enabled("apt_upgrade_dialog_ok", true); apt_upgrade_dialog.set_response_enabled("apt_upgrade_dialog_ok", true);
apt_upgrade_dialog.set_response_enabled("apt_upgrade_dialog_open_log_file", true); apt_upgrade_dialog
.set_response_enabled("apt_upgrade_dialog_open_log_file", true);
} }
_ => apt_upgrade_dialog.set_body(&state) _ => apt_upgrade_dialog.set_body(&state),
}
} }
} }
}), ));
);
let retry_signal_action0 = retry_signal_action.clone(); let retry_signal_action0 = retry_signal_action.clone();

View File

@ -3,7 +3,7 @@ use crate::config::{APP_GITHUB, APP_ICON, APP_ID, VERSION};
use adw::prelude::*; use adw::prelude::*;
use adw::*; use adw::*;
use gtk::glib::{clone, MainContext}; use gtk::glib::{clone, MainContext};
use gtk::{License}; use gtk::License;
use std::cell::RefCell; use std::cell::RefCell;
use std::process::Command; use std::process::Command;
use std::rc::Rc; use std::rc::Rc;
@ -36,28 +36,28 @@ pub fn build_ui(app: &Application) {
let internet_loop_context = MainContext::default(); let internet_loop_context = MainContext::default();
// The main loop executes the asynchronous block // The main loop executes the asynchronous block
internet_loop_context.spawn_local(clone!(#[weak] window_banner, async move { internet_loop_context.spawn_local(clone!(
while let Ok(state) = internet_loop_receiver.recv().await { #[weak]
let banner_text = t!("banner_text_no_internet").to_string(); window_banner,
if state == true { async move {
*internet_connected_status.borrow_mut()=true; while let Ok(state) = internet_loop_receiver.recv().await {
let banner_text = t!("banner_text_no_internet").to_string();
if state == true {
*internet_connected_status.borrow_mut() = true;
if window_banner.title() == banner_text { if window_banner.title() == banner_text {
window_banner.set_revealed(false) window_banner.set_revealed(false)
} }
} else { } else {
*internet_connected_status.borrow_mut()=false; *internet_connected_status.borrow_mut() = false;
window_banner.set_title(&banner_text); window_banner.set_title(&banner_text);
window_banner.set_revealed(true) window_banner.set_revealed(true)
} }
}
} }
})); ));
let window_headerbar = HeaderBar::builder() let window_headerbar = HeaderBar::builder()
.title_widget( .title_widget(&WindowTitle::builder().title(t!("application_name")).build())
&WindowTitle::builder()
.title(t!("application_name"))
.build(),
)
.build(); .build();
let window_adw_view_stack = ViewStack::builder() let window_adw_view_stack = ViewStack::builder()
@ -121,8 +121,7 @@ pub fn build_ui(app: &Application) {
window_headerbar.pack_end(&refresh_button); window_headerbar.pack_end(&refresh_button);
window_headerbar.pack_end(&credits_button); window_headerbar.pack_end(&credits_button);
credits_button credits_button.connect_clicked(move |_| credits_window.present());
.connect_clicked(move |_| credits_window.present());
// show the window // show the window
@ -138,9 +137,20 @@ pub fn build_ui(app: &Application) {
)) ))
.build(); .build();
apt_retry_signal_action.connect_activate(clone!(#[weak] window, #[strong] apt_retry_signal_action, #[strong] apt_update_view_stack_bin, move |_, _| { apt_retry_signal_action.connect_activate(clone!(
apt_update_view_stack_bin.set_child(Some(&apt_update_page::apt_update_page(window, &apt_retry_signal_action))); #[weak]
})); window,
#[strong]
apt_retry_signal_action,
#[strong]
apt_update_view_stack_bin,
move |_, _| {
apt_update_view_stack_bin.set_child(Some(&apt_update_page::apt_update_page(
window,
&apt_retry_signal_action,
)));
}
));
window_adw_view_stack.add_titled_with_icon( window_adw_view_stack.add_titled_with_icon(
&apt_update_view_stack_bin, &apt_update_view_stack_bin,
@ -150,12 +160,16 @@ pub fn build_ui(app: &Application) {
); );
// //
refresh_button.connect_clicked( refresh_button.connect_clicked(clone!(
clone!(#[weak] apt_retry_signal_action, #[weak] window_adw_view_stack, move |_| { #[weak]
apt_retry_signal_action,
#[weak]
window_adw_view_stack,
move |_| {
match window_adw_view_stack.visible_child_name().unwrap().as_str() { match window_adw_view_stack.visible_child_name().unwrap().as_str() {
"apt_update_page" => apt_retry_signal_action.activate(None), "apt_update_page" => apt_retry_signal_action.activate(None),
_ => {} _ => {}
} }
}), }
); ));
} }

View File

@ -1,5 +1,5 @@
use crate::pika_unixsocket_tools::*; use crate::pika_unixsocket_tools::*;
use rust_apt::progress::{DynInstallProgress}; use rust_apt::progress::DynInstallProgress;
use std::process::exit; use std::process::exit;
use tokio::io::AsyncWriteExt; use tokio::io::AsyncWriteExt;
use tokio::net::UnixStream; use tokio::net::UnixStream;

View File

@ -166,10 +166,7 @@ pub async fn start_socket_server_no_log(
match listener.accept().await { match listener.accept().await {
Ok((stream, _)) => { Ok((stream, _)) => {
// Handle the connection in a separate task // Handle the connection in a separate task
task::spawn(handle_client_no_log( task::spawn(handle_client_no_log(stream, buffer_sender.clone()));
stream,
buffer_sender.clone(),
));
} }
Err(e) => { Err(e) => {
// Print error message if a connection fails // Print error message if a connection fails