Uncrustified sources
Also, added astrognome-uncrustify.cfg for later use
This commit is contained in:
parent
7fc700bf4e
commit
ea3b038b57
@ -47,6 +47,8 @@ The project is currently hosted on [GitHub](https://github.com/gergelypolonkai/a
|
||||
|
||||
The entire project is written in C, utilizing GTK+ (3.8 currently, but the final version may come only with 3.10) and SWE-GLib (which is used for the calculations part).
|
||||
|
||||
Astrognome follows a well-defined coding style. If you contribute, please follow that by looking at existing sources, or use [Uncrustify](http://uncrustify.sourceforge.net/) with the config file under docs/. The only thing it messes up currently is the alignment of object type #definitions.
|
||||
|
||||
## !!!WARNING!!!
|
||||
-------------
|
||||
|
||||
|
140
docs/astrognome-uncrustify.cfg
Normal file
140
docs/astrognome-uncrustify.cfg
Normal file
@ -0,0 +1,140 @@
|
||||
newlines lf
|
||||
|
||||
input_tab_size 8
|
||||
output_tab_size 8
|
||||
|
||||
string_escape_char 92
|
||||
string_escape_char2 0
|
||||
|
||||
# indenting
|
||||
indent_columns 4
|
||||
indent_with_tabs 0
|
||||
indent_align_string True
|
||||
indent_brace 0
|
||||
indent_braces False
|
||||
indent_braces_no_func True
|
||||
indent_func_call_param False
|
||||
indent_func_def_param False
|
||||
indent_func_proto_param False
|
||||
indent_switch_case indent_columns
|
||||
indent_case_brace indent_columns
|
||||
indent_paren_close 1
|
||||
indent_var_def_cont False
|
||||
|
||||
# spacing
|
||||
sp_arith Add
|
||||
sp_assign Add
|
||||
sp_enum_assign Add
|
||||
sp_bool Add
|
||||
sp_compare Add
|
||||
sp_inside_paren Remove
|
||||
sp_inside_fparens Remove
|
||||
sp_func_def_paren Remove
|
||||
sp_func_proto_paren Remove
|
||||
sp_paren_paren Remove
|
||||
sp_balance_nested_parens False
|
||||
sp_paren_brace Remove
|
||||
sp_before_square Remove
|
||||
sp_before_squares Remove
|
||||
sp_inside_square Remove
|
||||
sp_after_comma Add
|
||||
sp_before_comma Remove
|
||||
sp_after_cast Remove
|
||||
sp_sizeof_paren Remove
|
||||
sp_not Remove
|
||||
sp_inv Remove
|
||||
sp_addr Remove
|
||||
sp_member Remove
|
||||
sp_deref Remove
|
||||
sp_sign Remove
|
||||
sp_incdec Remove
|
||||
sp_attribute_paren Remove
|
||||
sp_macro Force
|
||||
sp_func_call_paren Remove
|
||||
sp_brace_typedef add
|
||||
sp_cond_colon add
|
||||
sp_cond_question add
|
||||
sp_defined_paren Remove
|
||||
sp_inside_paren_cast Ignore
|
||||
sp_else_brace Add
|
||||
sp_between_ptr_star Remove
|
||||
sp_before_ptr_star Add
|
||||
|
||||
# alignment
|
||||
align_keep_tabs False
|
||||
align_with_tabs False
|
||||
align_on_tabstop False
|
||||
align_number_left True
|
||||
align_func_params True
|
||||
align_var_def_span 2
|
||||
align_var_def_amp_style 1
|
||||
align_var_def_colon True
|
||||
align_enum_equ_span 0
|
||||
align_var_struct_span 2
|
||||
align_var_def_star_style 1
|
||||
align_var_def_amp_style 1
|
||||
align_typedef_span 2
|
||||
align_typedef_func 0
|
||||
align_typedef_star_style 1
|
||||
align_typedef_amp_style 2
|
||||
align_var_def_inline True
|
||||
align_assign_span 1
|
||||
align_pp_define_together True
|
||||
|
||||
# newlines
|
||||
nl_assign_leave_one_liners True
|
||||
nl_enum_leave_one_liners False
|
||||
nl_func_leave_one_liners False
|
||||
nl_if_leave_one_liners False
|
||||
nl_end_of_file Add
|
||||
nl_end_of_file_min 2
|
||||
nl_assign_brace Remove
|
||||
nl_func_var_def_blk 1
|
||||
nl_fcall_brace Add
|
||||
nl_enum_brace Remove
|
||||
nl_struct_brace Remove
|
||||
nl_union_brace Remove
|
||||
nl_if_brace Remove
|
||||
nl_brace_else Remove
|
||||
nl_elseif_brace Remove
|
||||
nl_else_brace Remove
|
||||
nl_for_brace Remove
|
||||
nl_while_brace Remove
|
||||
nl_do_brace Remove
|
||||
nl_brace_while Remove
|
||||
nl_switch_brace Remove
|
||||
nl_before_case True
|
||||
nl_after_case True
|
||||
nl_func_type_name Force
|
||||
nl_func_proto_type_name Remove
|
||||
nl_func_paren Remove
|
||||
nl_func_decl_start Remove
|
||||
nl_func_decl_args Force
|
||||
nl_func_decl_end Remove
|
||||
nl_fdef_brace Force
|
||||
nl_after_return False
|
||||
nl_define_macro False
|
||||
nl_create_if_one_liner False
|
||||
nl_create_for_one_liner False
|
||||
nl_create_while_one_liner False
|
||||
nl_after_semicolon True
|
||||
nl_multi_line_cond False
|
||||
nl_var_def_blk_in 2
|
||||
nl_multi_line_define True
|
||||
|
||||
# mod
|
||||
mod_full_brace_for Force
|
||||
mod_full_brace_if Force
|
||||
mod_full_brace_while Force
|
||||
mod_full_brace_do Remove
|
||||
mod_full_brace_nl 3
|
||||
mod_paren_on_return Remove
|
||||
|
||||
# line splitting
|
||||
#code_width = 78
|
||||
ls_for_split_full True
|
||||
ls_func_split_full True
|
||||
|
||||
# positioning
|
||||
pos_bool Trail
|
||||
pos_conditional Lead
|
62
src/ag-app.c
62
src/ag-app.c
@ -17,7 +17,7 @@ ag_app_peek_first_window(AgApp *app)
|
||||
|
||||
for (l = gtk_application_get_windows(GTK_APPLICATION(app)); l; l = g_list_next(l)) {
|
||||
if (GTK_IS_WINDOW(l->data)) {
|
||||
return (GTK_WINDOW(l->data));
|
||||
return GTK_WINDOW(l->data);
|
||||
}
|
||||
}
|
||||
|
||||
@ -77,21 +77,21 @@ about_cb(GSimpleAction *action, GVariant *parameter, gpointer user_data)
|
||||
NULL
|
||||
};
|
||||
|
||||
const gchar **documentors = NULL;
|
||||
const gchar **documentors = NULL;
|
||||
const gchar *translator_credits = _("translator_credits");
|
||||
|
||||
/* i18n: Please don't translate "Astrognome" (it's marked as translatable for transliteration only */
|
||||
gtk_show_about_dialog(NULL,
|
||||
"name", _("Astrognome"),
|
||||
"version", PACKAGE_VERSION,
|
||||
"comments", _("Astrologers' software for GNOME"),
|
||||
"authors", authors,
|
||||
"documentors", documentors,
|
||||
"translator_credits", ((strcmp(translator_credits, "translator_credits") != 0) ? translator_credits : NULL),
|
||||
"website", PACKAGE_URL,
|
||||
"website-label", _("Astrognome Website"),
|
||||
"logo-icon-name", PACKAGE_TARNAME,
|
||||
NULL);
|
||||
"name", _("Astrognome"),
|
||||
"version", PACKAGE_VERSION,
|
||||
"comments", _("Astrologers' software for GNOME"),
|
||||
"authors", authors,
|
||||
"documentors", documentors,
|
||||
"translator_credits", ((strcmp(translator_credits, "translator_credits") != 0) ? translator_credits : NULL),
|
||||
"website", PACKAGE_URL,
|
||||
"website-label", _("Astrognome Website"),
|
||||
"logo-icon-name", PACKAGE_TARNAME,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -108,11 +108,11 @@ static void
|
||||
ag_app_open_chart(AgApp *app, GFile *file)
|
||||
{
|
||||
GtkWidget *window;
|
||||
AgChart *chart;
|
||||
GError *err = NULL;
|
||||
gchar *uri;
|
||||
AgChart *chart;
|
||||
GError *err = NULL;
|
||||
gchar *uri;
|
||||
|
||||
chart = ag_chart_load_from_file(file, &err);
|
||||
chart = ag_chart_load_from_file(file, &err);
|
||||
window = ag_app_create_window(app);
|
||||
ag_window_set_chart(AG_WINDOW(window), chart);
|
||||
ag_window_update_from_chart(AG_WINDOW(window));
|
||||
@ -124,16 +124,16 @@ ag_app_open_chart(AgApp *app, GFile *file)
|
||||
static void
|
||||
open_cb(GSimpleAction *action, GVariant *parameter, gpointer user_data)
|
||||
{
|
||||
gint response;
|
||||
gint response;
|
||||
GtkWidget *fs;
|
||||
GSList *filenames = NULL;
|
||||
GSList *filenames = NULL;
|
||||
|
||||
fs = gtk_file_chooser_dialog_new(_("Select charts"),
|
||||
NULL,
|
||||
GTK_FILE_CHOOSER_ACTION_OPEN,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
|
||||
NULL);
|
||||
NULL,
|
||||
GTK_FILE_CHOOSER_ACTION_OPEN,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
|
||||
NULL);
|
||||
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fs), filter_all);
|
||||
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fs), filter_chart);
|
||||
gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(fs), filter_chart);
|
||||
@ -152,7 +152,7 @@ open_cb(GSimpleAction *action, GVariant *parameter, gpointer user_data)
|
||||
|
||||
for (l = filenames; l; l = g_slist_next(l)) {
|
||||
GFile *file;
|
||||
char *data = l->data;
|
||||
char *data = l->data;
|
||||
|
||||
if (data == NULL) {
|
||||
continue;
|
||||
@ -169,7 +169,7 @@ open_cb(GSimpleAction *action, GVariant *parameter, gpointer user_data)
|
||||
static void
|
||||
raise_cb(GSimpleAction *action, GVariant *parameter, gpointer user_data)
|
||||
{
|
||||
AgApp *app = AG_APP(user_data);
|
||||
AgApp *app = AG_APP(user_data);
|
||||
GtkWindow *window;
|
||||
|
||||
window = ag_app_peek_first_window(app);
|
||||
@ -207,7 +207,7 @@ setup_menu(AgApp *app)
|
||||
{
|
||||
GtkBuilder *builder;
|
||||
GMenuModel *model;
|
||||
GError *err = NULL;
|
||||
GError *err = NULL;
|
||||
|
||||
builder = gtk_builder_new();
|
||||
|
||||
@ -273,10 +273,10 @@ ag_app_new(void)
|
||||
g_set_application_name(_("Astrognome"));
|
||||
|
||||
app = g_object_new(AG_TYPE_APP,
|
||||
"application-id", "eu.polonkai.gergely.Astrognome",
|
||||
"flags", G_APPLICATION_HANDLES_OPEN,
|
||||
"register-session", TRUE,
|
||||
NULL);
|
||||
"application-id", "eu.polonkai.gergely.Astrognome",
|
||||
"flags", G_APPLICATION_HANDLES_OPEN,
|
||||
"register-session", TRUE,
|
||||
NULL);
|
||||
g_signal_connect(app, "activate", G_CALLBACK(application_activate_cb), NULL);
|
||||
|
||||
return app;
|
||||
@ -293,6 +293,6 @@ ag_app_class_init(AgAppClass *klass)
|
||||
GApplicationClass *application_class = G_APPLICATION_CLASS(klass);
|
||||
|
||||
application_class->startup = startup;
|
||||
application_class->open = ag_app_open;
|
||||
application_class->open = ag_app_open;
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@ typedef struct _AgAppPrivate AgAppPrivate;
|
||||
|
||||
struct _AgApp {
|
||||
GtkApplication parent_instance;
|
||||
AgAppPrivate *priv;
|
||||
AgAppPrivate *priv;
|
||||
};
|
||||
|
||||
struct _AgAppClass {
|
||||
@ -36,7 +36,9 @@ GtkWindow *ag_app_peek_first_window(AgApp *self);
|
||||
void ag_app_new_window(AgApp *self);
|
||||
void ag_app_quit(AgApp *self);
|
||||
void ag_app_raise(AgApp *self);
|
||||
void ag_app_run_action(AgApp *app, gboolean is_remote, const AstrognomeOptions *options);
|
||||
void ag_app_run_action(AgApp *app,
|
||||
gboolean is_remote,
|
||||
const AstrognomeOptions *options);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
215
src/ag-chart.c
215
src/ag-chart.c
@ -31,17 +31,24 @@ typedef enum {
|
||||
XML_CONVERT_INT
|
||||
} XmlConvertType;
|
||||
|
||||
G_DEFINE_QUARK(ag-chart-error-quark, ag_chart_error);
|
||||
G_DEFINE_QUARK(ag_chart_error_quark, ag_chart_error);
|
||||
|
||||
G_DEFINE_TYPE(AgChart, ag_chart, GSWE_TYPE_MOMENT);
|
||||
|
||||
#define GET_PRIVATE(instance) (G_TYPE_INSTANCE_GET_PRIVATE((instance), AG_TYPE_CHART, AgChartPrivate))
|
||||
#define ag_g_variant_unref(v) if ((v) != NULL) { \
|
||||
g_variant_unref((v)); \
|
||||
}
|
||||
#define ag_g_variant_unref(v) \
|
||||
if ((v) != NULL) { \
|
||||
g_variant_unref((v)); \
|
||||
}
|
||||
|
||||
static void ag_chart_set_property(GObject *gobject, guint prop_id, const GValue *value, GParamSpec *param_spec);
|
||||
static void ag_chart_get_property(GObject *gobject, guint prop_id, GValue *value, GParamSpec *param_spec);
|
||||
static void ag_chart_set_property(GObject *gobject,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *param_spec);
|
||||
static void ag_chart_get_property(GObject *gobject,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *param_spec);
|
||||
static void ag_chart_finalize(GObject *gobject);
|
||||
|
||||
static void
|
||||
@ -53,7 +60,7 @@ ag_chart_class_init(AgChartClass *klass)
|
||||
|
||||
gobject_class->set_property = ag_chart_set_property;
|
||||
gobject_class->get_property = ag_chart_get_property;
|
||||
gobject_class->finalize = ag_chart_finalize;
|
||||
gobject_class->finalize = ag_chart_finalize;
|
||||
|
||||
g_object_class_install_property(gobject_class, PROP_NAME, g_param_spec_string("name", "Chart name", "Name of the person on this chart", NULL, G_PARAM_READWRITE));
|
||||
g_object_class_install_property(gobject_class, PROP_COUNTRY, g_param_spec_string("country", "Country name", "Name of the country of birth", NULL, G_PARAM_READWRITE));
|
||||
@ -63,10 +70,10 @@ ag_chart_class_init(AgChartClass *klass)
|
||||
static void
|
||||
ag_chart_init(AgChart *chart)
|
||||
{
|
||||
chart->priv = GET_PRIVATE(chart);
|
||||
chart->priv->name = NULL;
|
||||
chart->priv->country = NULL;
|
||||
chart->priv->city = NULL;
|
||||
chart->priv = GET_PRIVATE(chart);
|
||||
chart->priv->name = NULL;
|
||||
chart->priv->country = NULL;
|
||||
chart->priv->city = NULL;
|
||||
chart->priv->save_buffer = NULL;
|
||||
}
|
||||
|
||||
@ -138,18 +145,18 @@ ag_chart_finalize(GObject *gobject)
|
||||
AgChart *
|
||||
ag_chart_new_full(GsweTimestamp *timestamp, gdouble longitude, gdouble latitude, gdouble altitude, GsweHouseSystem house_system)
|
||||
{
|
||||
AgChart *chart;
|
||||
AgChart *chart;
|
||||
GsweCoordinates *coords = g_new0(GsweCoordinates, 1);
|
||||
|
||||
coords->longitude = longitude;
|
||||
coords->latitude = latitude;
|
||||
coords->altitude = altitude;
|
||||
coords->latitude = latitude;
|
||||
coords->altitude = altitude;
|
||||
|
||||
chart = AG_CHART(g_object_new(AG_TYPE_CHART,
|
||||
"timestamp", timestamp,
|
||||
"coordinates", coords,
|
||||
"house-system", house_system,
|
||||
NULL));
|
||||
"timestamp", timestamp,
|
||||
"coordinates", coords,
|
||||
"house-system", house_system,
|
||||
NULL));
|
||||
|
||||
g_free(coords);
|
||||
|
||||
@ -223,11 +230,11 @@ static GVariant *
|
||||
get_by_xpath(xmlXPathContextPtr xpath_context, const gchar *uri, const gchar *xpath, gboolean value_required, XmlConvertType type, GError **err)
|
||||
{
|
||||
xmlXPathObjectPtr xpathObj;
|
||||
const gchar *text;
|
||||
char *endptr;
|
||||
GVariant *ret = NULL;
|
||||
gdouble d;
|
||||
gint i;
|
||||
const gchar *text;
|
||||
char *endptr;
|
||||
GVariant *ret = NULL;
|
||||
gdouble d;
|
||||
gint i;
|
||||
|
||||
if ((xpathObj = xmlXPathEvalExpression((const xmlChar *)xpath, xpath_context)) == NULL) {
|
||||
g_set_error(err, AG_CHART_ERROR, AG_CHART_ERROR_LIBXML, "File '%s' could not be parsed due to internal XML error.", uri);
|
||||
@ -324,29 +331,29 @@ get_by_xpath(xmlXPathContextPtr xpath_context, const gchar *uri, const gchar *xp
|
||||
AgChart *
|
||||
ag_chart_load_from_file(GFile *file, GError **err)
|
||||
{
|
||||
AgChart *chart = NULL;
|
||||
gchar *uri,
|
||||
*xml = NULL,
|
||||
*country_name,
|
||||
*city_name;
|
||||
guint length;
|
||||
xmlDocPtr doc;
|
||||
AgChart *chart = NULL;
|
||||
gchar *uri;
|
||||
gchar *xml = NULL;
|
||||
gchar *country_name;
|
||||
gchar *city_name;
|
||||
guint length;
|
||||
xmlDocPtr doc;
|
||||
xmlXPathContextPtr xpath_context;
|
||||
GVariant *chart_name,
|
||||
*country,
|
||||
*city,
|
||||
*longitude,
|
||||
*latitude,
|
||||
*altitude,
|
||||
*year,
|
||||
*month,
|
||||
*day,
|
||||
*hour,
|
||||
*minute,
|
||||
*second,
|
||||
*timezone;
|
||||
GsweTimestamp *timestamp;
|
||||
gboolean found_error = FALSE;
|
||||
GVariant *chart_name;
|
||||
GVariant *country;
|
||||
GVariant *city;
|
||||
GVariant *longitude;
|
||||
GVariant *latitude;
|
||||
GVariant *altitude;
|
||||
GVariant *year;
|
||||
GVariant *month;
|
||||
GVariant *day;
|
||||
GVariant *hour;
|
||||
GVariant *minute;
|
||||
GVariant *second;
|
||||
GVariant *timezone;
|
||||
GsweTimestamp *timestamp;
|
||||
gboolean found_error = FALSE;
|
||||
|
||||
uri = g_file_get_uri(file);
|
||||
|
||||
@ -447,15 +454,15 @@ ag_chart_load_from_file(GFile *file, GError **err)
|
||||
}
|
||||
|
||||
timestamp = gswe_timestamp_new_from_gregorian_full(
|
||||
g_variant_get_int32(year),
|
||||
g_variant_get_int32(month),
|
||||
g_variant_get_int32(day),
|
||||
g_variant_get_int32(hour),
|
||||
g_variant_get_int32(minute),
|
||||
g_variant_get_int32(second),
|
||||
0,
|
||||
g_variant_get_double(timezone)
|
||||
);
|
||||
g_variant_get_int32(year),
|
||||
g_variant_get_int32(month),
|
||||
g_variant_get_int32(day),
|
||||
g_variant_get_int32(hour),
|
||||
g_variant_get_int32(minute),
|
||||
g_variant_get_int32(second),
|
||||
0,
|
||||
g_variant_get_double(timezone)
|
||||
);
|
||||
g_variant_unref(year);
|
||||
g_variant_unref(month);
|
||||
g_variant_unref(day);
|
||||
@ -494,16 +501,16 @@ ag_chart_load_from_file(GFile *file, GError **err)
|
||||
static xmlDocPtr
|
||||
create_save_doc(AgChart *chart)
|
||||
{
|
||||
xmlDocPtr doc = NULL;
|
||||
xmlNodePtr root_node = NULL,
|
||||
data_node = NULL,
|
||||
xmlDocPtr doc = NULL;
|
||||
xmlNodePtr root_node = NULL,
|
||||
data_node = NULL,
|
||||
place_node = NULL,
|
||||
time_node = NULL;
|
||||
gchar *value;
|
||||
time_node = NULL;
|
||||
gchar *value;
|
||||
GsweCoordinates *coordinates;
|
||||
GsweTimestamp *timestamp;
|
||||
GsweTimestamp *timestamp;
|
||||
|
||||
doc = xmlNewDoc(BAD_CAST "1.0");
|
||||
doc = xmlNewDoc(BAD_CAST "1.0");
|
||||
root_node = xmlNewNode(NULL, BAD_CAST "chartinfo");
|
||||
xmlDocSetRootElement(doc, root_node);
|
||||
|
||||
@ -590,8 +597,8 @@ create_save_doc(AgChart *chart)
|
||||
void
|
||||
ag_chart_save_to_file(AgChart *chart, GFile *file, GError **err)
|
||||
{
|
||||
xmlChar *content = NULL;
|
||||
int length;
|
||||
xmlChar *content = NULL;
|
||||
int length;
|
||||
xmlDocPtr save_doc = create_save_doc(chart);
|
||||
|
||||
xmlDocDumpFormatMemoryEnc(save_doc, &content, &length, "UTF-8", 1);
|
||||
@ -604,37 +611,37 @@ ag_chart_save_to_file(AgChart *chart, GFile *file, GError **err)
|
||||
gchar *
|
||||
ag_chart_create_svg(AgChart *chart, GError **err)
|
||||
{
|
||||
xmlDocPtr doc = create_save_doc(chart),
|
||||
xslt_doc,
|
||||
svg_doc;
|
||||
xmlNodePtr root_node = NULL,
|
||||
ascmcs_node = NULL,
|
||||
houses_node = NULL,
|
||||
bodies_node = NULL,
|
||||
aspects_node = NULL,
|
||||
antiscia_node = NULL,
|
||||
node = NULL;
|
||||
gchar *value,
|
||||
*stylesheet_path,
|
||||
*css_path,
|
||||
*save_content = NULL,
|
||||
*css_uri,
|
||||
*css_final_uri,
|
||||
**params;
|
||||
GList *houses,
|
||||
*house,
|
||||
*planet,
|
||||
*aspect,
|
||||
*antiscion;
|
||||
xmlDocPtr doc = create_save_doc(chart);
|
||||
xmlDocPtr xslt_doc;
|
||||
xmlDocPtr svg_doc;
|
||||
xmlNodePtr root_node = NULL;
|
||||
xmlNodePtr ascmcs_node = NULL;
|
||||
xmlNodePtr houses_node = NULL;
|
||||
xmlNodePtr bodies_node = NULL;
|
||||
xmlNodePtr aspects_node = NULL;
|
||||
xmlNodePtr antiscia_node = NULL;
|
||||
xmlNodePtr node = NULL;
|
||||
gchar *value;
|
||||
gchar *stylesheet_path;
|
||||
gchar *css_path;
|
||||
gchar *save_content = NULL;
|
||||
gchar *css_uri;
|
||||
gchar *css_final_uri;
|
||||
gchar **params;
|
||||
GList *houses;
|
||||
GList *house;
|
||||
GList *planet;
|
||||
GList *aspect;
|
||||
GList *antiscion;
|
||||
const GswePlanetData *planet_data;
|
||||
const GsweAspectData *aspect_data;
|
||||
GEnumClass *planets_class,
|
||||
*aspects_class,
|
||||
*antiscia_class;
|
||||
gint save_length;
|
||||
GFile *css_file;
|
||||
xsltStylesheetPtr xslt_proc;
|
||||
locale_t current_locale;
|
||||
GEnumClass *planets_class;
|
||||
GEnumClass *aspects_class;
|
||||
GEnumClass *antiscia_class;
|
||||
gint save_length;
|
||||
GFile *css_file;
|
||||
xsltStylesheetPtr xslt_proc;
|
||||
locale_t current_locale;
|
||||
|
||||
root_node = xmlDocGetRootElement(doc);
|
||||
|
||||
@ -648,7 +655,7 @@ ag_chart_create_svg(AgChart *chart, GError **err)
|
||||
node = xmlNewChild(ascmcs_node, NULL, BAD_CAST "ascendant", NULL);
|
||||
|
||||
planet_data = gswe_moment_get_planet(GSWE_MOMENT(chart), GSWE_PLANET_ASCENDENT, NULL);
|
||||
value = g_malloc0(12);
|
||||
value = g_malloc0(12);
|
||||
g_ascii_dtostr(value, 12, planet_data->position);
|
||||
xmlNewProp(node, BAD_CAST "degree_ut", BAD_CAST value);
|
||||
g_free(value);
|
||||
@ -656,7 +663,7 @@ ag_chart_create_svg(AgChart *chart, GError **err)
|
||||
node = xmlNewChild(ascmcs_node, NULL, BAD_CAST "mc", NULL);
|
||||
|
||||
planet_data = gswe_moment_get_planet(GSWE_MOMENT(chart), GSWE_PLANET_MC, NULL);
|
||||
value = g_malloc0(12);
|
||||
value = g_malloc0(12);
|
||||
g_ascii_dtostr(value, 12, planet_data->position);
|
||||
xmlNewProp(node, BAD_CAST "degree_ut", BAD_CAST value);
|
||||
g_free(value);
|
||||
@ -664,7 +671,7 @@ ag_chart_create_svg(AgChart *chart, GError **err)
|
||||
node = xmlNewChild(ascmcs_node, NULL, BAD_CAST "vertex", NULL);
|
||||
|
||||
planet_data = gswe_moment_get_planet(GSWE_MOMENT(chart), GSWE_PLANET_VERTEX, NULL);
|
||||
value = g_malloc0(12);
|
||||
value = g_malloc0(12);
|
||||
g_ascii_dtostr(value, 12, planet_data->position);
|
||||
xmlNewProp(node, BAD_CAST "degree_ut", BAD_CAST value);
|
||||
g_free(value);
|
||||
@ -700,10 +707,10 @@ ag_chart_create_svg(AgChart *chart, GError **err)
|
||||
GEnumValue *enum_value;
|
||||
|
||||
if (
|
||||
(planet_data->planet_id == GSWE_PLANET_ASCENDENT)
|
||||
|| (planet_data->planet_id == GSWE_PLANET_MC)
|
||||
|| (planet_data->planet_id == GSWE_PLANET_VERTEX)
|
||||
) {
|
||||
(planet_data->planet_id == GSWE_PLANET_ASCENDENT) ||
|
||||
(planet_data->planet_id == GSWE_PLANET_MC) ||
|
||||
(planet_data->planet_id == GSWE_PLANET_VERTEX)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -748,12 +755,12 @@ ag_chart_create_svg(AgChart *chart, GError **err)
|
||||
|
||||
// Begin <antiscia> node
|
||||
g_debug("Generating antiscia table");
|
||||
antiscia_node = xmlNewChild(root_node, NULL, BAD_CAST "antiscia", NULL);
|
||||
antiscia_node = xmlNewChild(root_node, NULL, BAD_CAST "antiscia", NULL);
|
||||
antiscia_class = g_type_class_ref(GSWE_TYPE_ANTISCION_AXIS);
|
||||
|
||||
for (antiscion = gswe_moment_get_all_antiscia(GSWE_MOMENT(chart)); antiscion; antiscion = g_list_next(antiscion)) {
|
||||
GsweAntiscionData *antiscion_data = antiscion->data;
|
||||
GEnumValue *enum_value;
|
||||
GEnumValue *enum_value;
|
||||
|
||||
if (antiscion_data->axis == GSWE_ANTISCION_AXIS_NONE) {
|
||||
continue;
|
||||
@ -778,7 +785,7 @@ ag_chart_create_svg(AgChart *chart, GError **err)
|
||||
css_path = g_strdup_printf("%s/%s", PKGDATADIR, "chart.css");
|
||||
g_debug("Using %s as a CSS stylesheet", css_path);
|
||||
css_file = g_file_new_for_path(css_path);
|
||||
css_uri = g_file_get_uri(css_file);
|
||||
css_uri = g_file_get_uri(css_file);
|
||||
|
||||
stylesheet_path = g_strdup_printf("%s/%s", PKGDATADIR, "chart.xsl");
|
||||
g_debug("Opening %s as a stylesheet", stylesheet_path);
|
||||
@ -813,7 +820,7 @@ ag_chart_create_svg(AgChart *chart, GError **err)
|
||||
|
||||
css_final_uri = g_strdup_printf("'%s'", css_uri);
|
||||
g_free(css_uri);
|
||||
params = g_new0(gchar *, 3);
|
||||
params = g_new0(gchar *, 3);
|
||||
params[0] = "css_file";
|
||||
params[1] = css_final_uri;
|
||||
// libxml2 messes up the output, as it prints decimal floating point
|
||||
@ -821,7 +828,7 @@ ag_chart_create_svg(AgChart *chart, GError **err)
|
||||
// character for decimal separator other than a dot. So let's just use the
|
||||
// C locale until the SVG is generated.
|
||||
current_locale = uselocale(newlocale(LC_ALL, "C", 0));
|
||||
svg_doc = xsltApplyStylesheet(xslt_proc, doc, (const char **)params);
|
||||
svg_doc = xsltApplyStylesheet(xslt_proc, doc, (const char **)params);
|
||||
uselocale(current_locale);
|
||||
g_free(stylesheet_path);
|
||||
g_free(css_path);
|
||||
|
@ -18,12 +18,12 @@ typedef enum {
|
||||
#define AG_IS_CHART_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), AG_TYPE_CHART))
|
||||
#define AG_CHART_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), AG_TYPE_CHART, AgChartClass))
|
||||
|
||||
typedef struct _AgChart AgChart;
|
||||
typedef struct _AgChartClass AgChartClass;
|
||||
typedef struct _AgChart AgChart;
|
||||
typedef struct _AgChartClass AgChartClass;
|
||||
typedef struct _AgChartPrivate AgChartPrivate;
|
||||
|
||||
struct _AgChart {
|
||||
GsweMoment parent_instance;
|
||||
GsweMoment parent_instance;
|
||||
AgChartPrivate *priv;
|
||||
};
|
||||
|
||||
@ -32,17 +32,28 @@ struct _AgChartClass {
|
||||
};
|
||||
|
||||
GType ag_chart_get_type(void) G_GNUC_CONST;
|
||||
AgChart *ag_chart_new_full(GsweTimestamp *timestamp, gdouble longitude, gdouble latitude, gdouble altitude, GsweHouseSystem house_system);
|
||||
AgChart *ag_chart_load_from_file(GFile *file, GError **err);
|
||||
void ag_chart_save_to_file(AgChart *chart, GFile *file, GError **err);
|
||||
AgChart *ag_chart_new_full(GsweTimestamp *timestamp,
|
||||
gdouble longitude,
|
||||
gdouble latitude,
|
||||
gdouble altitude,
|
||||
GsweHouseSystem house_system);
|
||||
AgChart *ag_chart_load_from_file(GFile *file,
|
||||
GError **err);
|
||||
void ag_chart_save_to_file(AgChart *chart,
|
||||
GFile *file,
|
||||
GError **err);
|
||||
|
||||
void ag_chart_set_name(AgChart *chart, const gchar *name);
|
||||
void ag_chart_set_name(AgChart *chart,
|
||||
const gchar *name);
|
||||
gchar *ag_chart_get_name(AgChart *chart);
|
||||
void ag_chart_set_country(AgChart *chart, const gchar *country);
|
||||
void ag_chart_set_country(AgChart *chart,
|
||||
const gchar *country);
|
||||
gchar *ag_chart_get_country(AgChart *chart);
|
||||
void ag_chart_set_city(AgChart *chart, const gchar *city);
|
||||
void ag_chart_set_city(AgChart *chart,
|
||||
const gchar *city);
|
||||
gchar *ag_chart_get_city(AgChart *chart);
|
||||
gchar *ag_chart_create_svg(AgChart *chart, GError **err);
|
||||
gchar *ag_chart_create_svg(AgChart *chart,
|
||||
GError **err);
|
||||
|
||||
#define AG_CHART_ERROR (ag_chart_error_quark())
|
||||
GQuark ag_chart_error_quark(void);
|
||||
|
120
src/ag-window.c
120
src/ag-window.c
@ -12,36 +12,36 @@
|
||||
#include "ag-chart.h"
|
||||
|
||||
struct _AgWindowPrivate {
|
||||
GtkWidget *grid;
|
||||
GtkWidget *header_bar;
|
||||
GtkWidget *stack;
|
||||
GtkWidget *stack_switcher;
|
||||
GtkWidget *name;
|
||||
GtkWidget *north_lat;
|
||||
GtkWidget *south_lat;
|
||||
GtkWidget *latitude;
|
||||
GtkWidget *east_long;
|
||||
GtkWidget *west_long;
|
||||
GtkWidget *longitude;
|
||||
GtkWidget *year;
|
||||
GtkWidget *month;
|
||||
GtkWidget *day;
|
||||
GtkWidget *hour;
|
||||
GtkWidget *minute;
|
||||
GtkWidget *second;
|
||||
GtkWidget *grid;
|
||||
GtkWidget *header_bar;
|
||||
GtkWidget *stack;
|
||||
GtkWidget *stack_switcher;
|
||||
GtkWidget *name;
|
||||
GtkWidget *north_lat;
|
||||
GtkWidget *south_lat;
|
||||
GtkWidget *latitude;
|
||||
GtkWidget *east_long;
|
||||
GtkWidget *west_long;
|
||||
GtkWidget *longitude;
|
||||
GtkWidget *year;
|
||||
GtkWidget *month;
|
||||
GtkWidget *day;
|
||||
GtkWidget *hour;
|
||||
GtkWidget *minute;
|
||||
GtkWidget *second;
|
||||
GtkBuilder *builder;
|
||||
|
||||
GtkWidget *tab_chart;
|
||||
GtkWidget *tab_aspects;
|
||||
GtkWidget *tab_points;
|
||||
GtkWidget *tab_edit;
|
||||
GtkWidget *current_tab;
|
||||
GtkWidget *tab_chart;
|
||||
GtkWidget *tab_aspects;
|
||||
GtkWidget *tab_points;
|
||||
GtkWidget *tab_edit;
|
||||
GtkWidget *current_tab;
|
||||
|
||||
AgChart *chart;
|
||||
gchar *uri;
|
||||
AgChart *chart;
|
||||
gchar *uri;
|
||||
};
|
||||
|
||||
G_DEFINE_QUARK(ag-window-error-quark, ag_window_error);
|
||||
G_DEFINE_QUARK(ag_window_error_quark, ag_window_error);
|
||||
|
||||
G_DEFINE_TYPE(AgWindow, ag_window, GTK_TYPE_APPLICATION_WINDOW);
|
||||
|
||||
@ -72,10 +72,10 @@ ag_window_close_action(GSimpleAction *action, GVariant *parameter, gpointer user
|
||||
static void
|
||||
ag_window_save_as(AgWindow *window, GError **err)
|
||||
{
|
||||
gchar *name,
|
||||
*file_name;
|
||||
gchar *name;
|
||||
gchar *file_name;
|
||||
GtkWidget *fs;
|
||||
gint response;
|
||||
gint response;
|
||||
|
||||
recalculate_chart(window);
|
||||
|
||||
@ -99,11 +99,11 @@ ag_window_save_as(AgWindow *window, GError **err)
|
||||
g_free(name);
|
||||
|
||||
fs = gtk_file_chooser_dialog_new(_("Save Chart"),
|
||||
GTK_WINDOW(window),
|
||||
GTK_FILE_CHOOSER_ACTION_SAVE,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
|
||||
NULL);
|
||||
GTK_WINDOW(window),
|
||||
GTK_FILE_CHOOSER_ACTION_SAVE,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
|
||||
NULL);
|
||||
gtk_dialog_set_default_response(GTK_DIALOG(fs), GTK_RESPONSE_ACCEPT);
|
||||
gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(fs), FALSE);
|
||||
gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(fs), TRUE);
|
||||
@ -126,8 +126,8 @@ static void
|
||||
ag_window_save_action(GSimpleAction *action, GVariant *parameter, gpointer user_data)
|
||||
{
|
||||
AgWindow *window = AG_WINDOW(user_data);
|
||||
GError *err = NULL;
|
||||
gchar *uri;
|
||||
GError *err = NULL;
|
||||
gchar *uri;
|
||||
|
||||
recalculate_chart(window);
|
||||
uri = ag_window_get_uri(window);
|
||||
@ -148,7 +148,7 @@ static void
|
||||
ag_window_save_as_action(GSimpleAction *action, GVariant *parameter, gpointer user_data)
|
||||
{
|
||||
AgWindow *window = AG_WINDOW(user_data);
|
||||
GError *err = NULL;
|
||||
GError *err = NULL;
|
||||
|
||||
recalculate_chart(window);
|
||||
ag_window_save_as(window, &err);
|
||||
@ -160,7 +160,7 @@ void
|
||||
ag_window_redraw_chart(AgWindow *window)
|
||||
{
|
||||
GError *err = NULL;
|
||||
gchar *svg_content;
|
||||
gchar *svg_content;
|
||||
|
||||
svg_content = ag_chart_create_svg(window->priv->chart, &err);
|
||||
|
||||
@ -175,10 +175,10 @@ ag_window_redraw_chart(AgWindow *window)
|
||||
void
|
||||
ag_window_update_from_chart(AgWindow *window)
|
||||
{
|
||||
GsweTimestamp *timestamp;
|
||||
GsweTimestamp *timestamp;
|
||||
GsweCoordinates *coordinates;
|
||||
|
||||
timestamp = gswe_moment_get_timestamp(GSWE_MOMENT(window->priv->chart));
|
||||
timestamp = gswe_moment_get_timestamp(GSWE_MOMENT(window->priv->chart));
|
||||
coordinates = gswe_moment_get_coordinates(GSWE_MOMENT(window->priv->chart));
|
||||
|
||||
gtk_spin_button_set_value(GTK_SPIN_BUTTON(window->priv->year), gswe_timestamp_get_gregorian_year(timestamp, NULL));
|
||||
@ -211,22 +211,22 @@ recalculate_chart(AgWindow *window)
|
||||
hour,
|
||||
minute,
|
||||
second;
|
||||
gdouble longitude,
|
||||
latitude;
|
||||
gboolean south,
|
||||
west;
|
||||
gdouble longitude,
|
||||
latitude;
|
||||
gboolean south,
|
||||
west;
|
||||
GsweTimestamp *timestamp;
|
||||
|
||||
g_debug("Recalculating chart data");
|
||||
|
||||
year = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(window->priv->year));
|
||||
month = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(window->priv->month));
|
||||
day = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(window->priv->day));
|
||||
hour = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(window->priv->hour));
|
||||
minute = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(window->priv->minute));
|
||||
second = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(window->priv->second));
|
||||
year = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(window->priv->year));
|
||||
month = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(window->priv->month));
|
||||
day = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(window->priv->day));
|
||||
hour = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(window->priv->hour));
|
||||
minute = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(window->priv->minute));
|
||||
second = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(window->priv->second));
|
||||
longitude = gtk_spin_button_get_value(GTK_SPIN_BUTTON(window->priv->longitude));
|
||||
latitude = gtk_spin_button_get_value(GTK_SPIN_BUTTON(window->priv->latitude));
|
||||
latitude = gtk_spin_button_get_value(GTK_SPIN_BUTTON(window->priv->latitude));
|
||||
|
||||
if ((south = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(window->priv->south_lat)))) {
|
||||
latitude = 0 - latitude;
|
||||
@ -255,7 +255,7 @@ static void
|
||||
tab_changed_cb(GdStack *stack, GParamSpec *pspec, AgWindow *window)
|
||||
{
|
||||
const gchar *active_tab_name = gd_stack_get_visible_child_name(stack);
|
||||
GtkWidget *active_tab;
|
||||
GtkWidget *active_tab;
|
||||
|
||||
g_debug("Active tab changed: %s", active_tab_name);
|
||||
|
||||
@ -280,7 +280,7 @@ tab_changed_cb(GdStack *stack, GParamSpec *pspec, AgWindow *window)
|
||||
static void
|
||||
ag_window_change_tab_action(GSimpleAction *action, GVariant *parameter, gpointer user_data)
|
||||
{
|
||||
AgWindow *window = user_data;
|
||||
AgWindow *window = user_data;
|
||||
const gchar *target_tab = g_variant_get_string(parameter, NULL);
|
||||
|
||||
gd_stack_set_visible_child_name(GD_STACK(window->priv->stack), target_tab);
|
||||
@ -299,13 +299,13 @@ static void
|
||||
ag_window_init(AgWindow *window)
|
||||
{
|
||||
AgWindowPrivate *priv;
|
||||
GtkAccelGroup *accel_group;
|
||||
GError *err = NULL;
|
||||
GtkAccelGroup *accel_group;
|
||||
GError *err = NULL;
|
||||
|
||||
window->priv = priv = GET_PRIVATE(window);
|
||||
|
||||
priv->chart = NULL;
|
||||
priv->uri = NULL;
|
||||
priv->uri = NULL;
|
||||
|
||||
gtk_window_set_hide_titlebar_when_maximized(GTK_WINDOW(window), TRUE);
|
||||
|
||||
@ -350,8 +350,8 @@ ag_window_class_init(AgWindowClass *klass)
|
||||
static GtkWidget *
|
||||
notebook_edit(AgWindow *window)
|
||||
{
|
||||
GtkWidget *grid;
|
||||
GtkWidget *label;
|
||||
GtkWidget *grid;
|
||||
GtkWidget *label;
|
||||
AgWindowPrivate *priv = window->priv;
|
||||
|
||||
grid = gtk_grid_new();
|
||||
@ -446,9 +446,9 @@ static void
|
||||
window_populate(AgWindow *window)
|
||||
{
|
||||
AgWindowPrivate *priv = window->priv;
|
||||
GtkWidget *menu_button,
|
||||
*scroll;
|
||||
GObject *menu;
|
||||
GtkWidget *menu_button;
|
||||
GtkWidget *scroll;
|
||||
GObject *menu;
|
||||
|
||||
priv->header_bar = gd_header_bar_new();
|
||||
gtk_widget_set_hexpand(priv->header_bar, TRUE);
|
||||
|
@ -19,13 +19,13 @@ typedef enum {
|
||||
#define AG_IS_WINDOW_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), AG_TYPE_WINDOW))
|
||||
#define AG_WINDOW_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), AG_TYPE_WINDOW, AgWindowClass))
|
||||
|
||||
typedef struct _AgWindow AgWindow;
|
||||
typedef struct _AgWindowClass AgWindowClass;
|
||||
typedef struct _AgWindow AgWindow;
|
||||
typedef struct _AgWindowClass AgWindowClass;
|
||||
typedef struct _AgWindowPrivate AgWindowPrivate;
|
||||
|
||||
struct _AgWindow {
|
||||
GtkApplicationWindow parent_instance;
|
||||
AgWindowPrivate *priv;
|
||||
AgWindowPrivate *priv;
|
||||
};
|
||||
|
||||
struct _AgWindowClass {
|
||||
@ -34,10 +34,12 @@ struct _AgWindowClass {
|
||||
|
||||
GType ag_window_get_type(void) G_GNUC_CONST;
|
||||
GtkWidget *ag_window_new(AgApp *app);
|
||||
void ag_window_set_chart(AgWindow *window, AgChart *chart);
|
||||
void ag_window_set_chart(AgWindow *window,
|
||||
AgChart *chart);
|
||||
AgChart *ag_window_get_chart(AgWindow *window);
|
||||
void ag_window_update_from_chart(AgWindow *window);
|
||||
void ag_window_set_uri(AgWindow *window, const gchar *uri);
|
||||
void ag_window_set_uri(AgWindow *window,
|
||||
const gchar *uri);
|
||||
gchar *ag_window_get_uri(AgWindow *window);
|
||||
|
||||
#define AG_WINDOW_ERROR (ag_window_error_quark())
|
||||
|
@ -17,11 +17,11 @@
|
||||
|
||||
#define UI_FILE PKGDATADIR "/astrognome.ui"
|
||||
|
||||
GtkBuilder *builder;
|
||||
GtkFileFilter *filter_all = NULL,
|
||||
*filter_chart = NULL;
|
||||
GtkBuilder *builder;
|
||||
GtkFileFilter *filter_all = NULL;
|
||||
GtkFileFilter *filter_chart = NULL;
|
||||
|
||||
const char *moonStateName[] = {
|
||||
const char *moonStateName[] = {
|
||||
"New Moon",
|
||||
"Waxing Crescent Moon",
|
||||
"Waxing Half Moon",
|
||||
@ -50,12 +50,12 @@ init_filters(void)
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
gint status;
|
||||
AgApp *app;
|
||||
GError *err = NULL;
|
||||
gint status;
|
||||
AgApp *app;
|
||||
GError *err = NULL;
|
||||
AstrognomeOptions options;
|
||||
|
||||
GOptionEntry option_entries[] = {
|
||||
GOptionEntry option_entries[] = {
|
||||
{ "new-window", 'n', 0, G_OPTION_ARG_NONE, &(options.new_window), N_("Opens a new Astrognome window"), NULL },
|
||||
{ "version", 'v', 0, G_OPTION_ARG_NONE, &(options.version), N_("Display version and exit"), NULL },
|
||||
{ "quit", 'q', 0, G_OPTION_ARG_NONE, &(options.quit), N_("Quit any running Astrognome"), NULL },
|
||||
|
@ -7,8 +7,8 @@ typedef struct {
|
||||
gboolean new_window;
|
||||
} AstrognomeOptions;
|
||||
|
||||
extern GtkFileFilter *filter_all,
|
||||
*filter_chart;
|
||||
extern GtkFileFilter *filter_all;
|
||||
extern GtkFileFilter *filter_chart;
|
||||
|
||||
#endif /* __ASTROGNOME_H__ */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user