Skip to content

Commit

Permalink
add filter for sex
Browse files Browse the repository at this point in the history
  • Loading branch information
SeaDve committed Dec 9, 2024
1 parent c7f69bb commit 01234da
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 22 deletions.
3 changes: 3 additions & 0 deletions data/resources/ui/entities_view.ui
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@
<child>
<object class="GtkDropDown" id="entity_expiration_dropdown"/>
</child>
<child>
<object class="GtkDropDown" id="entity_sex_dropdown"/>
</child>
<child>
<object class="UetsDateTimeRangeButton" id="dt_range_button"/>
</child>
Expand Down
7 changes: 4 additions & 3 deletions src/search_query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -312,22 +312,23 @@ impl SearchQueries {
}
}

/// Removes all queries with the given `iden` and `value`.
pub fn remove_all(&mut self, iden: &str, value: &str) {
/// Removes all queries with the given `iden` and `values`.
pub fn remove_all(&mut self, iden: &str, values: &[&str]) {
debug_assert!(!iden.contains(char::is_whitespace));

self.0.retain(|query| {
if let SQ::IdenValue {
iden: i, value: v, ..
} = query
{
i != iden || v != value
i != iden || !values.contains(&v.as_str())
} else {
true
}
});
}

/// Removes all queries with the given `iden`.
pub fn remove_all_iden(&mut self, iden: &str) {
debug_assert!(!iden.contains(char::is_whitespace));

Expand Down
10 changes: 10 additions & 0 deletions src/sex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,16 @@ pub enum Sex {
Female,
}

impl Sex {
pub fn is_male(&self) -> bool {
matches!(self, Self::Male)
}

pub fn is_female(&self) -> bool {
matches!(self, Self::Female)
}
}

impl fmt::Display for Sex {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Expand Down
116 changes: 106 additions & 10 deletions src/ui/entities_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,21 @@ struct S;
impl S {
const IS: &str = "is";

const ENTITY_ZONE_VALUES: &[&str] = &[Self::INSIDE, Self::OUTSIDE];
const INSIDE: &str = "inside";
const OUTSIDE: &str = "outside";

const ENTITY_SEX_VALUES: &[&str] = &[Self::MALE, Self::FEMALE];
const MALE: &str = "male";
const FEMALE: &str = "female";

const ENTITY_EXPIRATION_VALUES: &[&str] = &[
Self::NO_EXPIRATION,
Self::NOT_EXPIRING,
Self::EXPIRING,
Self::EXPIRED,
Self::EXPIRING_OR_EXPIRED,
];

const NO_EXPIRATION: &str = "no-expiration";
const NOT_EXPIRING: &str = "not-expiring";
const EXPIRING: &str = "expiring";
Expand Down Expand Up @@ -108,6 +112,16 @@ impl EntityExpirationFilter {
}
}

#[derive(Debug, Clone, Copy, glib::Enum)]
#[enum_type(name = "UetsEntitySexFilter")]
enum EntitySexFilter {
All,
Male,
Female,
}

list_model_enum!(EntitySexFilter);

#[derive(Debug, Default, Clone, Copy, glib::Enum)]
#[enum_type(name = "UetsEntitySort")]
enum EntitySort {
Expand Down Expand Up @@ -164,6 +178,8 @@ mod imp {
#[template_child]
pub(super) entity_expiration_dropdown: TemplateChild<gtk::DropDown>,
#[template_child]
pub(super) entity_sex_dropdown: TemplateChild<gtk::DropDown>,
#[template_child]
pub(super) dt_range_button: TemplateChild<DateTimeRangeButton>,
#[template_child]
pub(super) entity_sort_dropdown: TemplateChild<gtk::DropDown>,
Expand All @@ -184,6 +200,7 @@ mod imp {

pub(super) entity_zone_dropdown_selected_item_id: OnceCell<glib::SignalHandlerId>,
pub(super) entity_expiration_dropdown_selected_item_id: OnceCell<glib::SignalHandlerId>,
pub(super) entity_sex_dropdown_selected_item_id: OnceCell<glib::SignalHandlerId>,
pub(super) dt_range_button_range_notify_id: OnceCell<glib::SignalHandlerId>,
pub(super) entity_sort_dropdown_selected_item_id: OnceCell<glib::SignalHandlerId>,

Expand Down Expand Up @@ -229,6 +246,7 @@ mod imp {
obj,
move |_| {
obj.update_entity_expiration_dropdown_visibility();
obj.update_entity_sex_dropdown_visibility();
}
));

Expand Down Expand Up @@ -281,6 +299,23 @@ mod imp {
.set(entity_expiration_dropdown_selected_item_notify_id)
.unwrap();

self.entity_sex_dropdown
.set_expression(Some(&adw::EnumListItem::this_expression("name")));
self.entity_sex_dropdown
.set_model(Some(&EntitySexFilter::new_model()));
let entity_sex_dropdown_selected_item_notify_id = self
.entity_sex_dropdown
.connect_selected_item_notify(clone!(
#[weak]
obj,
move |dropdown| {
obj.handle_entity_sex_dropdown_selected_item_notify(dropdown);
}
));
self.entity_sex_dropdown_selected_item_id
.set(entity_sex_dropdown_selected_item_notify_id)
.unwrap();

let dt_range_button_range_notify_id =
self.dt_range_button.connect_range_notify(clone!(
#[weak]
Expand Down Expand Up @@ -421,6 +456,7 @@ mod imp {

obj.update_fallback_sorter();
obj.update_entity_expiration_dropdown_visibility();
obj.update_entity_sex_dropdown_visibility();
obj.update_stack();
obj.update_n_results_label();
}
Expand Down Expand Up @@ -620,6 +656,21 @@ impl EntitiesView {
imp.entity_expiration_dropdown
.unblock_signal(selected_item_notify_id);

let entity_sex = match queries.find_last_with_values(S::IS, S::ENTITY_SEX_VALUES) {
Some(S::MALE) => EntitySexFilter::Male,
Some(S::FEMALE) => EntitySexFilter::Female,
None => EntitySexFilter::All,
Some(_) => unreachable!(),
};

let selected_item_notify_id = imp.entity_sex_dropdown_selected_item_id.get().unwrap();
imp.entity_sex_dropdown
.block_signal(selected_item_notify_id);
imp.entity_sex_dropdown
.set_selected(entity_sex.model_position());
imp.entity_sex_dropdown
.unblock_signal(selected_item_notify_id);

let dt_range = queries.dt_range(S::FROM, S::TO);

let dt_range_button_range_notify_id = imp.dt_range_button_range_notify_id.get().unwrap();
Expand Down Expand Up @@ -699,6 +750,20 @@ impl EntitiesView {
}
}

match entity_sex {
EntitySexFilter::All => {}
EntitySexFilter::Male => {
every_filter.append(new_filter(move |entity: &Entity| {
entity.data().sex().is_some_and(|s| s.is_male())
}));
}
EntitySexFilter::Female => {
every_filter.append(new_filter(move |entity: &Entity| {
entity.data().sex().is_some_and(|s| s.is_female())
}));
}
}

let any_stock_filter = gtk::AnyFilter::new();
for stock_id in queries.all_values(S::STOCK).into_iter().map(StockId::new) {
any_stock_filter.append(new_filter(move |entity: &Entity| {
Expand Down Expand Up @@ -730,14 +795,13 @@ impl EntitiesView {

match selected_item.value().try_into().unwrap() {
EntityZoneFilter::All => {
queries.remove_all(S::IS, S::INSIDE);
queries.remove_all(S::IS, S::OUTSIDE);
queries.remove_all(S::IS, S::ENTITY_ZONE_VALUES);
}
EntityZoneFilter::Inside => {
queries.replace_all_or_insert(S::IS, &[S::OUTSIDE], S::INSIDE);
queries.replace_all_or_insert(S::IS, S::ENTITY_ZONE_VALUES, S::INSIDE);
}
EntityZoneFilter::Outside => {
queries.replace_all_or_insert(S::IS, &[S::INSIDE], S::OUTSIDE);
queries.replace_all_or_insert(S::IS, S::ENTITY_ZONE_VALUES, S::OUTSIDE);
}
}

Expand All @@ -757,11 +821,7 @@ impl EntitiesView {

match selected_item.value().try_into().unwrap() {
EntityExpirationFilter::All => {
queries.remove_all(S::IS, S::NO_EXPIRATION);
queries.remove_all(S::IS, S::NOT_EXPIRING);
queries.remove_all(S::IS, S::EXPIRING);
queries.remove_all(S::IS, S::EXPIRED);
queries.remove_all(S::IS, S::EXPIRING_OR_EXPIRED);
queries.remove_all(S::IS, S::ENTITY_EXPIRATION_VALUES);
}
EntityExpirationFilter::NoExpiration => {
queries.replace_all_or_insert(S::IS, S::ENTITY_EXPIRATION_VALUES, S::NO_EXPIRATION);
Expand All @@ -787,6 +847,32 @@ impl EntitiesView {
imp.search_entry.set_queries(queries);
}

fn handle_entity_sex_dropdown_selected_item_notify(&self, dropdown: &gtk::DropDown) {
let imp = self.imp();

let selected_item = dropdown
.selected_item()
.unwrap()
.downcast::<adw::EnumListItem>()
.unwrap();

let mut queries = imp.search_entry.queries();

match selected_item.value().try_into().unwrap() {
EntitySexFilter::All => {
queries.remove_all(S::IS, S::ENTITY_SEX_VALUES);
}
EntitySexFilter::Male => {
queries.replace_all_or_insert(S::IS, S::ENTITY_SEX_VALUES, S::MALE);
}
EntitySexFilter::Female => {
queries.replace_all_or_insert(S::IS, S::ENTITY_SEX_VALUES, S::FEMALE);
}
}

imp.search_entry.set_queries(queries);
}

fn handle_dt_range_button_range_notify(&self, button: &DateTimeRangeButton) {
let imp = self.imp();

Expand Down Expand Up @@ -886,6 +972,16 @@ impl EntitiesView {
imp.entity_expiration_dropdown.set_visible(is_visible);
}

fn update_entity_sex_dropdown_visibility(&self) {
let imp = self.imp();

let is_visible = Application::get()
.settings()
.operation_mode()
.is_valid_entity_data_field_ty(EntityDataFieldTy::Sex);
imp.entity_sex_dropdown.set_visible(is_visible);
}

fn update_stack(&self) {
let imp = self.imp();

Expand Down
5 changes: 1 addition & 4 deletions src/ui/stocks_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ impl S {
Self::LOWER_LIMIT_REACHED,
Self::UPPER_LIMIT_REACHED,
];

const LIMIT_REACHED: &str = "limit-reached";
const LOWER_LIMIT_REACHED: &str = "lower-limit-reached";
const UPPER_LIMIT_REACHED: &str = "upper-limit-reached";
Expand Down Expand Up @@ -584,9 +583,7 @@ impl StocksView {

match selected_item.value().try_into().unwrap() {
LimitReachedFilter::All => {
queries.remove_all(S::IS, S::LIMIT_REACHED);
queries.remove_all(S::IS, S::LOWER_LIMIT_REACHED);
queries.remove_all(S::IS, S::UPPER_LIMIT_REACHED);
queries.remove_all(S::IS, S::LIMIT_REACHED_VALUES);
}
LimitReachedFilter::LimitReached => {
queries.replace_all_or_insert(S::IS, S::LIMIT_REACHED_VALUES, S::LIMIT_REACHED);
Expand Down
10 changes: 5 additions & 5 deletions src/ui/timeline_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ struct S;
impl S {
const IS: &str = "is";

const ITEM_KIND_VALUES: &[&str] = &[Self::ENTRY, Self::EXIT];
const ENTRY: &str = "entry";
const EXIT: &str = "exit";

Expand Down Expand Up @@ -481,7 +482,7 @@ impl TimelineView {

let queries = entry.queries();

let item_kind = match queries.find_last_with_values(S::IS, &[S::ENTRY, S::EXIT]) {
let item_kind = match queries.find_last_with_values(S::IS, S::ITEM_KIND_VALUES) {
Some(S::ENTRY) => TimelineItemKindFilter::Entry,
Some(S::EXIT) => TimelineItemKindFilter::Exit,
None => TimelineItemKindFilter::All,
Expand Down Expand Up @@ -586,14 +587,13 @@ impl TimelineView {

match selected_item.value().try_into().unwrap() {
TimelineItemKindFilter::All => {
queries.remove_all(S::IS, S::ENTRY);
queries.remove_all(S::IS, S::EXIT);
queries.remove_all(S::IS, S::ITEM_KIND_VALUES);
}
TimelineItemKindFilter::Entry => {
queries.replace_all_or_insert(S::IS, &[S::EXIT], S::ENTRY);
queries.replace_all_or_insert(S::IS, S::ITEM_KIND_VALUES, S::ENTRY);
}
TimelineItemKindFilter::Exit => {
queries.replace_all_or_insert(S::IS, &[S::ENTRY], S::EXIT);
queries.replace_all_or_insert(S::IS, S::ITEM_KIND_VALUES, S::EXIT);
}
}

Expand Down

0 comments on commit 01234da

Please sign in to comment.