Add status page when no updates
This commit is contained in:
parent
e252712a7e
commit
ada5153524
@ -2,7 +2,7 @@
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<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>
|
||||
</component>
|
||||
</project>
|
||||
|
@ -59,13 +59,13 @@
|
||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||
"RunOnceActivity.rust.reset.selective.auto.import": "true",
|
||||
"git-widget-placeholder": "main",
|
||||
"last_opened_file_path": "/home/ward/RustroverProjects/pikman-update-manager",
|
||||
"last_opened_file_path": "/home/ward/RustroverProjects/pkg-pikman-update-manager",
|
||||
"node.js.detected.package.eslint": "true",
|
||||
"node.js.selected.package.eslint": "(autodetect)",
|
||||
"nodejs_package_manager_path": "npm",
|
||||
"org.rust.cargo.project.model.PROJECT_DISCOVERY": "true",
|
||||
"org.rust.cargo.project.model.impl.CargoExternalSystemProjectAware.subscribe.first.balloon": "",
|
||||
"org.rust.disableDetachedFileInspection/home/ward/RustroverProjects/pikman-update-manager/src/apt_update_progress_socket/lib.rs": "true",
|
||||
"org.rust.disableDetachedFileInspection/home/ward/RustroverProjects/pkg-pikman-update-manager/src/apt_update_progress_socket/lib.rs": "true",
|
||||
"org.rust.first.attach.projects": "true"
|
||||
}
|
||||
}</component>
|
||||
|
@ -52,5 +52,6 @@
|
||||
"apt_upgrade_dialog_status_failed": "APT Upgrade Transaction Failed!",
|
||||
"banner_text_no_internet": "Warning: No Internet Connection!",
|
||||
"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!"
|
||||
}
|
@ -14,7 +14,8 @@ fn main() {
|
||||
|
||||
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 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"] {
|
||||
for exclusion in exclusions {
|
||||
|
@ -1,7 +1,7 @@
|
||||
use pika_unixsocket_tools::apt_update_progress_socket::AptUpdateProgressSocket;
|
||||
use pika_unixsocket_tools::pika_unixsocket_tools::*;
|
||||
use rust_apt::new_cache;
|
||||
use rust_apt::progress::{AcquireProgress};
|
||||
use rust_apt::progress::AcquireProgress;
|
||||
use tokio::runtime::Runtime;
|
||||
|
||||
fn main() {
|
||||
|
@ -78,24 +78,46 @@ impl ObjectImpl for AptPackageRow {
|
||||
|
||||
let expandable_box = Box::new(Orientation::Vertical, 0);
|
||||
|
||||
obj.connect_package_name_notify(clone!(#[weak] prefix_box, #[weak] expandable_box, #[strong] obj, move |_| {
|
||||
remove_all_children_from_box(&prefix_box);
|
||||
remove_all_children_from_box(&expandable_box);
|
||||
//
|
||||
let package_name = obj.package_name();
|
||||
let package_arch = obj.package_arch();
|
||||
let package_installed_version= obj.package_installed_version();
|
||||
let package_candidate_version= obj.package_candidate_version();
|
||||
let package_description = obj.package_description();
|
||||
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.connect_package_name_notify(clone!(
|
||||
#[weak]
|
||||
prefix_box,
|
||||
#[weak]
|
||||
expandable_box,
|
||||
#[strong]
|
||||
obj,
|
||||
move |_| {
|
||||
remove_all_children_from_box(&prefix_box);
|
||||
remove_all_children_from_box(&expandable_box);
|
||||
//
|
||||
let package_name = obj.package_name();
|
||||
let package_arch = obj.package_arch();
|
||||
let package_installed_version = obj.package_installed_version();
|
||||
let package_candidate_version = obj.package_candidate_version();
|
||||
let package_description = obj.package_description();
|
||||
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_row(&expandable_box);
|
||||
@ -108,13 +130,19 @@ impl ObjectImpl for AptPackageRow {
|
||||
.vexpand(false)
|
||||
.build();
|
||||
|
||||
suffix_toggle.connect_toggled(clone!( #[weak] obj, #[weak] suffix_toggle, move |_| {
|
||||
if suffix_toggle.is_active() {
|
||||
obj.emit_by_name::<()>("checkbutton-toggled", &[]);
|
||||
} else {
|
||||
obj.emit_by_name::<()>("checkbutton-untoggled", &[]);
|
||||
suffix_toggle.connect_toggled(clone!(
|
||||
#[weak]
|
||||
obj,
|
||||
#[weak]
|
||||
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);
|
||||
|
||||
@ -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_diff_label);
|
||||
|
||||
let label_separator = Separator::builder()
|
||||
.margin_start(5)
|
||||
.margin_end(5)
|
||||
.build();
|
||||
let label_separator = Separator::builder().margin_start(5).margin_end(5).build();
|
||||
|
||||
let candidate_version_box = Box::builder()
|
||||
.halign(Align::Start)
|
||||
@ -343,37 +368,65 @@ fn create_expandable_content(
|
||||
//
|
||||
let expandable_bin = Bin::builder().hexpand(true).vexpand(true).build();
|
||||
//
|
||||
description_page_button.connect_clicked(
|
||||
clone!(#[strong] expandable_bin, #[strong] description_page_button, move |_|{
|
||||
description_page_button.connect_clicked(clone!(
|
||||
#[strong]
|
||||
expandable_bin,
|
||||
#[strong]
|
||||
description_page_button,
|
||||
move |_| {
|
||||
if description_page_button.is_active() {
|
||||
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(
|
||||
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)));
|
||||
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,
|
||||
)));
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
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"));
|
||||
//
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
mod process;
|
||||
|
||||
use crate::apt_package_row::AptPackageRow;
|
||||
use adw::gio::{SimpleAction};
|
||||
use adw::gio::SimpleAction;
|
||||
use adw::prelude::*;
|
||||
use gtk::glib::*;
|
||||
use gtk::*;
|
||||
@ -12,9 +12,10 @@ use rust_apt::records::RecordField;
|
||||
use std::cell::RefCell;
|
||||
use std::process::Command;
|
||||
use std::rc::Rc;
|
||||
use std::{thread};
|
||||
use std::thread;
|
||||
use tokio::runtime::Runtime;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct AptPackageSocket {
|
||||
pub name: String,
|
||||
pub arch: String,
|
||||
@ -58,7 +59,9 @@ pub fn apt_update_page(
|
||||
|
||||
thread::spawn(move || {
|
||||
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()
|
||||
.unwrap();
|
||||
match apt_update_command.code().unwrap() {
|
||||
@ -111,15 +114,22 @@ pub fn apt_update_page(
|
||||
.child(&packages_boxedlist)
|
||||
.build();
|
||||
|
||||
let apt_update_dialog_child_box = Box::builder()
|
||||
.orientation(Orientation::Vertical)
|
||||
let packages_no_viewport_page = adw::StatusPage::builder()
|
||||
.icon_name("emblem-default-symbolic")
|
||||
.title(t!("packages_no_viewport_page_title"))
|
||||
.hexpand(true)
|
||||
.vexpand(true)
|
||||
.build();
|
||||
|
||||
let apt_update_dialog_progress_bar = ProgressBar::builder()
|
||||
.show_text(true)
|
||||
.hexpand(true)
|
||||
let viewport_bin = adw::Bin::builder()
|
||||
.child(&packages_no_viewport_page)
|
||||
.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()
|
||||
.hexpand(true)
|
||||
.valign(Align::Start)
|
||||
@ -173,17 +183,24 @@ pub fn apt_update_page(
|
||||
.label(t!("select_button_deselect_all"))
|
||||
.build();
|
||||
|
||||
select_button.connect_clicked(clone!(#[weak] select_button, #[weak] packages_boxedlist, move |_| {
|
||||
let select_button_label = select_button.label().unwrap();
|
||||
let value_to_mark = if select_button_label == t!("select_button_select_all").to_string() {
|
||||
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)
|
||||
}));
|
||||
select_button.connect_clicked(clone!(
|
||||
#[weak]
|
||||
select_button,
|
||||
#[weak]
|
||||
packages_boxedlist,
|
||||
move |_| {
|
||||
let select_button_label = select_button.label().unwrap();
|
||||
let value_to_mark = if select_button_label == t!("select_button_select_all").to_string()
|
||||
{
|
||||
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()
|
||||
.halign(Align::End)
|
||||
@ -196,153 +213,228 @@ pub fn apt_update_page(
|
||||
.build();
|
||||
update_button.add_css_class("destructive-action");
|
||||
|
||||
update_button.connect_clicked(
|
||||
clone!(#[weak] window, #[weak] retry_signal_action, #[strong] excluded_updates_vec, move |_| {
|
||||
process::apt_process_update(&excluded_updates_vec.borrow(), window, &retry_signal_action);
|
||||
}),
|
||||
);
|
||||
update_button.connect_clicked(clone!(
|
||||
#[weak]
|
||||
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(&update_button);
|
||||
|
||||
let update_percent_server_context = MainContext::default();
|
||||
// The main loop executes the asynchronous block
|
||||
update_percent_server_context.spawn_local(clone!(#[weak] apt_update_dialog_progress_bar, async move {
|
||||
while let Ok(state) = update_percent_receiver.recv().await {
|
||||
update_percent_server_context.spawn_local(clone!(
|
||||
#[weak]
|
||||
apt_update_dialog_progress_bar,
|
||||
async move {
|
||||
while let Ok(state) = update_percent_receiver.recv().await {
|
||||
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(_) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
));
|
||||
|
||||
let update_status_server_context = MainContext::default();
|
||||
// The main loop executes the asynchronous block
|
||||
update_status_server_context.spawn_local(
|
||||
clone!(#[weak] apt_update_dialog, #[weak] apt_update_dialog_child_box, async move {
|
||||
while let Ok(state) = update_status_receiver.recv().await {
|
||||
match state.as_ref() {
|
||||
"FN_OVERRIDE_SUCCESSFUL" => {
|
||||
let get_upgradable_sender = get_upgradable_sender.clone();
|
||||
thread::spawn(move || {
|
||||
// Create upgradable list cache
|
||||
let upgradable_cache = new_cache!().unwrap();
|
||||
//
|
||||
upgradable_cache.upgrade(Upgrade::FullUpgrade).unwrap();
|
||||
update_status_server_context.spawn_local(clone!(
|
||||
#[weak]
|
||||
apt_update_dialog,
|
||||
#[weak]
|
||||
apt_update_dialog_child_box,
|
||||
async move {
|
||||
while let Ok(state) = update_status_receiver.recv().await {
|
||||
match state.as_ref() {
|
||||
"FN_OVERRIDE_SUCCESSFUL" => {
|
||||
let get_upgradable_sender = get_upgradable_sender.clone();
|
||||
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();
|
||||
while let Some(pkg) = upgradeable_iter.next() {
|
||||
let mut upgradeable_iter =
|
||||
upgradable_cache.get_changes(false).peekable();
|
||||
while let Some(pkg) = upgradeable_iter.next() {
|
||||
if !pkg.marked_delete() {
|
||||
let candidate_version_pkg = pkg.candidate().unwrap();
|
||||
let package_struct = AptPackageSocket {
|
||||
name: pkg.name().to_string(),
|
||||
arch: pkg.arch().to_string(),
|
||||
installed_version: match pkg.installed() {
|
||||
Some(t) => t.version().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,
|
||||
_ => t!("apt_pkg_property_unknown").to_string()
|
||||
},
|
||||
source_uri: candidate_version_pkg.uris().collect::<Vec<String>>().join("\n"),
|
||||
maintainer: match candidate_version_pkg.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()
|
||||
let package_struct = AptPackageSocket {
|
||||
name: pkg.name().to_string(),
|
||||
arch: pkg.arch().to_string(),
|
||||
installed_version: match pkg.installed() {
|
||||
Some(t) => t.version().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,
|
||||
_ => t!("apt_pkg_property_unknown").to_string(),
|
||||
},
|
||||
source_uri: candidate_version_pkg
|
||||
.uris()
|
||||
.collect::<Vec<String>>()
|
||||
.join("\n"),
|
||||
maintainer: match candidate_version_pkg
|
||||
.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" => {
|
||||
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_title(Some(&t!("apt_update_dialog_status_failed").to_string()));
|
||||
apt_update_dialog.set_response_enabled("apt_update_dialog_retry", true);
|
||||
"FN_OVERRIDE_FAILED" => {
|
||||
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_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();
|
||||
// The main loop executes the asynchronous block
|
||||
get_upgradable_server_context.spawn_local(
|
||||
clone!(#[weak] select_button, #[weak] update_button, #[weak] packages_boxedlist, #[strong] excluded_updates_vec, async move {
|
||||
while let Ok(state) = get_upgradable_receiver.recv().await {
|
||||
let apt_row = AptPackageRow::new(AptPackageSocket {
|
||||
name: state.name,
|
||||
arch: state.arch,
|
||||
installed_version: state.installed_version,
|
||||
candidate_version: state.candidate_version,
|
||||
description: state.description,
|
||||
source_uri: state.source_uri,
|
||||
maintainer: state.maintainer,
|
||||
size: state.size,
|
||||
installed_size: state.installed_size,
|
||||
is_last: state.is_last
|
||||
});
|
||||
get_upgradable_server_context.spawn_local(clone!(
|
||||
#[strong]
|
||||
select_button,
|
||||
#[strong]
|
||||
update_button,
|
||||
#[strong]
|
||||
packages_boxedlist,
|
||||
#[strong]
|
||||
packages_viewport,
|
||||
#[strong]
|
||||
viewport_bin,
|
||||
#[strong]
|
||||
excluded_updates_vec,
|
||||
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(
|
||||
"checkbutton-toggled",
|
||||
false,
|
||||
closure_local!(#[strong] select_button, #[strong] 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());
|
||||
closure_local!(
|
||||
#[strong]
|
||||
select_button,
|
||||
#[strong]
|
||||
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(
|
||||
"checkbutton-untoggled",
|
||||
false,
|
||||
closure_local!(#[strong] select_button, #[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())
|
||||
}),
|
||||
closure_local!(
|
||||
#[strong]
|
||||
select_button,
|
||||
#[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);
|
||||
if state.is_last {
|
||||
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(&packages_viewport);
|
||||
main_box.append(&viewport_bin);
|
||||
main_box.append(&bottom_bar);
|
||||
|
||||
apt_update_dialog.present();
|
||||
|
@ -10,11 +10,11 @@ use rust_apt::cache::Upgrade;
|
||||
use rust_apt::new_cache;
|
||||
use serde::Serialize;
|
||||
use serde_json::Value;
|
||||
use std::cell::RefCell;
|
||||
use std::path::Path;
|
||||
use std::process::Command;
|
||||
use std::{thread};
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
use std::thread;
|
||||
use tokio::runtime::Runtime;
|
||||
|
||||
struct AptChangesInfo {
|
||||
@ -88,11 +88,15 @@ pub fn apt_process_update(
|
||||
let excluded_updates_alert_dialog_action =
|
||||
SimpleAction::new("excluded_updates_alert_dialog_action", None);
|
||||
|
||||
excluded_updates_alert_dialog_action.connect_activate(
|
||||
clone!(#[weak] window, #[weak] retry_signal_action, #[strong] excluded_updates_vec, move |_, _| {
|
||||
apt_confirm_window(&excluded_updates_vec, window, &retry_signal_action)
|
||||
}),
|
||||
);
|
||||
excluded_updates_alert_dialog_action.connect_activate(clone!(
|
||||
#[weak]
|
||||
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() {
|
||||
excluded_updates_alert_dialog_action.activate(None);
|
||||
@ -136,7 +140,9 @@ fn apt_confirm_window(
|
||||
pkg.mark_install(true, false);
|
||||
} else if change.marked_delete() {
|
||||
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();
|
||||
}
|
||||
@ -182,9 +188,7 @@ fn apt_confirm_window(
|
||||
}
|
||||
}
|
||||
|
||||
let apt_confirm_dialog_child_box = Box::builder()
|
||||
.orientation(Orientation::Vertical)
|
||||
.build();
|
||||
let apt_confirm_dialog_child_box = Box::builder().orientation(Orientation::Vertical).build();
|
||||
|
||||
let apt_update_dialog_badges_size_group = 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);
|
||||
|
||||
apt_confirm_start_signal_action.connect_activate(clone!(#[weak] window, #[strong] 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);
|
||||
apt_confirm_start_signal_action.connect_activate(clone!(
|
||||
#[weak]
|
||||
window,
|
||||
#[strong]
|
||||
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();
|
||||
if to_be_removed_packages_borrow.is_empty() {
|
||||
apt_confirm_start_signal_action.activate(None);
|
||||
} else {
|
||||
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();
|
||||
|
||||
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.choose(None::<&gio::Cancellable>, move |choice| {
|
||||
if choice == "apt_remove_confirm_dialog_confirm" {
|
||||
apt_confirm_start_signal_action.activate(None);
|
||||
}
|
||||
if choice == "apt_remove_confirm_dialog_confirm" {
|
||||
apt_confirm_start_signal_action.activate(None);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -388,7 +408,7 @@ fn apt_full_upgrade_from_socket(
|
||||
thread::spawn(move || {
|
||||
let apt_upgrade_command = Command::new("pkexec")
|
||||
.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()
|
||||
.unwrap();
|
||||
@ -408,14 +428,10 @@ fn apt_full_upgrade_from_socket(
|
||||
}
|
||||
});
|
||||
|
||||
let apt_upgrade_dialog_child_box = Box::builder()
|
||||
.orientation(Orientation::Vertical)
|
||||
.build();
|
||||
let apt_upgrade_dialog_child_box = Box::builder().orientation(Orientation::Vertical).build();
|
||||
|
||||
let apt_upgrade_dialog_progress_bar = ProgressBar::builder()
|
||||
.show_text(true)
|
||||
.hexpand(true)
|
||||
.build();
|
||||
let apt_upgrade_dialog_progress_bar =
|
||||
ProgressBar::builder().show_text(true).hexpand(true).build();
|
||||
|
||||
let apt_upgrade_dialog_spinner = Spinner::builder()
|
||||
.hexpand(true)
|
||||
@ -441,9 +457,8 @@ fn apt_full_upgrade_from_socket(
|
||||
&t!("apt_upgrade_dialog_ok_label").to_string(),
|
||||
);
|
||||
|
||||
let apt_upgrade_dialog_child_box_done = Box::builder()
|
||||
.orientation(Orientation::Vertical)
|
||||
.build();
|
||||
let apt_upgrade_dialog_child_box_done =
|
||||
Box::builder().orientation(Orientation::Vertical).build();
|
||||
|
||||
let apt_upgrade_log_image = Image::builder()
|
||||
.pixel_size(128)
|
||||
@ -467,46 +482,62 @@ fn apt_full_upgrade_from_socket(
|
||||
|
||||
let upgrade_percent_server_context = MainContext::default();
|
||||
// The main loop executes the asynchronous block
|
||||
upgrade_percent_server_context.spawn_local(clone!(#[weak] apt_upgrade_dialog_progress_bar, async move {
|
||||
while let Ok(state) = upgrade_percent_receiver.recv().await {
|
||||
match state.as_ref() {
|
||||
"FN_OVERRIDE_SUCCESSFUL" => {}
|
||||
_ => {
|
||||
match state.parse::<f64>() {
|
||||
Ok(p) => apt_upgrade_dialog_progress_bar.set_fraction(p/100.0),
|
||||
upgrade_percent_server_context.spawn_local(clone!(
|
||||
#[weak]
|
||||
apt_upgrade_dialog_progress_bar,
|
||||
async move {
|
||||
while let Ok(state) = upgrade_percent_receiver.recv().await {
|
||||
match state.as_ref() {
|
||||
"FN_OVERRIDE_SUCCESSFUL" => {}
|
||||
_ => match state.parse::<f64>() {
|
||||
Ok(p) => apt_upgrade_dialog_progress_bar.set_fraction(p / 100.0),
|
||||
Err(_) => {}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
));
|
||||
|
||||
let upgrade_status_server_context = MainContext::default();
|
||||
// The main loop executes the asynchronous block
|
||||
upgrade_status_server_context.spawn_local(
|
||||
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 {
|
||||
while let Ok(state) = upgrade_status_receiver.recv().await {
|
||||
match state.as_ref() {
|
||||
"FN_OVERRIDE_SUCCESSFUL" => {
|
||||
upgrade_status_server_context.spawn_local(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 {
|
||||
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_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.set_title(Some(&t!("apt_upgrade_dialog_status_successful").to_string()));
|
||||
apt_upgrade_dialog
|
||||
.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);
|
||||
}
|
||||
"FN_OVERRIDE_FAILED" => {
|
||||
"FN_OVERRIDE_FAILED" => {
|
||||
apt_upgrade_dialog_child_box.set_visible(false);
|
||||
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.set_title(Some(&t!("apt_upgrade_dialog_status_failed").to_string()));
|
||||
apt_upgrade_dialog
|
||||
.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_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();
|
||||
|
||||
|
@ -3,7 +3,7 @@ use crate::config::{APP_GITHUB, APP_ICON, APP_ID, VERSION};
|
||||
use adw::prelude::*;
|
||||
use adw::*;
|
||||
use gtk::glib::{clone, MainContext};
|
||||
use gtk::{License};
|
||||
use gtk::License;
|
||||
use std::cell::RefCell;
|
||||
use std::process::Command;
|
||||
use std::rc::Rc;
|
||||
@ -36,28 +36,28 @@ pub fn build_ui(app: &Application) {
|
||||
|
||||
let internet_loop_context = MainContext::default();
|
||||
// The main loop executes the asynchronous block
|
||||
internet_loop_context.spawn_local(clone!(#[weak] window_banner, async move {
|
||||
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;
|
||||
internet_loop_context.spawn_local(clone!(
|
||||
#[weak]
|
||||
window_banner,
|
||||
async move {
|
||||
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 {
|
||||
window_banner.set_revealed(false)
|
||||
}
|
||||
} else {
|
||||
*internet_connected_status.borrow_mut()=false;
|
||||
*internet_connected_status.borrow_mut() = false;
|
||||
window_banner.set_title(&banner_text);
|
||||
window_banner.set_revealed(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
));
|
||||
|
||||
let window_headerbar = HeaderBar::builder()
|
||||
.title_widget(
|
||||
&WindowTitle::builder()
|
||||
.title(t!("application_name"))
|
||||
.build(),
|
||||
)
|
||||
.title_widget(&WindowTitle::builder().title(t!("application_name")).build())
|
||||
.build();
|
||||
|
||||
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(&credits_button);
|
||||
credits_button
|
||||
.connect_clicked(move |_| credits_window.present());
|
||||
credits_button.connect_clicked(move |_| credits_window.present());
|
||||
|
||||
// show the window
|
||||
|
||||
@ -138,9 +137,20 @@ pub fn build_ui(app: &Application) {
|
||||
))
|
||||
.build();
|
||||
|
||||
apt_retry_signal_action.connect_activate(clone!(#[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)));
|
||||
}));
|
||||
apt_retry_signal_action.connect_activate(clone!(
|
||||
#[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(
|
||||
&apt_update_view_stack_bin,
|
||||
@ -150,12 +160,16 @@ pub fn build_ui(app: &Application) {
|
||||
);
|
||||
//
|
||||
|
||||
refresh_button.connect_clicked(
|
||||
clone!(#[weak] apt_retry_signal_action, #[weak] window_adw_view_stack, move |_| {
|
||||
refresh_button.connect_clicked(clone!(
|
||||
#[weak]
|
||||
apt_retry_signal_action,
|
||||
#[weak]
|
||||
window_adw_view_stack,
|
||||
move |_| {
|
||||
match window_adw_view_stack.visible_child_name().unwrap().as_str() {
|
||||
"apt_update_page" => apt_retry_signal_action.activate(None),
|
||||
_ => {}
|
||||
}
|
||||
}),
|
||||
);
|
||||
}
|
||||
));
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::pika_unixsocket_tools::*;
|
||||
use rust_apt::progress::{DynInstallProgress};
|
||||
use rust_apt::progress::DynInstallProgress;
|
||||
use std::process::exit;
|
||||
use tokio::io::AsyncWriteExt;
|
||||
use tokio::net::UnixStream;
|
||||
|
@ -166,10 +166,7 @@ pub async fn start_socket_server_no_log(
|
||||
match listener.accept().await {
|
||||
Ok((stream, _)) => {
|
||||
// Handle the connection in a separate task
|
||||
task::spawn(handle_client_no_log(
|
||||
stream,
|
||||
buffer_sender.clone(),
|
||||
));
|
||||
task::spawn(handle_client_no_log(stream, buffer_sender.clone()));
|
||||
}
|
||||
Err(e) => {
|
||||
// Print error message if a connection fails
|
||||
|
Loading…
Reference in New Issue
Block a user