-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
19dfab3
commit 8fb4260
Showing
9 changed files
with
1,002 additions
and
35 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
.sat_cache | ||
obj/ | ||
orbvis | ||
*.glade~ |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,235 @@ | ||
#include "filter.h" | ||
|
||
#include "catalog.h" | ||
#include "satcat_code_list.h" | ||
|
||
#include <float.h> | ||
|
||
#define FILTER_FUNC_BETWEEN(field, target, var) ((field_active[field]) && (((target)[0] >= (var)) || ((target)[1] <= (var)))) | ||
#define SC_DATE_LESS(d1, d2) (((d1).year < (d2).year) ? (TRUE) : (((d1).year == (d2).year) ? (((d1).month < (d2).month) ? (TRUE) : (((d1).month == (d2).month) ? ((d1).day < (d2).day) : (FALSE))) : (FALSE))) | ||
|
||
enum FilterCombo { | ||
COMBO_STATUS = 0u, | ||
COMBO_LAUNCH_SITE, | ||
COMBO_SOURCE, | ||
NUM_FILTER_COMBO, | ||
}; | ||
|
||
enum FilterEntry { | ||
ENTRY_PERIGEE = 0u, | ||
ENTRY_APOGEE, | ||
ENTRY_INCLINATION, | ||
ENTRY_PERIOD, | ||
ENTRY_LAUNCH_DATE, | ||
NUM_FILTER_ENTRY, | ||
}; | ||
|
||
enum FilterField { | ||
FIELD_STATUS = 0u, | ||
FIELD_LAUNCH_SITE, | ||
FIELD_SOURCE, | ||
FIELD_PERIGEE, | ||
FIELD_APOGEE, | ||
FIELD_INCLINATION, | ||
FIELD_PERIOD, | ||
FIELD_LAUNCH_DATE, | ||
NUM_FILTER_FIELD, | ||
}; | ||
|
||
static const char *combo_item_ids[NUM_FILTER_COMBO] = { | ||
[COMBO_STATUS] = "filter_status", | ||
[COMBO_LAUNCH_SITE] = "filter_launch_site", | ||
[COMBO_SOURCE] = "filter_source", | ||
}; | ||
|
||
static const char *entry_item_ids[NUM_FILTER_ENTRY][2] = { | ||
[ENTRY_PERIGEE] = { "filter_low_perigee", "filter_high_perigee" }, | ||
[ENTRY_APOGEE] = { "filter_low_apogee", "filter_high_apogee" }, | ||
[ENTRY_INCLINATION] = { "filter_low_inclination", "filter_high_inclination" }, | ||
[ENTRY_PERIOD] = { "filter_low_period", "filter_high_period" }, | ||
[ENTRY_LAUNCH_DATE] = { "filter_low_launch_date", "filter_high_launch_date" }, | ||
}; | ||
|
||
static GtkComboBoxText *combo_items[NUM_FILTER_COMBO]; | ||
static GtkEntry *entry_items[NUM_FILTER_ENTRY][2]; | ||
static gboolean field_active[NUM_FILTER_FIELD] = { FALSE }; | ||
|
||
static gboolean active = FALSE; | ||
|
||
static char target_status; | ||
static sc_code_t target_source; | ||
static sc_code_t target_launch_site; | ||
static double target_perigee[2]; | ||
static double target_apogee[2]; | ||
static double target_inclination[2]; | ||
static double target_period[2]; | ||
static struct SCDate target_launch_date[2]; | ||
|
||
static void on_filter_clear_clicked(GtkButton *button, gpointer user_data); | ||
static void on_filter_apply_clicked(GtkButton *button, gpointer user_data); | ||
static void on_filter_clear_status_clicked(GtkButton *button, gpointer user_data); | ||
static void on_filter_clear_source_clicked(GtkButton *button, gpointer user_data); | ||
static void on_filter_clear_launch_site_clicked(GtkButton *button, gpointer user_data); | ||
static void on_filter_launch_date_activate(GtkEntry *entry, gpointer user_data); | ||
|
||
static void filter_set_from_entry(enum FilterEntry entry, enum FilterField field, double *target, double dflt[2]); | ||
|
||
void on_filter_clear_status_clicked(GtkButton *button, gpointer user_data) | ||
{ | ||
(void)button; | ||
(void)user_data; | ||
gtk_combo_box_set_active(GTK_COMBO_BOX(combo_items[COMBO_STATUS]), -1); | ||
} | ||
|
||
void on_filter_clear_source_clicked(GtkButton *button, gpointer user_data) | ||
{ | ||
(void)button; | ||
(void)user_data; | ||
gtk_combo_box_set_active(GTK_COMBO_BOX(combo_items[COMBO_SOURCE]), -1); | ||
} | ||
|
||
void on_filter_clear_launch_site_clicked(GtkButton *button, gpointer user_data) | ||
{ | ||
(void)button; | ||
(void)user_data; | ||
gtk_combo_box_set_active(GTK_COMBO_BOX(combo_items[COMBO_LAUNCH_SITE]), -1); | ||
} | ||
|
||
void on_filter_launch_date_activate(GtkEntry *entry, gpointer user_data) | ||
{ | ||
(void)user_data; | ||
|
||
const gchar *text = gtk_entry_get_text(entry); | ||
unsigned y, m = 1, d = 1; | ||
int nitems = sscanf(text, "%4u-%2u-%2u", &y, &m, &d); | ||
if (!nitems) | ||
goto FAIL; | ||
{ | ||
GTimeZone *tz = g_time_zone_new_utc(); | ||
GDateTime *dt = g_date_time_new(tz, y, m, d, 0, 0, 0); | ||
if (dt) { | ||
g_date_time_unref(dt); | ||
g_time_zone_unref(tz); | ||
return; | ||
} | ||
g_time_zone_unref(tz); | ||
} | ||
FAIL: | ||
gtk_entry_set_text(entry, ""); | ||
} | ||
|
||
void on_filter_clear_clicked(GtkButton *button, gpointer user_data) | ||
{ | ||
(void)button; | ||
(void)user_data; | ||
|
||
unsigned i, j; | ||
for (i = 0; i < NUM_FILTER_COMBO; i++) | ||
gtk_combo_box_set_active(GTK_COMBO_BOX(combo_items[i]), -1); | ||
for (i = 0; i < NUM_FILTER_ENTRY; i++) | ||
for (j = 0; j < 2; j++) | ||
gtk_entry_set_text(entry_items[i][j], ""); | ||
for (i = 0; i < NUM_FILTER_FIELD; i++) | ||
field_active[i] = FALSE; | ||
|
||
active = FALSE; | ||
gtk_tree_model_filter_refilter(e_catalog_filter); | ||
} | ||
|
||
void filter_set_from_entry(enum FilterEntry entry, enum FilterField field, double *target, double dflt[2]) | ||
{ | ||
field_active[field] = FALSE; | ||
unsigned j; | ||
for (j = 0; j < 2; j++) { | ||
const gchar *text = gtk_entry_get_text(entry_items[entry][j]); | ||
gchar *endptr; | ||
target[j] = g_ascii_strtod(text, &endptr); | ||
if (endptr == text) | ||
target[j] = dflt[j]; | ||
else | ||
field_active[field] = TRUE; | ||
} | ||
} | ||
|
||
void on_filter_apply_clicked(GtkButton *button, gpointer user_data) | ||
{ | ||
(void)button; | ||
(void)user_data; | ||
|
||
int idx; | ||
|
||
idx = gtk_combo_box_get_active(GTK_COMBO_BOX(combo_items[COMBO_STATUS])); | ||
field_active[FIELD_STATUS] = (idx != -1); | ||
if (field_active[FIELD_STATUS]) | ||
target_status = SCSTAT[idx]; | ||
|
||
idx = gtk_combo_box_get_active(GTK_COMBO_BOX(combo_items[COMBO_SOURCE])); | ||
field_active[FIELD_SOURCE] = (idx != -1); | ||
if (field_active[FIELD_SOURCE]) | ||
target_source = SCSRC[idx]; | ||
|
||
idx = gtk_combo_box_get_active(GTK_COMBO_BOX(combo_items[COMBO_LAUNCH_SITE])); | ||
field_active[FIELD_LAUNCH_SITE] = (idx != -1); | ||
if (field_active[FIELD_LAUNCH_SITE]) | ||
target_launch_site = SCSITE[idx]; | ||
|
||
filter_set_from_entry(ENTRY_PERIGEE, FIELD_PERIGEE, target_perigee, (double[2]){ 0, DBL_MAX }); | ||
filter_set_from_entry(ENTRY_APOGEE, FIELD_APOGEE, target_apogee, (double[2]){ 0, DBL_MAX }); | ||
filter_set_from_entry(ENTRY_INCLINATION, FIELD_INCLINATION, target_inclination, (double[2]){ 0, 360.0 }); | ||
filter_set_from_entry(ENTRY_PERIOD, FIELD_PERIOD, target_period, (double[2]){ 0, DBL_MAX }); | ||
|
||
field_active[FIELD_LAUNCH_DATE] = FALSE; | ||
unsigned i; | ||
for (i = 0; i < 2; i++) { | ||
target_launch_date[i].year = (unsigned[2]){ 0, 9999 }[i]; | ||
target_launch_date[i].month = 1; | ||
target_launch_date[i].day = 1; | ||
int nitems = sscanf(gtk_entry_get_text(entry_items[ENTRY_LAUNCH_DATE][i]), "%4u-%2u-%2u", &target_launch_date[i].year, &target_launch_date[i].month, &target_launch_date[i].day); | ||
if (nitems) | ||
field_active[FIELD_LAUNCH_DATE] = TRUE; | ||
} | ||
|
||
active = TRUE; | ||
gtk_tree_model_filter_refilter(e_catalog_filter); | ||
} | ||
|
||
gboolean filter_func(struct Satellite *satellite) | ||
{ | ||
if (!active) | ||
return TRUE; | ||
|
||
return !((field_active[FIELD_STATUS] && satellite->satcat.opstat != target_status) | ||
|| (field_active[FIELD_SOURCE] && SC_STR5_TO_CODE(satellite->satcat.source) != target_source) | ||
|| (field_active[FIELD_LAUNCH_SITE] && SC_STR5_TO_CODE(satellite->satcat.launch_site) != target_launch_site) | ||
|| FILTER_FUNC_BETWEEN(FIELD_PERIGEE, target_perigee, satellite->satcat.perigee) | ||
|| FILTER_FUNC_BETWEEN(FIELD_APOGEE, target_apogee, satellite->satcat.apogee) | ||
|| FILTER_FUNC_BETWEEN(FIELD_INCLINATION, target_inclination, satellite->satcat.inc_deg) | ||
|| FILTER_FUNC_BETWEEN(FIELD_PERIOD, target_period, satellite->satcat.period) | ||
|| (field_active[FIELD_LAUNCH_DATE] && (SC_DATE_LESS(satellite->satcat.launch_date, target_launch_date[0]) || SC_DATE_LESS(target_launch_date[1], satellite->satcat.launch_date)))); | ||
} | ||
|
||
void filter_init(GtkBuilder *builder) | ||
{ | ||
gtk_builder_add_callback_symbols(builder, | ||
"on_filter_clear_clicked", G_CALLBACK(on_filter_clear_clicked), | ||
"on_filter_apply_clicked", G_CALLBACK(on_filter_apply_clicked), | ||
"on_filter_clear_status_clicked", G_CALLBACK(on_filter_clear_status_clicked), | ||
"on_filter_clear_source_clicked", G_CALLBACK(on_filter_clear_source_clicked), | ||
"on_filter_clear_launch_site_clicked", G_CALLBACK(on_filter_clear_launch_site_clicked), | ||
"on_filter_launch_date_activate", G_CALLBACK(on_filter_launch_date_activate), | ||
NULL); | ||
|
||
unsigned i, j; | ||
for (i = 0; i < NUM_FILTER_COMBO; i++) | ||
combo_items[i] = GTK_COMBO_BOX_TEXT(gtk_builder_get_object(builder, combo_item_ids[i])); | ||
for (i = 0; i < NUM_FILTER_ENTRY; i++) | ||
for (j = 0; j < 2; j++) | ||
entry_items[i][j] = GTK_ENTRY(gtk_builder_get_object(builder, entry_item_ids[i][j])); | ||
|
||
for (i = 0; i < NUM_SCSTAT; i++) | ||
gtk_combo_box_text_append(combo_items[COMBO_STATUS], NULL, sc_status_str(SCSTAT[i])); | ||
for (i = 0; i < NUM_SCSRC; i++) | ||
gtk_combo_box_text_append(combo_items[COMBO_SOURCE], NULL, sc_source_str(SCSRC[i])); | ||
for (i = 0; i < NUM_SCSITE; i++) | ||
gtk_combo_box_text_append(combo_items[COMBO_LAUNCH_SITE], NULL, sc_launch_site_str(SCSITE[i])); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#ifndef __FILTER_H__ | ||
#define __FILTER_H__ | ||
|
||
#include "satellite.h" | ||
#include "ui.h" | ||
|
||
void filter_init(GtkBuilder *builder); | ||
gboolean filter_func(struct Satellite *satellite); | ||
|
||
#endif /* __FILTER_H__ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.