Merge pull request #77 from gergelypolonkai/display-themes

Add display theme support
This commit is contained in:
Gergely Polonkai 2014-09-14 14:35:11 +02:00
commit 0af9bcc13f
20 changed files with 1258 additions and 558 deletions

View File

@ -22,6 +22,11 @@
<summary>The default house system</summary>
<description>The house system to use by default in new charts</description>
</key>
<key name="default-display-theme" type="i">
<default>-1</default>
<summary>The ID of the default display theme to use</summary>
<description>The database ID of the display theme to be used when a chart is created/opened.</description>
</key>
</schema>
<schema id="eu.polonkai.gergely.Astrognome.state" path="/eu/polonkai/gergely/Astrognome/state/">
<child name="window" schema="eu.polonkai.gergely.Astrognome.state.window" />
@ -44,11 +49,4 @@
<description>The height of newly created windows.</description>
</key>
</schema>
<schema id="eu.polonkai.gergely.Astrognome.state.chart" path="/eu/polonkai/gergely/Astrognome/state/chart/">
<key name="classic-only" type="b">
<default>false</default>
<summary>Use the classical view</summary>
<description>Use the classical view: planets only between Sun and Saturn, only Ptolemaic aspects, no antiscia.</description>
</key>
</schema>
</schemalist>

View File

@ -13,13 +13,14 @@ BUILT_SOURCES = \
$(NULL)
astrognome_source_files = \
ag-app.c \
ag-window.c \
ag-chart.c \
ag-settings.c \
ag-preferences.c \
ag-db.c \
astrognome.c \
ag-app.c \
ag-window.c \
ag-chart.c \
ag-settings.c \
ag-preferences.c \
ag-db.c \
ag-display-theme.c \
astrognome.c \
$(NULL)
EXTRA_DIST = \

View File

@ -8,11 +8,7 @@
#include "config.h"
#include "astrognome.h"
typedef struct _AgAppPrivate {
WebKitUserContentManager *manager;
} AgAppPrivate;
G_DEFINE_TYPE_WITH_PRIVATE(AgApp, ag_app, GTK_TYPE_APPLICATION);
G_DEFINE_TYPE(AgApp, ag_app, GTK_TYPE_APPLICATION);
GtkWindow *
ag_app_peek_first_window(AgApp *app)
@ -56,9 +52,8 @@ static GtkWidget *
ag_app_create_window(AgApp *app)
{
GtkWidget *window;
AgAppPrivate *priv = ag_app_get_instance_private(app);
window = ag_window_new(app, priv->manager);
window = ag_window_new(app);
gtk_application_add_window(GTK_APPLICATION(app), GTK_WINDOW(window));
gtk_widget_show_all(window);
@ -432,33 +427,6 @@ ag_app_new(void)
static void
ag_app_init(AgApp *app)
{
AgAppPrivate *priv;
GBytes *css_data;
const gchar *css_source;
gsize css_length;
WebKitUserStyleSheet *stylesheet;
priv = ag_app_get_instance_private(app);
priv->manager = webkit_user_content_manager_new();
css_data = g_resources_lookup_data(
"/eu/polonkai/gergely/Astrognome/ui/chart-default.css",
G_RESOURCE_LOOKUP_FLAGS_NONE,
NULL
);
if ((css_source = g_bytes_get_data(css_data, &css_length)) != NULL) {
stylesheet = webkit_user_style_sheet_new(
css_source,
WEBKIT_USER_CONTENT_INJECT_TOP_FRAME,
WEBKIT_USER_STYLE_LEVEL_USER,
NULL, NULL
);
webkit_user_content_manager_add_style_sheet(priv->manager, stylesheet);
webkit_user_style_sheet_unref(stylesheet);
}
g_bytes_unref(css_data);
}
static void

View File

@ -12,6 +12,7 @@
#include <string.h>
#include "config.h"
#include "astrognome.h"
#include "ag-db.h"
#include "ag-chart.h"
#include "placidus.h"
@ -221,145 +222,18 @@ ag_chart_finalize(GObject *gobject)
void
ag_chart_add_planets(AgChart *chart)
{
int i;
AgChartPrivate *priv = ag_chart_get_instance_private(chart);
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_CHARIKLO, NULL);
priv->planet_list = g_list_prepend(
priv->planet_list,
GINT_TO_POINTER(GSWE_PLANET_CHARIKLO)
);
for (i = 0; i < used_planets_count; i++) {
gswe_moment_add_planet(GSWE_MOMENT(chart), used_planets[i], NULL);
priv->planet_list = g_list_prepend(
priv->planet_list,
GINT_TO_POINTER(used_planets[i])
);
}
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_VESTA, NULL);
priv->planet_list = g_list_prepend(
priv->planet_list,
GINT_TO_POINTER(GSWE_PLANET_VESTA)
);
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_JUNO, NULL);
priv->planet_list = g_list_prepend(
priv->planet_list,
GINT_TO_POINTER(GSWE_PLANET_JUNO)
);
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_PALLAS, NULL);
priv->planet_list = g_list_prepend(
priv->planet_list,
GINT_TO_POINTER(GSWE_PLANET_PALLAS)
);
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_CERES, NULL);
priv->planet_list = g_list_prepend(
priv->planet_list,
GINT_TO_POINTER(GSWE_PLANET_CERES)
);
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_NESSUS, NULL);
priv->planet_list = g_list_prepend(
priv->planet_list,
GINT_TO_POINTER(GSWE_PLANET_NESSUS)
);
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_PHOLUS, NULL);
priv->planet_list = g_list_prepend(
priv->planet_list,
GINT_TO_POINTER(GSWE_PLANET_PHOLUS)
);
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_CHIRON, NULL);
priv->planet_list = g_list_prepend(
priv->planet_list,
GINT_TO_POINTER(GSWE_PLANET_CHIRON)
);
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_MOON_APOGEE, NULL);
priv->planet_list = g_list_prepend(
priv->planet_list,
GINT_TO_POINTER(GSWE_PLANET_MOON_APOGEE)
);
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_MOON_NODE, NULL);
priv->planet_list = g_list_prepend(
priv->planet_list,
GINT_TO_POINTER(GSWE_PLANET_MOON_NODE)
);
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_PLUTO, NULL);
priv->planet_list = g_list_prepend(
priv->planet_list,
GINT_TO_POINTER(GSWE_PLANET_PLUTO)
);
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_NEPTUNE, NULL);
priv->planet_list = g_list_prepend(
priv->planet_list,
GINT_TO_POINTER(GSWE_PLANET_NEPTUNE)
);
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_URANUS, NULL);
priv->planet_list = g_list_prepend(
priv->planet_list,
GINT_TO_POINTER(GSWE_PLANET_URANUS)
);
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_SATURN, NULL);
priv->planet_list = g_list_prepend(
priv->planet_list,
GINT_TO_POINTER(GSWE_PLANET_SATURN)
);
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_JUPITER, NULL);
priv->planet_list = g_list_prepend(
priv->planet_list,
GINT_TO_POINTER(GSWE_PLANET_JUPITER)
);
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_MARS, NULL);
priv->planet_list = g_list_prepend(
priv->planet_list,
GINT_TO_POINTER(GSWE_PLANET_MARS)
);
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_VENUS, NULL);
priv->planet_list = g_list_prepend(
priv->planet_list,
GINT_TO_POINTER(GSWE_PLANET_VENUS)
);
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_MERCURY, NULL);
priv->planet_list = g_list_prepend(
priv->planet_list,
GINT_TO_POINTER(GSWE_PLANET_MERCURY)
);
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_MOON, NULL);
priv->planet_list = g_list_prepend(
priv->planet_list,
GINT_TO_POINTER(GSWE_PLANET_MOON)
);
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_SUN, NULL);
priv->planet_list = g_list_prepend(
priv->planet_list,
GINT_TO_POINTER(GSWE_PLANET_SUN)
);
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_VERTEX, NULL);
priv->planet_list = g_list_prepend(
priv->planet_list,
GINT_TO_POINTER(GSWE_PLANET_VERTEX)
);
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_ASCENDANT, NULL);
priv->planet_list = g_list_prepend(
priv->planet_list,
GINT_TO_POINTER(GSWE_PLANET_ASCENDANT)
);
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_MC, NULL);
priv->planet_list = g_list_prepend(
priv->planet_list,
GINT_TO_POINTER(GSWE_PLANET_MC)
);
priv->planet_list = g_list_reverse(priv->planet_list);
}
AgChart *
@ -1277,7 +1151,7 @@ AgChart *ag_chart_load_from_placidus_file(GFile *file,
}
AgChart *
ag_chart_new_from_db_save(AgDbSave *save_data, GError **err)
ag_chart_new_from_db_save(AgDbChartSave *save_data, GError **err)
{
GsweTimestamp *timestamp;
gchar *house_system_enum_name;
@ -1675,7 +1549,7 @@ ag_chart_create_svg(AgChart *chart, gsize *length, GError **err)
G_ENUM_CLASS(planets_class),
gswe_planet_data_get_planet(planet_data)
);
xmlNewProp(node, BAD_CAST "name", BAD_CAST enum_value->value_name);
xmlNewProp(node, BAD_CAST "name", BAD_CAST enum_value->value_nick);
value = g_malloc0(12);
g_ascii_dtostr(value, 12, gswe_planet_data_get_position(planet_data));
@ -1724,14 +1598,14 @@ ag_chart_create_svg(AgChart *chart, gsize *length, GError **err)
G_ENUM_CLASS(planets_class),
gswe_planet_data_get_planet(planet_data)
);
xmlNewProp(node, BAD_CAST "body1", BAD_CAST enum_value->value_name);
xmlNewProp(node, BAD_CAST "body1", BAD_CAST enum_value->value_nick);
planet_data = gswe_aspect_data_get_planet2(aspect_data);
enum_value = g_enum_get_value(
G_ENUM_CLASS(planets_class),
gswe_planet_data_get_planet(planet_data)
);
xmlNewProp(node, BAD_CAST "body2", BAD_CAST enum_value->value_name);
xmlNewProp(node, BAD_CAST "body2", BAD_CAST enum_value->value_nick);
enum_value = g_enum_get_value(
G_ENUM_CLASS(aspects_class),
@ -1769,20 +1643,20 @@ ag_chart_create_svg(AgChart *chart, gsize *length, GError **err)
G_ENUM_CLASS(planets_class),
gswe_planet_data_get_planet(planet_data)
);
xmlNewProp(node, BAD_CAST "body1", BAD_CAST enum_value->value_name);
xmlNewProp(node, BAD_CAST "body1", BAD_CAST enum_value->value_nick);
planet_data = gswe_antiscion_data_get_planet2(antiscion_data);
enum_value = g_enum_get_value(
G_ENUM_CLASS(planets_class),
gswe_planet_data_get_planet(planet_data)
);
xmlNewProp(node, BAD_CAST "body2", BAD_CAST enum_value->value_name);
xmlNewProp(node, BAD_CAST "body2", BAD_CAST enum_value->value_nick);
enum_value = g_enum_get_value(
G_ENUM_CLASS(antiscia_class),
gswe_antiscion_data_get_axis(antiscion_data)
);
xmlNewProp(node, BAD_CAST "axis", BAD_CAST enum_value->value_name);
xmlNewProp(node, BAD_CAST "axis", BAD_CAST enum_value->value_nick);
}
g_type_class_unref(planets_class);
@ -1908,12 +1782,12 @@ ag_chart_get_note(AgChart *chart)
return priv->note;
}
AgDbSave *
AgDbChartSave *
ag_chart_get_db_save(AgChart *chart, gint db_id)
{
GsweCoordinates *coords;
AgChartPrivate *priv = ag_chart_get_instance_private(chart);
AgDbSave *save_data = g_new0(AgDbSave, 1);
AgDbChartSave *save_data = g_new0(AgDbChartSave, 1);
GsweTimestamp *timestamp = gswe_moment_get_timestamp(GSWE_MOMENT(chart));
GEnumClass *house_system_class;
GEnumValue *house_system_enum;

View File

@ -57,7 +57,7 @@ AgChart *ag_chart_load_from_agc(GFile *file,
AgChart *ag_chart_load_from_placidus_file(GFile *file,
GError **err);
AgChart *ag_chart_new_from_db_save(AgDbSave *save_data, GError **err);
AgChart *ag_chart_new_from_db_save(AgDbChartSave *save_data, GError **err);
void ag_chart_save_to_file(AgChart *chart,
GFile *file,
@ -92,7 +92,7 @@ void ag_chart_set_note(AgChart *chart, const gchar *note);
const gchar *ag_chart_get_note(AgChart *chart);
AgDbSave *ag_chart_get_db_save(AgChart *chart, gint db_id);
AgDbChartSave *ag_chart_get_db_save(AgChart *chart, gint db_id);
#define AG_CHART_ERROR (ag_chart_error_quark())
GQuark ag_chart_error_quark(void);

View File

@ -22,50 +22,50 @@ G_DEFINE_QUARK(ag_db_error_quark, ag_db_error);
G_DEFINE_TYPE_WITH_PRIVATE(AgDb, ag_db, G_TYPE_OBJECT);
typedef enum {
COLUMN_ID,
COLUMN_NAME,
COLUMN_COUNTRY,
COLUMN_CITY,
COLUMN_LONGITUDE,
COLUMN_LATITUDE,
COLUMN_ALTITUDE,
COLUMN_YEAR,
COLUMN_MONTH,
COLUMN_DAY,
COLUMN_HOUR,
COLUMN_MINUTE,
COLUMN_SECOND,
COLUMN_TIMEZONE,
COLUMN_HOUSE_SYSTEM,
COLUMN_NOTE,
enum {
COLUMN_CHART_ID,
COLUMN_CHART_NAME,
COLUMN_CHART_COUNTRY,
COLUMN_CHART_CITY,
COLUMN_CHART_LONGITUDE,
COLUMN_CHART_LATITUDE,
COLUMN_CHART_ALTITUDE,
COLUMN_CHART_YEAR,
COLUMN_CHART_MONTH,
COLUMN_CHART_DAY,
COLUMN_CHART_HOUR,
COLUMN_CHART_MINUTE,
COLUMN_CHART_SECOND,
COLUMN_CHART_TIMEZONE,
COLUMN_CHART_HOUSE_SYSTEM,
COLUMN_CHART_NOTE,
/* Leave this as the last element */
COLUMN_COUNT
} ChartTableColumn;
COLUMN_CHART_COUNT
};
typedef struct {
ChartTableColumn id;
int id;
gchar *name;
} ChartTableColumnDef;
} TableColumnDef;
static ChartTableColumnDef chart_table_column[] = {
{ COLUMN_ID, "id" },
{ COLUMN_NAME, "name" },
{ COLUMN_COUNTRY, "country_name" },
{ COLUMN_CITY, "city_name" },
{ COLUMN_LONGITUDE, "longitude" },
{ COLUMN_LATITUDE, "latitude" },
{ COLUMN_ALTITUDE, "altitude" },
{ COLUMN_YEAR, "year" },
{ COLUMN_MONTH, "month" },
{ COLUMN_DAY, "day" },
{ COLUMN_HOUR, "hour" },
{ COLUMN_MINUTE, "minute" },
{ COLUMN_SECOND, "second" },
{ COLUMN_TIMEZONE, "timezone" },
{ COLUMN_HOUSE_SYSTEM, "house_system" },
{ COLUMN_NOTE, "note" },
static TableColumnDef chart_table_column[] = {
{ COLUMN_CHART_ID, "id" },
{ COLUMN_CHART_NAME, "name" },
{ COLUMN_CHART_COUNTRY, "country_name" },
{ COLUMN_CHART_CITY, "city_name" },
{ COLUMN_CHART_LONGITUDE, "longitude" },
{ COLUMN_CHART_LATITUDE, "latitude" },
{ COLUMN_CHART_ALTITUDE, "altitude" },
{ COLUMN_CHART_YEAR, "year" },
{ COLUMN_CHART_MONTH, "month" },
{ COLUMN_CHART_DAY, "day" },
{ COLUMN_CHART_HOUR, "hour" },
{ COLUMN_CHART_MINUTE, "minute" },
{ COLUMN_CHART_SECOND, "second" },
{ COLUMN_CHART_TIMEZONE, "timezone" },
{ COLUMN_CHART_HOUSE_SYSTEM, "house_system" },
{ COLUMN_CHART_NOTE, "note" },
};
/**
@ -542,12 +542,12 @@ ag_db_get(void)
/**
* ag_db_save_data_free:
* @save_data: the #AgDbSave struct to free
* @save_data: the #AgDbChartSave struct to free
*
* Frees @save_data and all its fields
*/
void
ag_db_save_data_free(AgDbSave *save_data)
ag_db_chart_save_free(AgDbChartSave *save_data)
{
if (!save_data) {
return;
@ -577,7 +577,7 @@ ag_db_save_data_free(AgDbSave *save_data)
}
/**
* ag_db_save_chart:
* ag_db_chart_save:
* @db: the #AgDb object to operate on
* @save_data: the data to save.
* @err: a #GError for storing errors
@ -589,7 +589,7 @@ ag_db_save_data_free(AgDbSave *save_data)
* Returns: TRUE if the save succeeds, FALSE otherwise
*/
gboolean
ag_db_save_chart(AgDb *db, AgDbSave *save_data, GError **err)
ag_db_chart_save(AgDb *db, AgDbChartSave *save_data, GError **err)
{
GError *local_err = NULL;
gboolean save_success = TRUE;
@ -780,7 +780,7 @@ ag_db_save_chart(AgDb *db, AgDbSave *save_data, GError **err)
}
/**
* ag_db_get_chart_list:
* ag_db_chart_get_list:
* @db: the #AgDb object to operate on
* @err: a #GError
*
@ -788,15 +788,15 @@ ag_db_save_chart(AgDb *db, AgDbSave *save_data, GError **err)
* value may be NULL even if there are no charts or if there was an error, you
* may want to check @err if the return value is NULL.
*
* Please be aware that the #AgDbSave objects of the returned value are not
* Please be aware that the #AgDbChartSave objects of the returned value are not
* fully realised chart records. To get one, you need to call
* ag_db_get_chart_data_by_id()
* ag_db_chart_get_data_by_id()
*
* Returns: (element-type AgDbSave) (transfer full): the list of all charts, or
* or NULL if there are none, or if there is an error.
* Returns: (element-type AgDbChartSave) (transfer full): the list of all
* charts, or NULL if there are none, or if there is an error.
*/
GList *
ag_db_get_chart_list(AgDb *db, GError **err)
ag_db_chart_get_list(AgDb *db, GError **err)
{
GdaDataModelIter *iter;
GList *ret = NULL;
@ -814,8 +814,8 @@ ag_db_get_chart_list(AgDb *db, GError **err)
iter = gda_data_model_create_iter(result);
while (gda_data_model_iter_move_next(iter)) {
const GValue *value;
AgDbSave *save_data = g_new0(AgDbSave, 1);
const GValue *value;
AgDbChartSave *save_data = g_new0(AgDbChartSave, 1);
value = gda_data_model_iter_get_value_at(iter, 0);
save_data->db_id = g_value_get_int(value);
@ -830,19 +830,19 @@ ag_db_get_chart_list(AgDb *db, GError **err)
}
/**
* ag_db_get_chart_data_by_id:
* ag_db_chart_get_data_by_id:
* @db: the #AgDb object to operate on
* @row_id: the ID field of the requested chart
* @err: a #GError
*
* Fetches the specified row from the chart table.
*
* Returns: (transfer full): A fully filled #AgDbSave record of the chart
* Returns: (transfer full): A fully filled #AgDbChartSave record of the chart
*/
AgDbSave *
ag_db_get_chart_data_by_id(AgDb *db, guint row_id, GError **err)
AgDbChartSave *
ag_db_chart_get_data_by_id(AgDb *db, guint row_id, GError **err)
{
AgDbSave *save_data;
AgDbChartSave *save_data;
const GValue *value;
gchar *query,
*columns;
@ -852,7 +852,7 @@ ag_db_get_chart_data_by_id(AgDb *db, guint row_id, GError **err)
columns = NULL;
for (i = 1; i < COLUMN_COUNT; i++) {
for (i = 1; i < COLUMN_CHART_COUNT; i++) {
gchar *tmp;
if (i == 1) {
@ -892,18 +892,28 @@ ag_db_get_chart_data_by_id(AgDb *db, guint row_id, GError **err)
return NULL;
}
save_data = g_new0(AgDbSave, 1);
save_data = g_new0(AgDbChartSave, 1);
/* id */
value = gda_data_model_get_value_at(result, COLUMN_ID, 0, NULL);
value = gda_data_model_get_value_at(
result,
COLUMN_CHART_ID,
0,
NULL
);
save_data->db_id = g_value_get_int(value);
/* name */
value = gda_data_model_get_value_at(result, COLUMN_NAME, 0, NULL);
value = gda_data_model_get_value_at(
result,
COLUMN_CHART_NAME,
0,
NULL
);
save_data->name = g_strdup(g_value_get_string(value));
/* country */
value = gda_data_model_get_value_at(result, COLUMN_COUNTRY, 0, NULL);
value = gda_data_model_get_value_at(result, COLUMN_CHART_COUNTRY, 0, NULL);
if (GDA_VALUE_HOLDS_NULL(value)) {
save_data->country = NULL;
@ -911,7 +921,7 @@ ag_db_get_chart_data_by_id(AgDb *db, guint row_id, GError **err)
save_data->country = g_strdup(g_value_get_string(value));
}
value = gda_data_model_get_value_at(result, COLUMN_CITY, 0, NULL);
value = gda_data_model_get_value_at(result, COLUMN_CHART_CITY, 0, NULL);
if (GDA_VALUE_HOLDS_NULL(value)) {
save_data->city = NULL;
@ -919,23 +929,23 @@ ag_db_get_chart_data_by_id(AgDb *db, guint row_id, GError **err)
save_data->city = g_strdup(g_value_get_string(value));
}
value = gda_data_model_get_value_at(
value = gda_data_model_get_value_at(
result,
COLUMN_LONGITUDE,
COLUMN_CHART_LONGITUDE,
0,
NULL
);
save_data->longitude = g_value_get_double(value);
value = gda_data_model_get_value_at(
value = gda_data_model_get_value_at(
result,
COLUMN_LATITUDE,
COLUMN_CHART_LATITUDE,
0,
NULL
);
save_data->latitude = g_value_get_double(value);
value = gda_data_model_get_value_at(result, COLUMN_ALTITUDE, 0, NULL);
value = gda_data_model_get_value_at(result, COLUMN_CHART_ALTITUDE, 0, NULL);
if (GDA_VALUE_HOLDS_NULL(value)) {
save_data->altitude = DEFAULT_ALTITUDE;
@ -943,56 +953,61 @@ ag_db_get_chart_data_by_id(AgDb *db, guint row_id, GError **err)
save_data->altitude = g_value_get_double(value);
}
value = gda_data_model_get_value_at(result, COLUMN_YEAR, 0, NULL);
value = gda_data_model_get_value_at(
result,
COLUMN_CHART_YEAR,
0,
NULL
);
save_data->year = g_value_get_int(value);
value = gda_data_model_get_value_at(
value = gda_data_model_get_value_at(
result,
COLUMN_MONTH,
COLUMN_CHART_MONTH,
0,
NULL
);
save_data->month = g_value_get_uint(value);
value = gda_data_model_get_value_at(result, COLUMN_DAY, 0, NULL);
value = gda_data_model_get_value_at(result, COLUMN_CHART_DAY, 0, NULL);
save_data->day = g_value_get_uint(value);
value = gda_data_model_get_value_at(result, COLUMN_HOUR, 0, NULL);
value = gda_data_model_get_value_at(result, COLUMN_CHART_HOUR, 0, NULL);
save_data->hour = g_value_get_uint(value);
value = gda_data_model_get_value_at(
value = gda_data_model_get_value_at(
result,
COLUMN_MINUTE,
COLUMN_CHART_MINUTE,
0,
NULL
);
save_data->minute = g_value_get_uint(value);
value = gda_data_model_get_value_at(
value = gda_data_model_get_value_at(
result,
COLUMN_SECOND,
COLUMN_CHART_SECOND,
0,
NULL
);
save_data->second = g_value_get_uint(value);
value = gda_data_model_get_value_at(
value = gda_data_model_get_value_at(
result,
COLUMN_TIMEZONE,
COLUMN_CHART_TIMEZONE,
0,
NULL
);
save_data->timezone = g_value_get_double(value);
value = gda_data_model_get_value_at(
value = gda_data_model_get_value_at(
result,
COLUMN_HOUSE_SYSTEM,
COLUMN_CHART_HOUSE_SYSTEM,
0,
NULL
);
save_data->house_system = g_strdup(g_value_get_string(value));
value = gda_data_model_get_value_at(result, COLUMN_NOTE, 0, NULL);
value = gda_data_model_get_value_at(result, COLUMN_CHART_NOTE, 0, NULL);
if (GDA_VALUE_HOLDS_NULL(value)) {
save_data->note = NULL;
@ -1038,17 +1053,19 @@ string_collate(const gchar *str1, const gchar *str2)
}
/**
* ag_db_save_identical:
* @a: the first #AgDbSave structure
* @b: the second #AgDbSave structure
* ag_db_chart_save_identical:
* @a: the first #AgDbChartSave structure
* @b: the second #AgDbChartSave structure
*
* Compares two #AgDbSave structures and their contents.
* Compares two #AgDbChartSave structures and their contents.
*
* Returns: TRUE if the two structs hold equal values (strings are also compared
* with string_collate()), FALSE otherwise
*/
gboolean
ag_db_save_identical(const AgDbSave *a, const AgDbSave *b, gboolean chart_only)
ag_db_chart_save_identical(const AgDbChartSave *a,
const AgDbChartSave *b,
gboolean chart_only)
{
if (a == b) {
g_debug("identical: Equal");
@ -1156,7 +1173,7 @@ ag_db_save_identical(const AgDbSave *a, const AgDbSave *b, gboolean chart_only)
}
gboolean
ag_db_delete_chart(AgDb *db, gint row_id, GError **err)
ag_db_chart_delete(AgDb *db, gint row_id, GError **err)
{
AgDbPrivate *priv = ag_db_get_instance_private(db);
GValue id = G_VALUE_INIT;

View File

@ -30,7 +30,7 @@ struct _AgDbClass {
GObjectClass parent_class;
};
typedef struct _AgDbSave {
typedef struct _AgDbChartSave {
gint db_id;
gchar *name;
gchar *country;
@ -47,7 +47,7 @@ typedef struct _AgDbSave {
gdouble timezone;
gchar *house_system;
gchar *note;
} AgDbSave;
} AgDbChartSave;
typedef enum {
AG_DB_ERROR_NO_CHART,
@ -58,21 +58,21 @@ GType ag_db_get_type(void) G_GNUC_CONST;
AgDb *ag_db_get(void);
void ag_db_save_data_free(AgDbSave *save_data);
void ag_db_chart_save_free(AgDbChartSave *save_data);
gboolean ag_db_save_chart(AgDb *db,
AgDbSave *save_data,
GError **err);
gboolean ag_db_chart_save(AgDb *db,
AgDbChartSave *save_data,
GError **err);
GList *ag_db_get_chart_list(AgDb *db, GError **err);
GList *ag_db_chart_get_list(AgDb *db, GError **err);
AgDbSave *ag_db_get_chart_data_by_id(AgDb *db, guint row_id, GError **err);
AgDbChartSave *ag_db_chart_get_data_by_id(AgDb *db, guint row_id, GError **err);
gboolean ag_db_delete_chart(AgDb *db, gint row_id, GError **err);
gboolean ag_db_chart_delete(AgDb *db, gint row_id, GError **err);
gboolean ag_db_save_identical(const AgDbSave *a,
const AgDbSave *b,
gboolean chart_only);
gboolean ag_db_chart_save_identical(const AgDbChartSave *a,
const AgDbChartSave *b,
gboolean chart_only);
#define AG_DB_ERROR (ag_db_error_quark())
GQuark ag_db_error_quark(void);

276
src/ag-display-theme.c Normal file
View File

@ -0,0 +1,276 @@
#include <glib/gi18n.h>
#include <swe-glib.h>
#include "astrognome.h"
#include "ag-display-theme.h"
static gchar *planet_all = ".planet {\n" \
" visibility: visible;\n" \
"}\n";
static gchar *planet_none = ".planet {\n" \
" visibility: hidden;\n" \
" }\n";
static gchar *planet_tmpl = ".planet-%s {\n" \
" visibility: %s !important;\n" \
"}\n";
static gchar *aspect_all = ".aspect {\n" \
" visibility: visible;\n" \
"}\n";
static gchar *aspect_none = ".aspect {\n" \
" visibility: hidden;\n" \
" }\n";
static gchar *aspect_tmpl = ".aspect-%s {\n" \
" visibility: %s !important;\n" \
"}\n";
static gchar *antiscion_all = ".antiscion {\n" \
" visibility: visible;\n" \
"}\n";
static gchar *antiscion_none = ".antiscion {\n" \
" visibility: hidden;\n" \
"}\n";
static gchar *antiscion_tmpl = ".antiscion-%s {\n" \
" visibility: %s !important;\n" \
"}\n";
static AgDisplayTheme **builtin_themes = NULL;
static gchar *builtin_theme_name[AG_DISPLAY_THEME_COUNT] = {
NC_("Display theme name", "Everything"),
NC_("Display theme name", "Classic"),
};
gchar *
ag_display_theme_to_css(AgDisplayTheme *theme)
{
GList *i;
gchar *ret;
GString *css = NULL;
if (theme->planets_include) {
css = g_string_new(planet_none);
} else {
css = g_string_new(planet_all);
}
for (i = theme->planets; i; i = g_list_next(i)) {
const gchar *planet_name;
planet_name = ag_planet_id_to_nick(GPOINTER_TO_INT(i->data));
g_string_append_printf(
css,
planet_tmpl,
planet_name,
(theme->planets_include) ? "visible" : "hidden"
);
}
if (theme->aspects_include) {
g_string_append(css, aspect_none);
} else {
g_string_append(css, aspect_all);
}
for (i = theme->aspects; i; i = g_list_next(i)) {
const gchar *aspect_name;
aspect_name = ag_aspect_id_to_nick(GPOINTER_TO_INT(i->data));
g_string_append_printf(
css,
aspect_tmpl,
aspect_name,
(theme->aspects_include) ? "visible" : "hidden"
);
}
if (theme->antiscia_include) {
g_string_append(css, antiscion_none);
} else {
g_string_append(css, antiscion_all);
}
for (i = theme->antiscia; i; i = g_list_next(i)) {
const gchar *antiscion_axis_name;
antiscion_axis_name = ag_antiscion_axis_id_to_nick(
GPOINTER_TO_INT(i->data)
);
g_string_append_printf(
css,
antiscion_tmpl,
antiscion_axis_name,
(theme->antiscia_include) ? "visible" : "hidden"
);
}
ret = g_string_free(css, FALSE);
g_debug("%s", ret);
return ret;
}
static AgDisplayTheme *
ag_display_theme_get_builtin(gint id)
{
AgDisplayTheme *theme;
// Builtin themes all have a negative ID
g_return_val_if_fail(id < 0, NULL);
// And must be greater then AG_DISPLAY_THEME_COUNT
g_return_val_if_fail(id >= -AG_DISPLAY_THEME_COUNT, NULL);
if (builtin_themes == NULL) {
builtin_themes = g_new0(AgDisplayTheme *, AG_DISPLAY_THEME_COUNT);
}
// If the theme is already created, return it
if (builtin_themes[-id] != NULL) {
return builtin_themes[-id];
}
theme = builtin_themes[-id] = g_new0(AgDisplayTheme, 1);
switch (id) {
case AG_DISPLAY_THEME_ALL:
theme->id = id;
theme->name = gettext(builtin_theme_name[-id - 1]);
theme->builtin = TRUE;
theme->planets_include = FALSE;
theme->planets = NULL;
theme->aspects_include = FALSE;
theme->aspects = NULL;
theme->antiscia_include = FALSE;
theme->antiscia = NULL;
break;
case AG_DISPLAY_THEME_CLASSIC:
// TODO: If SWE-GLib would support it, we could programatically get
// classic planets and aspects here, thus, if it is messed up,
// we need to fix it only once.
theme->id = id;
theme->name = gettext(builtin_theme_name[-id - 1]);
theme->builtin = TRUE;
theme->planets_include = TRUE;
theme->planets = NULL;
theme->aspects_include = TRUE;
theme->aspects = NULL;
theme->antiscia_include = TRUE;
theme->antiscia = NULL;
theme->planets = g_list_prepend(
theme->planets,
GINT_TO_POINTER(GSWE_PLANET_SUN)
);
theme->planets = g_list_prepend(
theme->planets,
GINT_TO_POINTER(GSWE_PLANET_MOON)
);
theme->planets = g_list_prepend(
theme->planets,
GINT_TO_POINTER(GSWE_PLANET_MERCURY)
);
theme->planets = g_list_prepend(
theme->planets,
GINT_TO_POINTER(GSWE_PLANET_VENUS)
);
theme->planets = g_list_prepend(
theme->planets,
GINT_TO_POINTER(GSWE_PLANET_MARS)
);
theme->planets = g_list_prepend(
theme->planets,
GINT_TO_POINTER(GSWE_PLANET_JUPITER)
);
theme->planets = g_list_prepend(
theme->planets,
GINT_TO_POINTER(GSWE_PLANET_SATURN)
);
theme->planets = g_list_prepend(
theme->planets,
GINT_TO_POINTER(GSWE_PLANET_MOON_NODE)
);
theme->aspects = g_list_prepend(
theme->aspects,
GINT_TO_POINTER(GSWE_ASPECT_CONJUCTION)
);
theme->aspects = g_list_prepend(
theme->aspects,
GINT_TO_POINTER(GSWE_ASPECT_OPPOSITION)
);
theme->aspects = g_list_prepend(
theme->aspects,
GINT_TO_POINTER(GSWE_ASPECT_TRINE)
);
theme->aspects = g_list_prepend(
theme->aspects,
GINT_TO_POINTER(GSWE_ASPECT_SQUARE)
);
theme->aspects = g_list_prepend(
theme->aspects,
GINT_TO_POINTER(GSWE_ASPECT_SEXTILE)
);
break;
default:
g_free(theme);
g_warning("Trying to instantiate unknown builtin theme %d", id);
return NULL;
}
return theme;
}
GList *
ag_display_theme_get_list(void)
{
int i;
GList *ret = NULL;
for (i = 1; i <= AG_DISPLAY_THEME_COUNT; i++) {
AgDisplayTheme *theme = ag_display_theme_get_builtin(-i);
ret = g_list_append(ret, theme);
}
return ret;
}
AgDisplayTheme *
ag_display_theme_get_by_id(int id)
{
if (id < 0) {
return ag_display_theme_get_builtin(id);
}
g_warning("Invalid theme ID. Falling back to display everything.");
return ag_display_theme_get_builtin(AG_DISPLAY_THEME_ALL);
}
void
ag_display_theme_free(AgDisplayTheme *display_theme)
{
if (!display_theme || display_theme->builtin)
{
return;
}
g_free(display_theme->name);
g_list_free(display_theme->planets);
g_list_free(display_theme->aspects);
g_list_free(display_theme->antiscia);
g_free(display_theme);
}

33
src/ag-display-theme.h Normal file
View File

@ -0,0 +1,33 @@
#ifndef __AG_DISPLAY_THEME_H__
#define __AG_DISPLAY_THEME_H__
#include <glib.h>
typedef struct _AgDisplayTheme {
gint id;
gchar *name;
gboolean builtin;
gboolean planets_include;
GList *planets;
gboolean aspects_include;
GList *aspects;
gboolean antiscia_include;
GList *antiscia;
} AgDisplayTheme;
enum {
AG_DISPLAY_THEME_ALL = -1,
AG_DISPLAY_THEME_CLASSIC = -2,
AG_DISPLAY_THEME_PREV,
AG_DISPLAY_THEME_COUNT = - AG_DISPLAY_THEME_PREV + 1
};
gchar *ag_display_theme_to_css(AgDisplayTheme *display_theme);
AgDisplayTheme *ag_display_theme_get_by_id(int id);
GList *ag_display_theme_get_list(void);
void ag_display_theme_free(AgDisplayTheme *display_theme);
#endif /* __AG_DISPLAY_THEME_H__ */

View File

@ -1,8 +1,10 @@
#include <gtk/gtk.h>
#include <swe-glib.h>
#include <stdlib.h>
#include "ag-settings.h"
#include "ag-preferences.h"
#include "ag-display-theme.h"
static GtkWidget *prefs_dialog = NULL;
@ -12,6 +14,8 @@ typedef struct _AgPreferencesPrivate {
GtkCheckButton *aspect_chars;
GtkWidget *house_system;
GtkListStore *house_system_model;
GtkWidget *display_theme;
GtkListStore *display_theme_model;
AgSettings *settings;
} AgPreferencesPrivate;
@ -75,6 +79,16 @@ ag_preferences_class_init(AgPreferencesClass *klass)
AgPreferences,
house_system_model
);
gtk_widget_class_bind_template_child_private(
widget_class,
AgPreferences,
display_theme
);
gtk_widget_class_bind_template_child_private(
widget_class,
AgPreferences,
display_theme_model
);
}
static void
@ -98,14 +112,68 @@ ag_preferences_add_house_system(GsweHouseSystemInfo *house_system_info,
);
}
static void
ag_preferences_add_display_theme(AgDisplayTheme *display_theme,
AgPreferencesPrivate *priv)
{
GtkTreeIter iter;
gchar *id_string = g_strdup_printf("%d", display_theme->id);
g_debug("Adding theme with ID %d ('%s')", display_theme->id, id_string);
gtk_list_store_append(priv->display_theme_model, &iter);
gtk_list_store_set(
priv->display_theme_model, &iter,
0, id_string,
1, display_theme->name,
-1
);
g_free(id_string);
}
static gboolean
ag_preferences_display_theme_get(GValue *value,
GVariant *variant,
gpointer user_data)
{
gint32 id = g_variant_get_int32(variant);
gchar *id_string = g_strdup_printf("%d", id);
g_debug("Converted %d to '%s'", id, id_string);
g_value_take_string(value, id_string);
return TRUE;
}
static GVariant *
ag_preferences_display_theme_set(const GValue *value,
const GVariantType *expected_type,
gpointer user_data)
{
const gchar *id_string;
gint32 id;
GVariant *variant;
id_string = g_value_get_string(value);
id = atoi(id_string);
g_debug("Converted '%s' to %d", id_string, id);
variant = g_variant_new_int32(id);
return variant;
}
static void
ag_preferences_init(AgPreferences *prefs)
{
GSettings *settings_window,
*settings_main;
GList *house_system_list = gswe_all_house_systems();
AgPreferencesPrivate *priv = ag_preferences_get_instance_private(prefs);
GtkCellRenderer *cell_renderer;
GList *house_system_list = gswe_all_house_systems(),
*display_theme_list = ag_display_theme_get_list();
AgPreferencesPrivate *priv = ag_preferences_get_instance_private(prefs);
gtk_widget_init_template(GTK_WIDGET(prefs));
priv->settings = ag_settings_get();
@ -127,6 +195,24 @@ ag_preferences_init(AgPreferences *prefs)
NULL
);
g_list_foreach(
display_theme_list,
(GFunc)ag_preferences_add_display_theme,
priv
);
cell_renderer = gtk_cell_renderer_text_new();
gtk_cell_layout_pack_start(
GTK_CELL_LAYOUT(priv->display_theme),
cell_renderer,
TRUE
);
gtk_cell_layout_set_attributes(
GTK_CELL_LAYOUT(priv->display_theme),
cell_renderer,
"text", 1,
NULL
);
settings_window = ag_settings_peek_window_settings(priv->settings);
g_settings_bind(
settings_window,
@ -158,6 +244,17 @@ ag_preferences_init(AgPreferences *prefs)
"active-id",
G_SETTINGS_BIND_DEFAULT
);
g_settings_bind_with_mapping(
settings_main,
"default-display-theme",
priv->display_theme,
"active-id",
G_SETTINGS_BIND_DEFAULT,
ag_preferences_display_theme_get,
ag_preferences_display_theme_set,
NULL,
NULL
);
}
void

View File

@ -2,15 +2,13 @@
#define SETTINGS_SCHEMA_ID_MAIN "eu.polonkai.gergely.Astrognome"
#define SETTINGS_SCHEMA_ID_WINDOW "eu.polonkai.gergely.Astrognome.state.window"
#define SETTINGS_SCHEMA_ID_CHART "eu.polonkai.gergely.Astrognome.state.chart"
static AgSettings *singleton = NULL;
struct _AgSettingsPrivate {
typedef struct _AgSettingsPrivate {
GSettings *settings_main;
GSettings *settings_window;
GSettings *settings_chart;
};
} AgSettingsPrivate;
G_DEFINE_TYPE_WITH_PRIVATE(AgSettings, ag_settings, G_TYPE_OBJECT);
@ -21,7 +19,6 @@ ag_settings_init(AgSettings *settings)
priv->settings_main = g_settings_new(SETTINGS_SCHEMA_ID_MAIN);
priv->settings_window = g_settings_new(SETTINGS_SCHEMA_ID_WINDOW);
priv->settings_chart = g_settings_new(SETTINGS_SCHEMA_ID_CHART);
}
static void
@ -32,7 +29,6 @@ ag_settings_dispose(GObject *object)
);
g_clear_object(&priv->settings_window);
g_clear_object(&priv->settings_chart);
g_clear_object(&priv->settings_main);
G_OBJECT_CLASS(ag_settings_parent_class)->dispose(object);
@ -84,11 +80,3 @@ ag_settings_peek_window_settings(AgSettings *settings)
return priv->settings_window;
}
GSettings *
ag_settings_peek_chart_settings(AgSettings *settings)
{
AgSettingsPrivate *priv = ag_settings_get_instance_private(settings);
return priv->settings_chart;
}

View File

@ -23,7 +23,6 @@ G_BEGIN_DECLS
typedef struct _AgSettings AgSettings;
typedef struct _AgSettingsClass AgSettingsClass;
typedef struct _AgSettingsPrivate AgSettingsPrivate;
struct _AgSettings {
GObject parent_instance;
@ -39,7 +38,6 @@ AgSettings *ag_settings_get(void);
GSettings *ag_settings_peek_main_settings(AgSettings *settings);
GSettings *ag_settings_peek_window_settings(AgSettings *settings);
GSettings *ag_settings_peek_chart_settings(AgSettings *settings);
G_END_DECLS

View File

@ -16,6 +16,7 @@
#include "ag-chart.h"
#include "ag-settings.h"
#include "ag-db.h"
#include "ag-display-theme.h"
struct _AgWindowPrivate {
GtkWidget *header_bar;
@ -40,6 +41,7 @@ struct _AgWindowPrivate {
GtkWidget *second;
GtkWidget *timezone;
GtkWidget *house_system;
GtkWidget *display_theme;
GtkWidget *tab_list;
GtkWidget *tab_chart;
@ -57,11 +59,14 @@ struct _AgWindowPrivate {
GtkTextBuffer *note_buffer;
GtkListStore *house_system_model;
GtkListStore *db_chart_data;
AgDbSave *saved_data;
AgDbChartSave *saved_data;
GtkEntryCompletion *country_comp;
GtkEntryCompletion *city_comp;
gchar *selected_country;
gchar *selected_city;
GList *style_sheets;
AgDisplayTheme *theme;
GtkListStore *display_theme_model;
};
struct cc_search {
@ -643,7 +648,7 @@ ag_window_chart_changed(AgChart *chart, AgWindow *window)
static void
ag_window_recalculate_chart(AgWindow *window, gboolean set_everything)
{
AgDbSave *edit_data,
AgDbChartSave *edit_data,
*chart_data;
AgWindowPrivate *priv = ag_window_get_instance_private(window);
gboolean south,
@ -673,7 +678,7 @@ ag_window_recalculate_chart(AgWindow *window, gboolean set_everything)
gtk_spin_button_update(GTK_SPIN_BUTTON(current));
}
edit_data = g_new0(AgDbSave, 1);
edit_data = g_new0(AgDbChartSave, 1);
edit_data->db_id = db_id;
@ -748,16 +753,16 @@ ag_window_recalculate_chart(AgWindow *window, gboolean set_everything)
: NULL
;
if (ag_db_save_identical(edit_data, chart_data, !set_everything)) {
if (ag_db_chart_save_identical(edit_data, chart_data, !set_everything)) {
g_debug("No redrawing needed");
ag_db_save_data_free(edit_data);
ag_db_save_data_free(chart_data);
ag_db_chart_save_free(edit_data);
ag_db_chart_save_free(chart_data);
return;
}
ag_db_save_data_free(chart_data);
ag_db_chart_save_free(chart_data);
g_debug("Recalculating chart data");
@ -799,7 +804,7 @@ ag_window_recalculate_chart(AgWindow *window, gboolean set_everything)
ag_chart_set_note(priv->chart, edit_data->note);
}
ag_db_save_data_free(edit_data);
ag_db_chart_save_free(edit_data);
}
static void
@ -989,7 +994,7 @@ ag_window_can_close(AgWindow *window, gboolean display_dialog)
gint db_id = (priv->saved_data)
? priv->saved_data->db_id
: -1;
AgDbSave *save_data = NULL;
AgDbChartSave *save_data = NULL;
AgDb *db = ag_db_get();
GError *err = NULL;
gboolean ret = TRUE;
@ -999,7 +1004,7 @@ ag_window_can_close(AgWindow *window, gboolean display_dialog)
save_data = ag_chart_get_db_save(priv->chart, db_id);
if (
!ag_db_save_identical(priv->saved_data, save_data, FALSE)
!ag_db_chart_save_identical(priv->saved_data, save_data, FALSE)
|| !(priv->saved_data)
|| (priv->saved_data->db_id == -1)
) {
@ -1020,7 +1025,7 @@ ag_window_can_close(AgWindow *window, gboolean display_dialog)
switch (response) {
case GTK_RESPONSE_YES:
if (!ag_db_save_chart(db, save_data, &err)) {
if (!ag_db_chart_save(db, save_data, &err)) {
ag_app_message_dialog(
GTK_WINDOW(window),
GTK_MESSAGE_ERROR,
@ -1051,7 +1056,7 @@ ag_window_can_close(AgWindow *window, gboolean display_dialog)
}
}
ag_db_save_data_free(save_data);
ag_db_chart_save_free(save_data);
return ret;
}
@ -1066,7 +1071,7 @@ ag_window_save_action(GSimpleAction *action,
AgDb *db = ag_db_get();
GError *err = NULL;
gint old_id;
AgDbSave *save_data;
AgDbChartSave *save_data;
ag_window_recalculate_chart(window, TRUE);
@ -1074,7 +1079,7 @@ ag_window_save_action(GSimpleAction *action,
old_id = (priv->saved_data) ? priv->saved_data->db_id : -1;
save_data = ag_chart_get_db_save(priv->chart, old_id);
if (!ag_db_save_chart(db, save_data, &err)) {
if (!ag_db_chart_save(db, save_data, &err)) {
ag_app_message_dialog(
GTK_WINDOW(window),
GTK_MESSAGE_ERROR,
@ -1083,7 +1088,7 @@ ag_window_save_action(GSimpleAction *action,
);
}
ag_db_save_data_free(priv->saved_data);
ag_db_chart_save_free(priv->saved_data);
priv->saved_data = save_data;
}
}
@ -1108,6 +1113,130 @@ ag_window_delete_event_callback(AgWindow *window,
return (!ag_window_can_close(window, TRUE));
}
static void
ag_window_clear_style_sheets(AgWindow *window)
{
WebKitUserContentManager *manager;
AgWindowPrivate *priv = ag_window_get_instance_private(window);
g_debug("Clearing style sheets");
manager = webkit_web_view_get_user_content_manager(
WEBKIT_WEB_VIEW(priv->chart_web_view)
);
webkit_user_content_manager_remove_all_style_sheets(manager);
g_list_free_full(
priv->style_sheets,
(GDestroyNotify)webkit_user_style_sheet_unref
);
priv->style_sheets = NULL;
}
static void
ag_window_add_style_sheet(AgWindow *window, const gchar *path)
{
gchar *css_source;
gboolean source_free = FALSE;
AgWindowPrivate *priv = ag_window_get_instance_private(window);
if (strncmp("gres://", path, 7) == 0) {
gchar *res_path = g_strdup_printf(
"/eu/polonkai/gergely/Astrognome/%s",
path + 7
);
GBytes *css_data = g_resources_lookup_data(
res_path,
G_RESOURCE_LOOKUP_FLAGS_NONE,
NULL
);
css_source = g_strdup(g_bytes_get_data(css_data, NULL));
source_free = TRUE;
g_bytes_unref(css_data);
} else if (strncmp("raw:", path, 4) == 0) {
css_source = (gchar *)path + 4;
} else {
GFile *css_file = g_file_new_for_uri(path);
GError *err = NULL;
g_file_load_contents(
css_file,
NULL,
&css_source, NULL,
NULL,
&err
);
source_free = TRUE;
g_object_unref(css_file);
}
if (css_source) {
WebKitUserStyleSheet *style_sheet = webkit_user_style_sheet_new(
css_source,
WEBKIT_USER_CONTENT_INJECT_TOP_FRAME,
WEBKIT_USER_STYLE_LEVEL_USER,
NULL, NULL
);
priv->style_sheets = g_list_append(priv->style_sheets, style_sheet);
if (source_free) {
g_free(css_source);
}
}
}
static void
ag_window_update_style_sheets(AgWindow *window)
{
GList *item;
WebKitUserContentManager *manager;
AgWindowPrivate *priv = ag_window_get_instance_private(window);
g_debug("Updating style sheets");
manager = webkit_web_view_get_user_content_manager(
WEBKIT_WEB_VIEW(priv->chart_web_view)
);
webkit_user_content_manager_remove_all_style_sheets(manager);
for (item = priv->style_sheets; item; item = g_list_next(item)) {
WebKitUserStyleSheet *style_sheet = item->data;
webkit_user_content_manager_add_style_sheet(manager, style_sheet);
}
}
static void
ag_window_set_theme(AgWindow *window, AgDisplayTheme *theme)
{
gchar *css,
*css_final;
g_debug("Setting theme to %s", (theme) ? theme->name : "no theme");
ag_window_clear_style_sheets(window);
// Add the default style sheet
ag_window_add_style_sheet(
window,
"gres://ui/chart-default.css"
);
if (theme) {
css = ag_display_theme_to_css(theme);
css_final = g_strdup_printf("raw:%s", css);
g_free(css);
ag_window_add_style_sheet(window, css_final);
g_free(css_final);
}
ag_window_update_style_sheets(window);
}
static void
ag_window_tab_changed_cb(GtkStack *stack, GParamSpec *pspec, AgWindow *window)
{
@ -1125,6 +1254,23 @@ ag_window_tab_changed_cb(GtkStack *stack, GParamSpec *pspec, AgWindow *window)
if (strcmp("chart", active_tab_name) == 0) {
gtk_widget_set_size_request(active_tab, 600, 600);
if (priv->theme == NULL) {
AgSettings *settings;
GSettings *main_settings;
gint default_theme;
settings = ag_settings_get();
main_settings = ag_settings_peek_main_settings(settings);
default_theme = g_settings_get_int(
main_settings,
"default-display-theme"
);
g_object_unref(settings);
priv->theme = ag_display_theme_get_by_id(default_theme);
ag_window_set_theme(window, priv->theme);
}
}
if (strcmp("list", active_tab_name) == 0) {
@ -1203,6 +1349,37 @@ ag_window_set_default_house_system(GtkTreeModel *model,
return FALSE;
}
static gboolean
ag_window_set_default_display_theme(GtkTreeModel *model,
GtkTreePath *path,
GtkTreeIter *iter,
AgWindow *window)
{
gint row_display_theme;
AgWindowPrivate *priv = ag_window_get_instance_private(window);
AgSettings *settings = ag_settings_get();
GSettings *main_settings = ag_settings_peek_main_settings(settings);
gint default_theme = g_settings_get_int(
main_settings,
"default-display-theme"
);
g_clear_object(&settings);
gtk_tree_model_get(
model, iter,
0, &row_display_theme,
-1
);
if (default_theme == row_display_theme) {
gtk_combo_box_set_active_iter(GTK_COMBO_BOX(priv->display_theme), iter);
return TRUE;
}
return FALSE;
}
static void
ag_window_new_chart_action(GSimpleAction *action,
GVariant *parameter,
@ -1262,7 +1439,7 @@ ag_window_back_action(GSimpleAction *action,
if (ag_window_can_close(window, TRUE)) {
g_clear_object(&(priv->chart));
ag_db_save_data_free(priv->saved_data);
ag_db_chart_save_free(priv->saved_data);
priv->saved_data = NULL;
ag_window_load_chart_list(window);
@ -1355,7 +1532,7 @@ ag_window_delete_action(GSimpleAction *action,
id = atoi(id_str);
g_free(id_str);
if (!ag_db_delete_chart(db, id, &err)) {
if (!ag_db_chart_delete(db, id, &err)) {
ag_app_message_dialog(
GTK_WINDOW(window),
GTK_MESSAGE_ERROR,
@ -1399,8 +1576,8 @@ ag_window_connection_action(GSimpleAction *action,
);
static gchar *js = "aspects = document.getElementById('aspects');\n" \
"antiscia = document.getElementById('antiscia');\n" \
"aspects.setAttribute('visibility', '%s');\n" \
"antiscia.setAttribute('visibility', '%s');\n";
"aspects.setAttribute('display', '%s');\n" \
"antiscia.setAttribute('display', '%s');\n";
current_state = g_action_get_state(G_ACTION(action));
@ -1414,10 +1591,10 @@ ag_window_connection_action(GSimpleAction *action,
if (strcmp("aspects", state) == 0) {
g_debug("Switching to aspects");
js_code = g_strdup_printf(js, "visible", "hidden");
js_code = g_strdup_printf(js, "block", "none");
} else if (strcmp("antiscia", state) == 0) {
g_debug("Switching to antiscia");
js_code = g_strdup_printf(js, "hidden", "visible");
js_code = g_strdup_printf(js, "none", "block");
} else {
g_warning("Connection type '%s' is invalid", state);
}
@ -1480,6 +1657,21 @@ ag_window_add_house_system(GsweHouseSystemInfo *house_system_info,
);
}
static void
ag_window_add_display_theme(AgDisplayTheme *display_theme,
AgWindowPrivate *priv)
{
GtkTreeIter iter;
gtk_list_store_append(priv->display_theme_model, &iter);
gtk_list_store_set(
priv->display_theme_model, &iter,
0, display_theme->id,
1, display_theme->name,
-1
);
}
static void
ag_window_list_item_activated_cb(GdMainView *view,
const gchar *id,
@ -1507,7 +1699,7 @@ ag_window_list_item_activated_cb(GdMainView *view,
g_debug("Loading chart with ID %d", row_id);
if ((priv->saved_data = ag_db_get_chart_data_by_id(
if ((priv->saved_data = ag_db_chart_get_data_by_id(
db,
row_id,
&err)) == NULL) {
@ -1534,7 +1726,7 @@ ag_window_list_item_activated_cb(GdMainView *view,
"Error: %s",
err->message
);
ag_db_save_data_free(priv->saved_data);
ag_db_chart_save_free(priv->saved_data);
priv->saved_data = NULL;
return;
@ -1612,17 +1804,46 @@ ag_window_city_matches(GtkEntryCompletion *city_comp,
return ret;
}
gboolean
ag_window_chart_context_cb(WebKitWebView *web_view,
GtkWidget *default_menu,
WebKitHitTestResult *hit_test_result,
gboolean triggered_with_keyboard,
gpointer user_data)
{
return TRUE;
}
static void
ag_window_init(AgWindow *window)
{
GtkAccelGroup *accel_group;
GSettings *main_settings;
GList *house_system_list;
GtkCellRenderer *house_system_renderer;
AgWindowPrivate *priv = ag_window_get_instance_private(window);
GtkAccelGroup *accel_group;
GSettings *main_settings;
GList *house_system_list,
*display_theme_list;
GtkCellRenderer *house_system_renderer,
*display_theme_renderer;
WebKitUserContentManager *manager = webkit_user_content_manager_new();
AgWindowPrivate *priv = ag_window_get_instance_private(window);
gtk_widget_init_template(GTK_WIDGET(window));
priv->chart_web_view = webkit_web_view_new_with_user_content_manager(
manager
);
gtk_box_pack_end(
GTK_BOX(priv->tab_chart),
priv->chart_web_view,
TRUE, TRUE, 0
);
g_signal_connect(
priv->chart_web_view,
"context-menu",
G_CALLBACK(ag_window_chart_context_cb),
NULL
);
priv->settings = ag_settings_get();
main_settings = ag_settings_peek_main_settings(priv->settings);
@ -1678,6 +1899,32 @@ ag_window_init(AgWindow *window)
NULL
);
display_theme_list = ag_display_theme_get_list();
g_list_foreach(
display_theme_list,
(GFunc)ag_window_add_display_theme,
priv
);
g_list_free_full(display_theme_list, (GDestroyNotify)ag_display_theme_free);
gtk_tree_model_foreach(
GTK_TREE_MODEL(priv->display_theme_model),
(GtkTreeModelForeachFunc)ag_window_set_default_display_theme,
window
);
display_theme_renderer = gtk_cell_renderer_text_new();
gtk_cell_layout_pack_start(
GTK_CELL_LAYOUT(priv->display_theme),
display_theme_renderer,
TRUE
);
gtk_cell_layout_set_attributes(
GTK_CELL_LAYOUT(priv->display_theme),
display_theme_renderer,
"text", 1,
NULL
);
priv->tab_list = GTK_WIDGET(gd_main_view_new(GD_MAIN_VIEW_ICON));
gtk_stack_add_titled(
GTK_STACK(priv->stack),
@ -1930,6 +2177,26 @@ ag_window_city_changed_callback(GtkSearchEntry *city, AgWindow *window)
}
}
void
ag_window_display_theme_changed_cb(GtkComboBox *combo_box,
AgWindow *window)
{
GtkTreeIter iter;
gint theme_id;
AgDisplayTheme *theme;
AgWindowPrivate *priv = ag_window_get_instance_private(window);
gtk_combo_box_get_active_iter(combo_box, &iter);
gtk_tree_model_get(
GTK_TREE_MODEL(priv->display_theme_model), &iter,
0, &theme_id,
-1
);
theme = ag_display_theme_get_by_id(theme_id);
ag_window_set_theme(window, theme);
}
static void
ag_window_class_init(AgWindowClass *klass)
{
@ -2074,6 +2341,16 @@ ag_window_class_init(AgWindowClass *klass)
AgWindow,
points_eq
);
gtk_widget_class_bind_template_child_private(
widget_class,
AgWindow,
display_theme
);
gtk_widget_class_bind_template_child_private(
widget_class,
AgWindow,
display_theme_model
);
gtk_widget_class_bind_template_callback(
widget_class,
@ -2095,16 +2372,10 @@ ag_window_class_init(AgWindowClass *klass)
widget_class,
ag_window_city_changed_callback
);
}
gboolean
ag_window_chart_context_cb(WebKitWebView *web_view,
GtkWidget *default_menu,
WebKitHitTestResult *hit_test_result,
gboolean triggered_with_keyboard,
gpointer user_data)
{
return TRUE;
gtk_widget_class_bind_template_callback(
widget_class,
ag_window_display_theme_changed_cb
);
}
static gboolean
@ -2124,26 +2395,10 @@ ag_window_configure_event_cb(GtkWidget *widget,
}
GtkWidget *
ag_window_new(AgApp *app, WebKitUserContentManager *manager)
ag_window_new(AgApp *app)
{
AgWindow *window = g_object_new(AG_TYPE_WINDOW, NULL);
AgWindowPrivate *priv = ag_window_get_instance_private(window);
priv->chart_web_view = webkit_web_view_new_with_user_content_manager(
manager
);
gtk_box_pack_end(
GTK_BOX(priv->tab_chart),
priv->chart_web_view,
TRUE, TRUE, 0
);
g_signal_connect(
priv->chart_web_view,
"context-menu",
G_CALLBACK(ag_window_chart_context_cb),
NULL
);
AgWindow *window = g_object_new(AG_TYPE_WINDOW, NULL);
AgWindowPrivate *priv = ag_window_get_instance_private(window);
// TODO: translate this error message!
webkit_web_view_load_html(
@ -2192,7 +2447,7 @@ ag_window_set_chart(AgWindow *window, AgChart *chart)
g_clear_object(&(priv->chart));
}
ag_db_save_data_free(priv->saved_data);
ag_db_chart_save_free(priv->saved_data);
priv->chart = chart;
g_signal_connect(
@ -2278,7 +2533,7 @@ ag_window_change_tab(AgWindow *window, const gchar *tab_name)
}
static void
ag_window_add_chart_to_list(AgDbSave *save_data, AgWindow *window)
ag_window_add_chart_to_list(AgDbChartSave *save_data, AgWindow *window)
{
GtkTreeIter iter;
AgWindowPrivate *priv = ag_window_get_instance_private(window);
@ -2313,7 +2568,7 @@ ag_window_load_chart_list(AgWindow *window)
{
AgDb *db = ag_db_get();
GError *err = NULL;
GList *chart_list = ag_db_get_chart_list(db, &err);
GList *chart_list = ag_db_chart_get_list(db, &err);
ag_window_clear_chart_list(window);
/* With only a few charts, this should be fine. Maybe implementing lazy

View File

@ -2,7 +2,6 @@
#define __AG_WINDOW_H__
#include <gtk/gtk.h>
#include <webkit2/webkit2.h>
#include "ag-app.h"
#include "ag-chart.h"
@ -41,7 +40,7 @@ struct _AgWindowClass {
GType ag_window_get_type(void) G_GNUC_CONST;
GtkWidget *ag_window_new(AgApp *app, WebKitUserContentManager *manager);
GtkWidget *ag_window_new(AgApp *app);
void ag_window_set_chart(AgWindow *window,
AgChart *chart);

View File

@ -27,6 +27,7 @@ GtkFileFilter *filter_hor = NULL;
GtkTreeModel *country_list = NULL;
GtkTreeModel *city_list = NULL;
GHashTable *xinclude_positions;
gsize used_planets_count;
const char *moonStateName[] = {
"New Moon",
@ -40,6 +41,32 @@ const char *moonStateName[] = {
"Dark Moon"
};
const GswePlanet used_planets[] = {
GSWE_PLANET_MC,
GSWE_PLANET_ASCENDANT,
GSWE_PLANET_VERTEX,
GSWE_PLANET_SUN,
GSWE_PLANET_MOON,
GSWE_PLANET_MERCURY,
GSWE_PLANET_VENUS,
GSWE_PLANET_MARS,
GSWE_PLANET_JUPITER,
GSWE_PLANET_SATURN,
GSWE_PLANET_URANUS,
GSWE_PLANET_NEPTUNE,
GSWE_PLANET_PLUTO,
GSWE_PLANET_MOON_NODE,
GSWE_PLANET_MOON_APOGEE,
GSWE_PLANET_CHIRON,
GSWE_PLANET_PHOLUS,
GSWE_PLANET_NESSUS,
GSWE_PLANET_CERES,
GSWE_PLANET_PALLAS,
GSWE_PLANET_JUNO,
GSWE_PLANET_VESTA,
GSWE_PLANET_CHARIKLO
};
void
init_filters(void)
{
@ -188,6 +215,102 @@ ag_house_system_nick_to_id(const gchar *nick)
return GSWE_HOUSE_SYSTEM_NONE;
}
const gchar *
ag_planet_id_to_nick(GswePlanet planet)
{
GEnumClass *planet_class;
GEnumValue *enum_value;
planet_class = g_type_class_ref(GSWE_TYPE_PLANET);
enum_value = g_enum_get_value(planet_class, planet);
if (enum_value) {
return enum_value->value_nick;
}
return NULL;
}
GswePlanet
ag_planet_nick_to_id(const gchar *nick)
{
GEnumClass *planet_class;
GEnumValue *enum_value;
planet_class = g_type_class_ref(GSWE_TYPE_PLANET);
enum_value = g_enum_get_value_by_nick(planet_class, nick);
if (enum_value) {
return enum_value->value;
}
return GSWE_PLANET_NONE;
}
const gchar *
ag_aspect_id_to_nick(GsweAspect aspect)
{
GEnumClass *aspect_class;
GEnumValue *enum_value;
aspect_class = g_type_class_ref(GSWE_TYPE_ASPECT);
enum_value = g_enum_get_value(aspect_class, aspect);
if (enum_value) {
return enum_value->value_nick;
}
return NULL;
}
GsweAspect
ag_aspect_nick_to_id(const gchar *nick)
{
GEnumClass *aspect_class;
GEnumValue *enum_value;
aspect_class = g_type_class_ref(GSWE_TYPE_ASPECT);
enum_value = g_enum_get_value_by_nick(aspect_class, nick);
if (enum_value) {
return enum_value->value;
}
return GSWE_ASPECT_NONE;
}
const gchar *
ag_antiscion_axis_id_to_nick(GsweAntiscionAxis antiscion_axis)
{
GEnumClass *antiscion_axis_class;
GEnumValue *enum_value;
antiscion_axis_class = g_type_class_ref(GSWE_TYPE_ANTISCION_AXIS);
enum_value = g_enum_get_value(antiscion_axis_class, antiscion_axis);
if (enum_value) {
return enum_value->value_nick;
}
return NULL;
}
GsweAntiscionAxis
ag_antiscion_axis_nick_to_id(const gchar *nick)
{
GEnumClass *antiscion_axis_class;
GEnumValue *enum_value;
antiscion_axis_class = g_type_class_ref(GSWE_TYPE_ANTISCION_AXIS);
enum_value = g_enum_get_value_by_nick(antiscion_axis_class, nick);
if (enum_value) {
return enum_value->value;
}
return GSWE_ANTISCION_AXIS_NONE;
}
/**
* ag_get_user_data_dir:
*
@ -261,6 +384,7 @@ main(int argc, char *argv[])
textdomain(GETTEXT_PACKAGE);
#endif
used_planets_count = sizeof(used_planets) / sizeof(GswePlanet);
LIBXML_TEST_VERSION;
xmlSubstituteEntitiesDefault(1);
xmlLoadExtDtdDefaultValue = 1;

View File

@ -10,11 +10,13 @@ typedef struct {
gboolean new_window;
} AstrognomeOptions;
extern GtkFileFilter *filter_all;
extern GtkFileFilter *filter_chart;
extern GtkFileFilter *filter_hor;
extern GtkTreeModel *country_list;
extern GtkTreeModel *city_list;
extern GtkFileFilter *filter_all;
extern GtkFileFilter *filter_chart;
extern GtkFileFilter *filter_hor;
extern GtkTreeModel *country_list;
extern GtkTreeModel *city_list;
extern const GswePlanet used_planets[];
extern gsize used_planets_count;
enum {
AG_COUNTRY_CODE,
@ -35,6 +37,16 @@ enum {
const gchar *ag_house_system_id_to_nick(GsweHouseSystem house_system);
GsweHouseSystem ag_house_system_nick_to_id(const gchar *nick);
const gchar *ag_planet_id_to_nick(GswePlanet planet);
GswePlanet ag_planet_nick_to_id(const gchar *nick);
const gchar *ag_aspect_id_to_nick(GsweAspect aspect);
GsweAspect ag_aspect_nick_to_id(const gchar *nick);
const gchar *ag_antiscion_axis_id_to_nick(GsweAntiscionAxis antiscion_axis);
GsweAntiscionAxis ag_antiscion_axis_nick_to_id(const gchar *nick);
GFile *ag_get_user_data_dir(void);
#ifndef GDOUBLE_FROM_LE

View File

@ -10,11 +10,19 @@
<column type="gchararray"/>
</columns>
</object>
<object class="GtkListStore" id="display_theme_model">
<columns>
<!-- column-name display-theme-id -->
<column type="gchararray"/>
<!-- column-name display-theme-name -->
<column type="gchararray"/>
</columns>
</object>
<template class="AgPreferences" parent="GtkDialog">
<property name="can_focus">False</property>
<property name="type_hint">normal</property>
<child internal-child="vbox">
<object class="GtkBox" id="dialog-vbox1">
<object class="GtkBox">
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
@ -37,7 +45,7 @@
</packing>
</child>
<child>
<object class="GtkGrid" id="grid2">
<object class="GtkGrid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
@ -86,7 +94,7 @@
</packing>
</child>
<child>
<object class="GtkLabel" id="label1">
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Default house system</property>
@ -99,7 +107,7 @@
<child>
<object class="GtkComboBox" id="house_system">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="can_focus">True</property>
<property name="model">house_system_model</property>
<property name="id_column">0</property>
</object>
@ -108,6 +116,29 @@
<property name="top_attach">3</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Default display theme</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">4</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="display_theme">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="model">display_theme_model</property>
<property name="id_column">0</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">4</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>

View File

@ -114,6 +114,14 @@
<column type="gchararray"/>
</columns>
</object>
<object class="GtkListStore" id="display_theme_model">
<columns>
<!-- column-name display-theme-id -->
<column type="gint"/>
<!-- column-name display-theme-name -->
<column type="gchararray"/>
</columns>
</object>
<object class="GtkTextBuffer" id="note_buffer">
</object>
<object class="GtkListStore" id="db_chart_data">
@ -794,6 +802,15 @@
<property name="action_target">'antiscia'</property>
</object>
</child>
<child>
<object class="GtkComboBox" id="display_theme">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="model">display_theme_model</property>
<property name="id_column">1</property>
<signal name="changed" handler="ag_window_display_theme_changed_cb" swapped="no"/>
</object>
</child>
</object>
<packing>
<property name="pack_type">start</property>

View File

@ -128,3 +128,9 @@ line.aspect-biquintile {
line.aspect-quincunx {
stroke: #cc0000;
}
line.antiscion {
stroke-width: 1;
stroke: #000000;
stroke-dasharray: 20,10;
}

View File

@ -2,6 +2,7 @@
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:math="http://exslt.org/math">
<xsl:output
method="xml"
@ -18,6 +19,49 @@
<xsl:variable name="icon_size" select="30" />
<xsl:variable name="r_aspect" select="$image_size * 0.3" />
<xsl:template name="planet-template">
<xsl:param name="planet_name"/>
<xsl:param name="planet_base"/>
<xsl:param name="rotate"/>
<xsl:param name="dist"/>
<xsl:param name="retrograde"/>
<xsl:param name="upside-down"/>
<g xmlns="http://www.w3.org/2000/svg">
<xsl:attribute name="id">planet-<xsl:value-of select="$planet_name"/></xsl:attribute>
<xsl:attribute name="class">planet planet-<xsl:value-of select="$planet_name"/></xsl:attribute>
<xsl:attribute name="transform">rotate(<xsl:value-of select="-$rotate"/>, 0, 0)</xsl:attribute>
<line y1="0" y2="0" class="planet-marker">
<xsl:attribute name="x1"><xsl:value-of select="$image_size * 0.2875"/></xsl:attribute>
<xsl:attribute name="x2"><xsl:value-of select="$image_size * 0.3"/></xsl:attribute>
</line>
<line y1="0" y2="0" class="planet-marker">
<xsl:attribute name="x1"><xsl:value-of select="$image_size * 0.375"/></xsl:attribute>
<xsl:attribute name="x2"><xsl:value-of select="$image_size * 0.3875"/></xsl:attribute>
</line>
<g>
<xsl:attribute name="transform">translate(<xsl:value-of select="$image_size * 0.4125 + $dist * ($icon_size * 1.1666666)"/>, <xsl:value-of select="-$icon_size div 2"/>) rotate(<xsl:value-of select="$rotate - $asc_rotate"/>, <xsl:value-of select="$icon_size div 2"/>, <xsl:value-of select="$icon_size div 2"/>)</xsl:attribute>
<use class="planet-symbol">
<xsl:attribute name="xlink:href">#<xsl:value-of select="$planet_base"/>_tmpl</xsl:attribute>
<xsl:choose>
<xsl:when test="$upside-down='yes'">
<xsl:attribute name="transform">rotate(180, <xsl:value-of select="$icon_size div 2"/>, <xsl:value-of select="$icon_size div 2"/>)</xsl:attribute>
</xsl:when>
</xsl:choose>
</use>
<xsl:choose>
<xsl:when test="$retrograde='True'">
<text>
<xsl:attribute name="font-size"><xsl:value-of select="$icon_size div 2"/></xsl:attribute>
<xsl:attribute name="transform">translate(<xsl:value-of select="$icon_size"/>, <xsl:value-of select="$icon_size * 1.5"/>)</xsl:attribute>
R
</text>
</xsl:when>
</xsl:choose>
</g>
</g>
</xsl:template>
<xsl:template match="/">
<svg
xmlns="http://www.w3.org/2000/svg"
@ -505,7 +549,9 @@
<use x="0" y="0" xlink:href="#sign_pisces_tmpl" id="sign_pisces" class="sign sign-water">
<xsl:attribute name="transform">rotate(-345,0,0) translate(<xsl:value-of select="$image_size * 0.32625"/>,-<xsl:value-of select="$icon_size div 2"/>) rotate(90,<xsl:value-of select="$icon_size div 2"/>,<xsl:value-of select="$icon_size div 2"/>)</xsl:attribute>
</use>
</g>
<g id="houes">
<xsl:for-each select="chartinfo/houses/house">
<xsl:variable name="next_house" select="@number + 1"/>
<xsl:variable name="next_degree_read">
@ -581,191 +627,151 @@
<xsl:attribute name="x2"><xsl:value-of select="$image_size * 0.0625"/></xsl:attribute>
<xsl:attribute name="transform"><xsl:value-of select="concat('rotate(-', $mc, ')')" /></xsl:attribute>
</line>
</g>
<g id="planets">
<xsl:for-each select="chartinfo/ascmcs/vertex">
<xsl:variable name="planet_base">point_vertex</xsl:variable>
<xsl:variable name="degree"><xsl:value-of select="@degree_ut" /></xsl:variable>
<xsl:variable name="negative_degree"><xsl:value-of select="0 - $degree" /></xsl:variable>
<g>
<xsl:attribute name="id"><xsl:value-of select="$planet_base"/></xsl:attribute>
<xsl:attribute name="transform"><xsl:value-of select="concat('rotate(', $negative_degree, ',0,0)')"/></xsl:attribute>
<line y1="0" y2="0" class="planet-marker">
<xsl:attribute name="x1"><xsl:value-of select="$image_size * 0.2875"/></xsl:attribute>
<xsl:attribute name="x2"><xsl:value-of select="$image_size * 0.3"/></xsl:attribute>
<xsl:attribute name="id"><xsl:value-of select="concat('mark_', $planet_base)" /></xsl:attribute>
</line>
<line y1="0" y2="0" class="planet-marker">
<xsl:attribute name="x1"><xsl:value-of select="$image_size * 0.375"/></xsl:attribute>
<xsl:attribute name="x2"><xsl:value-of select="$image_size * 0.4"/></xsl:attribute>
<xsl:attribute name="id"><xsl:value-of select="concat('mark_', $planet_base, '_outer')" /></xsl:attribute>
</line>
<use class="planet-symbol">
<xsl:attribute name="xlink:href"><xsl:value-of select="concat('#', $planet_base, '_tmpl')"/></xsl:attribute>
<xsl:attribute name="transform"><xsl:value-of select="concat('translate(',$image_size * 0.4125,',-',$icon_size div 2,') rotate(', $degree - $asc_rotate ,',', $icon_size div 2, ',', $icon_size div 2, ')')"/></xsl:attribute>
</use>
</g>
</xsl:for-each>
<xsl:for-each select="chartinfo/bodies/body">
<xsl:variable name="planet_base" select="substring(translate(@name, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 6)"/>
<xsl:variable name="negative_degree"><xsl:value-of select="0 - @degree"/></xsl:variable>
<g>
<xsl:attribute name="id"><xsl:value-of select="$planet_base"/></xsl:attribute>
<xsl:attribute name="transform"><xsl:value-of select="concat('rotate(', $negative_degree, ',0,0)')"/></xsl:attribute>
<line y1="0" y2="0" class="planet-marker">
<xsl:attribute name="x1"><xsl:value-of select="$image_size * 0.2875"/></xsl:attribute>
<xsl:attribute name="x2"><xsl:value-of select="$image_size * 0.3"/></xsl:attribute>
<xsl:attribute name="id"><xsl:value-of select="concat('mark_', $planet_base)" /></xsl:attribute>
</line>
<line y1="0" y2="0" class="planet-marker">
<xsl:attribute name="x1"><xsl:value-of select="$image_size * 0.375"/></xsl:attribute>
<xsl:attribute name="x2"><xsl:value-of select="$image_size * 0.3875"/></xsl:attribute>
<xsl:attribute name="id"><xsl:value-of select="concat('mark_', $planet_base, '_outer')" /></xsl:attribute>
</line>
<use class="planet-symbol">
<xsl:attribute name="xlink:href"><xsl:value-of select="concat('#', $planet_base, '_tmpl')"/></xsl:attribute>
<xsl:attribute name="transform"><xsl:value-of select="concat('translate(', $image_size * 0.4125 + @dist * ($icon_size * 1.1666666), ',-', $icon_size div 2, ') rotate(', @degree - $asc_rotate ,',', $icon_size div 2, ',', $icon_size div 2, ')')"/></xsl:attribute>
</use>
<xsl:choose>
<xsl:when test="@retrograde='True'">
<text>
<xsl:attribute name="transform"><xsl:value-of select="concat('translate(', $image_size * 0.45625 + @dist * $icon_size * 1.1666666, ',', $icon_size div 2, ') rotate(', @degree - $asc_rotate, ',-', $icon_size * 0.666666, ',-', $icon_size * 0.666666, ')')"/></xsl:attribute>
R
</text>
</xsl:when>
</xsl:choose>
</g>
<g id="planets">
<xsl:for-each select="chartinfo/ascmcs/vertex">
<xsl:call-template name="planet-template">
<xsl:with-param name="planet_name">vertex</xsl:with-param>
<xsl:with-param name="rotate"><xsl:value-of select="@degree_ut"/></xsl:with-param>
<xsl:with-param name="planet_base">point_vertex</xsl:with-param>
<!-- TODO: dist must be calculated for Vertex, too! -->
<xsl:with-param name="dist">0</xsl:with-param>
<xsl:with-param name="retrograde">False</xsl:with-param>
</xsl:call-template>
</xsl:for-each>
<xsl:for-each select="chartinfo/bodies/body">
<xsl:call-template name="planet-template">
<xsl:with-param name="planet_name"><xsl:value-of select="@name"/></xsl:with-param>
<xsl:with-param name="rotate"><xsl:value-of select="@degree"/></xsl:with-param>
<xsl:with-param name="planet_base">planet_<xsl:value-of select="translate(@name, '-', '_')"/></xsl:with-param>
<xsl:with-param name="dist"><xsl:value-of select="@dist"/></xsl:with-param>
<xsl:with-param name="retrograde"><xsl:value-of select="@retrograde"/></xsl:with-param>
</xsl:call-template>
<xsl:choose>
<xsl:when test="@name='moon-node'">
<xsl:call-template name="planet-template">
<xsl:with-param name="planet_name"><xsl:value-of select="@name"/>-desc</xsl:with-param>
<xsl:with-param name="rotate"><xsl:value-of select="180 + @degree"/></xsl:with-param>
<xsl:with-param name="planet_base">planet_moon_node</xsl:with-param>
<xsl:with-param name="dist"><xsl:value-of select="@dist"/></xsl:with-param>
<xsl:with-param name="retrograde"><xsl:value-of select="@retrograde"/></xsl:with-param>
<xsl:with-param name="upside-down">yes</xsl:with-param>
</xsl:call-template>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</g>
<g id="aspects">
<xsl:for-each select="chartinfo/aspects/aspect">
<xsl:variable name="planet1" select="@body1"/>
<xsl:variable name="deg1">
<xsl:choose>
<xsl:when test="@name='GSWE_PLANET_MOON_NODE'">
<g>
<xsl:attribute name="id"><xsl:value-of select="concat($planet_base, '_desc')"/></xsl:attribute>
<xsl:attribute name="transform"><xsl:value-of select="concat('rotate(', 180 + $negative_degree, ',0,0)')"/></xsl:attribute>
<line y1="0" y2="0" class="planet-marker">
<xsl:attribute name="x1"><xsl:value-of select="$image_size * 0.2875"/></xsl:attribute>
<xsl:attribute name="x2"><xsl:value-of select="$image_size * 0.3"/></xsl:attribute>
<xsl:attribute name="id"><xsl:value-of select="concat('mark_', $planet_base)" /></xsl:attribute>
</line>
<line y1="0" y2="0" class="planet-marker">
<xsl:attribute name="x1"><xsl:value-of select="$image_size * 0.375"/></xsl:attribute>
<xsl:attribute name="x2"><xsl:value-of select="$image_size * 0.3875"/></xsl:attribute>
<xsl:attribute name="id"><xsl:value-of select="concat('mark_', $planet_base, '_outer')" /></xsl:attribute>
</line>
<use class="planet-symbol">
<xsl:attribute name="xlink:href"><xsl:value-of select="concat('#', $planet_base, '_tmpl')"/></xsl:attribute>
<xsl:attribute name="transform"><xsl:value-of select="concat('translate(', $image_size * 0.4125, ',-', $icon_size div 2, ') rotate(', @degree - $asc_rotate ,',', $icon_size div 2, ',', $icon_size div 2, ')')"/></xsl:attribute>
</use>
</g>
<xsl:when test="$planet1='ascendant'">
<xsl:value-of select="/chartinfo/ascmcs/ascendant/@degree_ut" />
</xsl:when>
<xsl:when test="$planet1='mc'">
<xsl:value-of select="/chartinfo/ascmcs/mc/@degree_ut" />
</xsl:when>
<xsl:when test="$planet1='vertex'">
<xsl:value-of select="/chartinfo/ascmcs/vertex/@degree_ut" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="/chartinfo/bodies/body[@name=$planet1]/@degree" />
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</g>
</xsl:variable>
<xsl:variable name="rad1" select="$deg1 * $PI div 180"/>
<xsl:variable name="x1" select="$r_aspect * math:cos($rad1)"/>
<xsl:variable name="y1" select="$r_aspect * -math:sin($rad1)"/>
<g id="aspects">
<xsl:for-each select="chartinfo/aspects/aspect">
<xsl:variable name="planet1" select="@body1"/>
<xsl:variable name="deg1">
<xsl:choose>
<xsl:when test="$planet1='GSWE_PLANET_ASCENDANT'">
<xsl:value-of select="/chartinfo/ascmcs/ascendant/@degree_ut" />
</xsl:when>
<xsl:when test="$planet1='GSWE_PLANET_MC'">
<xsl:value-of select="/chartinfo/ascmcs/mc/@degree_ut" />
</xsl:when>
<xsl:when test="$planet1='GSWE_PLANET_VERTEX'">
<xsl:value-of select="/chartinfo/ascmcs/vertex/@degree_ut" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="/chartinfo/bodies/body[@name=$planet1]/@degree" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="rad1" select="$deg1 * $PI div 180"/>
<xsl:variable name="x1" select="$r_aspect * math:cos($rad1)"/>
<xsl:variable name="y1" select="$r_aspect * -math:sin($rad1)"/>
<xsl:variable name="planet2" select="@body2"/>
<xsl:variable name="deg2">
<xsl:choose>
<xsl:when test="$planet2='ascendant'">
<xsl:value-of select="/chartinfo/ascmcs/ascendant/@degree_ut" />
</xsl:when>
<xsl:when test="$planet2='mc'">
<xsl:value-of select="/chartinfo/ascmcs/mc/@degree_ut" />
</xsl:when>
<xsl:when test="$planet2='vertex'">
<xsl:value-of select="/chartinfo/ascmcs/vertex/@degree_ut" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="/chartinfo/bodies/body[@name=$planet2]/@degree" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="rad2" select="$deg2 * $PI div 180"/>
<xsl:variable name="x2" select="$r_aspect * math:cos($rad2)"/>
<xsl:variable name="y2" select="$r_aspect * -math:sin($rad2)"/>
<xsl:variable name="planet2" select="@body2"/>
<xsl:variable name="deg2">
<xsl:choose>
<xsl:when test="$planet2='GSWE_PLANET_ASCENDANT'">
<xsl:value-of select="/chartinfo/ascmcs/ascendant/@degree_ut" />
</xsl:when>
<xsl:when test="$planet2='GSWE_PLANET_MC'">
<xsl:value-of select="/chartinfo/ascmcs/mc/@degree_ut" />
</xsl:when>
<xsl:when test="$planet2='GSWE_PLANET_VERTEX'">
<xsl:value-of select="/chartinfo/ascmcs/vertex/@degree_ut" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="/chartinfo/bodies/body[@name=$planet2]/@degree" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="rad2" select="$deg2 * $PI div 180"/>
<xsl:variable name="x2" select="$r_aspect * math:cos($rad2)"/>
<xsl:variable name="y2" select="$r_aspect * -math:sin($rad2)"/>
<line class="aspect">
<xsl:attribute name="id">aspect-<xsl:value-of select="$planet1"/>-<xsl:value-of select="$planet2"/></xsl:attribute>
<xsl:attribute name="class">aspect aspect-<xsl:value-of select="@type"/> aspect-<xsl:value-of select="$planet1"/> aspect-<xsl:value-of select="$planet2"/></xsl:attribute>
<xsl:attribute name="x1"><xsl:value-of select="$x1"/></xsl:attribute>
<xsl:attribute name="y1"><xsl:value-of select="$y1"/></xsl:attribute>
<xsl:attribute name="x2"><xsl:value-of select="$x2"/></xsl:attribute>
<xsl:attribute name="y2"><xsl:value-of select="$y2"/></xsl:attribute>
</line>
</xsl:for-each>
</g>
<line class="aspect">
<xsl:attribute name="class"><xsl:value-of select="concat('aspect aspect-', @type)"/></xsl:attribute>
<xsl:attribute name="x1"><xsl:value-of select="$x1"/></xsl:attribute>
<xsl:attribute name="y1"><xsl:value-of select="$y1"/></xsl:attribute>
<xsl:attribute name="x2"><xsl:value-of select="$x2"/></xsl:attribute>
<xsl:attribute name="y2"><xsl:value-of select="$y2"/></xsl:attribute>
</line>
</xsl:for-each>
</g>
<g id="antiscia" display="none">
<xsl:for-each select="chartinfo/antiscia/antiscia">
<xsl:variable name="planet1" select="@body1"/>
<xsl:variable name="deg1">
<xsl:choose>
<xsl:when test="$planet1='ascendant'">
<xsl:value-of select="/chartinfo/ascmcs/ascendant/@degree_ut" />
</xsl:when>
<xsl:when test="$planet1='mc'">
<xsl:value-of select="/chartinfo/ascmcs/mc/@degree_ut" />
</xsl:when>
<xsl:when test="$planet1='vertex'">
<xsl:value-of select="/chartinfo/ascmcs/vertex/@degree_ut" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="/chartinfo/bodies/body[@name=$planet1]/@degree" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="rad1" select="$deg1 * $PI div 180"/>
<xsl:variable name="x1" select="$r_aspect * math:cos($rad1)"/>
<xsl:variable name="y1" select="$r_aspect * -math:sin($rad1)"/>
<g id="antiscia" visibility="hidden">
<xsl:for-each select="chartinfo/antiscia/antiscia">
<xsl:variable name="planet1" select="@body1"/>
<xsl:variable name="deg1">
<xsl:choose>
<xsl:when test="$planet1='GSWE_PLANET_ASCENDANT'">
<xsl:value-of select="/chartinfo/ascmcs/ascendant/@degree_ut" />
</xsl:when>
<xsl:when test="$planet1='GSWE_PLANET_MC'">
<xsl:value-of select="/chartinfo/ascmcs/mc/@degree_ut" />
</xsl:when>
<xsl:when test="$planet1='GSWE_PLANET_VERTEX'">
<xsl:value-of select="/chartinfo/ascmcs/vertex/@degree_ut" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="/chartinfo/bodies/body[@name=$planet1]/@degree" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="rad1" select="$deg1 * $PI div 180"/>
<xsl:variable name="x1" select="$r_aspect * math:cos($rad1)"/>
<xsl:variable name="y1" select="$r_aspect * -math:sin($rad1)"/>
<xsl:variable name="planet2" select="@body2"/>
<xsl:variable name="deg2">
<xsl:choose>
<xsl:when test="$planet2='ascendant'">
<xsl:value-of select="/chartinfo/ascmcs/ascendant/@degree_ut" />
</xsl:when>
<xsl:when test="$planet2='mc'">
<xsl:value-of select="/chartinfo/ascmcs/mc/@degree_ut" />
</xsl:when>
<xsl:when test="$planet2='vertex'">
<xsl:value-of select="/chartinfo/ascmcs/vertex/@degree_ut" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="/chartinfo/bodies/body[@name=$planet2]/@degree" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="rad2" select="$deg2 * $PI div 180"/>
<xsl:variable name="x2" select="$r_aspect * math:cos($rad2)"/>
<xsl:variable name="y2" select="$r_aspect * -math:sin($rad2)"/>
<xsl:variable name="planet2" select="@body2"/>
<xsl:variable name="deg2">
<xsl:choose>
<xsl:when test="$planet2='GSWE_PLANET_ASCENDANT'">
<xsl:value-of select="/chartinfo/ascmcs/ascendant/@degree_ut" />
</xsl:when>
<xsl:when test="$planet2='GSWE_PLANET_MC'">
<xsl:value-of select="/chartinfo/ascmcs/mc/@degree_ut" />
</xsl:when>
<xsl:when test="$planet2='GSWE_PLANET_VERTEX'">
<xsl:value-of select="/chartinfo/ascmcs/vertex/@degree_ut" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="/chartinfo/bodies/body[@name=$planet2]/@degree" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="rad2" select="$deg2 * $PI div 180"/>
<xsl:variable name="x2" select="$r_aspect * math:cos($rad2)"/>
<xsl:variable name="y2" select="$r_aspect * -math:sin($rad2)"/>
<line style="stroke-width:1;stroke:#000000;stroke-dasharray:20,10">
<xsl:attribute name="x1"><xsl:value-of select="$x1"/></xsl:attribute>
<xsl:attribute name="y1"><xsl:value-of select="$y1"/></xsl:attribute>
<xsl:attribute name="x2"><xsl:value-of select="$x2"/></xsl:attribute>
<xsl:attribute name="y2"><xsl:value-of select="$y2"/></xsl:attribute>
</line>
</xsl:for-each>
</g>
<line class="antiscion">
<xsl:attribute name="id">antiscion-<xsl:value-of select="$planet1"/>-<xsl:value-of select="$planet2"/></xsl:attribute>
<xsl:attribute name="class">antiscion antiscion-<xsl:value-of select="@axis"/> antiscion-<xsl:value-of select="$planet1"/> antiscion-<xsl:value-of select="$planet2"/></xsl:attribute>
<xsl:attribute name="x1"><xsl:value-of select="$x1"/></xsl:attribute>
<xsl:attribute name="y1"><xsl:value-of select="$y1"/></xsl:attribute>
<xsl:attribute name="x2"><xsl:value-of select="$x2"/></xsl:attribute>
<xsl:attribute name="y2"><xsl:value-of select="$y2"/></xsl:attribute>
</line>
</xsl:for-each>
</g>
</g>
</g>