Merge branch 'master' into settings

This commit is contained in:
Gergely Polonkai 2014-06-30 18:16:47 +02:00
commit 1cee8bf38c
18 changed files with 482 additions and 165 deletions

4
.gitignore vendored
View File

@ -1,6 +1,7 @@
.deps/ .deps/
.libs/ .libs/
*~ *~
*.a
*.o *.o
*.lo *.lo
*.la *.la
@ -73,6 +74,9 @@ Makefile.in
/help/*/*.page /help/*/*.page
!/help/C/*.page !/help/C/*.page
/.anjuta*
/*.anjuta
#Documentation related files #Documentation related files
/docs/reference/*/*.args /docs/reference/*/*.args
/docs/reference/*/*.hierarchy /docs/reference/*/*.hierarchy

3
.gitmodules vendored
View File

@ -1,3 +0,0 @@
[submodule "libgd"]
path = libgd
url = git://git.gnome.org/libgd

View File

@ -1,5 +1,5 @@
ACLOCAL_AMFLAGS = -I m4 ACLOCAL_AMFLAGS = -I m4
SUBDIRS = libgd src po data help SUBDIRS = src po data help
EXTRA_DIST = config.rpath ChangeLog EXTRA_DIST = config.rpath ChangeLog

View File

@ -43,13 +43,9 @@ Astrognome was originally created by Jean-André Santoni, and was hosted on [Goo
## Hacking ## Hacking
The project is currently hosted on [GitHub](https://github.com/gergelypolonkai/astrognome). Just fork the repo, make your changes and issue a pull request. Don't like GitHub? That's fine with me; in this case, clone the repo, and send your changes, and send me your modifications at gergely@polonkai.eu as a git-bundle or a patch (in this latter case, you should also mention which commit is your base). The project is currently hosted on [GitHub](https://github.com/gergelypolonkai/astrognome). Just fork the repo, make your changes and issue a pull request. Dont like GitHub? Thats fine with me; in this case, clone the repo, and send your changes, and send me your modifications at gergely@polonkai.eu as a git-bundle or a patch (in this latter case, you should also mention which commit is your base).
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). The entire project is written in C, utilizing GTK+ 3.10 (or anything later in the 3.x series) and SWE-GLib 2.0 (which is used for the calculations part). Im testing my code under Fedora, so even testers from other distributions are welcome!
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. 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!!!
-------------
The code is a bit messy yet, and displays calculated data only in a textual form. Graphics will be added later.

View File

@ -5,7 +5,6 @@ srcdir=`dirname $0`
test -z "$srcdir" && srcdir=. test -z "$srcdir" && srcdir=.
PKG_NAME="astrognome" PKG_NAME="astrognome"
ACLOCAL_FLAGS="-I libgd $ACLOCAL_FLAGS"
(test -f $srcdir/configure.ac \ (test -f $srcdir/configure.ac \
&& test -f $srcdir/src/astrognome.c) || { && test -f $srcdir/src/astrognome.c) || {
@ -19,7 +18,5 @@ which gnome-autogen.sh || {
exit 1 exit 1
} }
git submodule update --init --recursive
REQUIRED_AUTOMAKE_VERSION=1.9 . gnome-autogen.sh REQUIRED_AUTOMAKE_VERSION=1.9 . gnome-autogen.sh

View File

@ -27,23 +27,16 @@ GTK_DOC_CHECK([1.19], [--flavour no-tmpl])
PKG_PROG_PKG_CONFIG PKG_PROG_PKG_CONFIG
GLIB_GSETTINGS GLIB_GSETTINGS
AC_PATH_PROG([GLIB_MKENUMS], [glib-mkenums]) AC_PATH_PROG([GLIB_MKENUMS], [glib-mkenums])
PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.30]) PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.38])
PKG_CHECK_MODULES([GOBJECT], [gobject-2.0]) PKG_CHECK_MODULES([GOBJECT], [gobject-2.0])
PKG_CHECK_MODULES([GTK], [gtk+-3.0 >= 3.8]) PKG_CHECK_MODULES([GTK], [gtk+-3.0 >= 3.8])
PKG_CHECK_MODULES([LIBXML], [libxml-2.0]) PKG_CHECK_MODULES([LIBXML], [libxml-2.0])
PKG_CHECK_MODULES([LIBXSLT], [libexslt]) PKG_CHECK_MODULES([LIBXSLT], [libexslt])
PKG_CHECK_MODULES([WEBKIT], [webkitgtk-3.0]) PKG_CHECK_MODULES([WEBKIT], [webkitgtk-3.0])
PKG_CHECK_MODULES([SWE_GLIB], [swe-glib]) PKG_CHECK_MODULES([SWE_GLIB], [swe-glib >= 2.0.0])
LIBGD_INIT([
header-bar
stack
static
])
AC_CONFIG_FILES([ AC_CONFIG_FILES([
Makefile Makefile
libgd/Makefile
src/Makefile src/Makefile
help/Makefile help/Makefile
po/Makefile.in po/Makefile.in

View File

@ -523,7 +523,7 @@
<line id="descendent" x1="-320" y1="0" x2="-50" y2="0" transform="rotate(-103.432962,0,0)" class="axis"> <line id="descendent" x1="-320" y1="0" x2="-50" y2="0" transform="rotate(-103.432962,0,0)" class="axis">
<xsl:attribute name="transform"><xsl:value-of select="concat('rotate(-', $asc, ')')" /></xsl:attribute> <xsl:attribute name="transform"><xsl:value-of select="concat('rotate(-', $asc, ')')" /></xsl:attribute>
</line> </line>
<line id="ascendent" x1="50" y1="0" x2="320" y2="0" class="axis axis-end"> <line id="ascendant" x1="50" y1="0" x2="320" y2="0" class="axis axis-end">
<xsl:attribute name="transform"><xsl:value-of select="concat('rotate(-', $asc, ')')" /></xsl:attribute> <xsl:attribute name="transform"><xsl:value-of select="concat('rotate(-', $asc, ')')" /></xsl:attribute>
</line> </line>
<xsl:variable name="mc" select="chartinfo/ascmcs/mc/@degree_ut"/> <xsl:variable name="mc" select="chartinfo/ascmcs/mc/@degree_ut"/>
@ -597,7 +597,7 @@
<xsl:variable name="planet1" select="@body1"/> <xsl:variable name="planet1" select="@body1"/>
<xsl:variable name="deg1"> <xsl:variable name="deg1">
<xsl:choose> <xsl:choose>
<xsl:when test="$planet1='GSWE_PLANET_ASCENDENT'"> <xsl:when test="$planet1='GSWE_PLANET_ASCENDANT'">
<xsl:value-of select="/chartinfo/ascmcs/ascendant/@degree_ut" /> <xsl:value-of select="/chartinfo/ascmcs/ascendant/@degree_ut" />
</xsl:when> </xsl:when>
<xsl:when test="$planet1='GSWE_PLANET_MC'"> <xsl:when test="$planet1='GSWE_PLANET_MC'">
@ -618,7 +618,7 @@
<xsl:variable name="planet2" select="@body2"/> <xsl:variable name="planet2" select="@body2"/>
<xsl:variable name="deg2"> <xsl:variable name="deg2">
<xsl:choose> <xsl:choose>
<xsl:when test="$planet2='GSWE_PLANET_ASCENDENT'"> <xsl:when test="$planet2='GSWE_PLANET_ASCENDANT'">
<xsl:value-of select="/chartinfo/ascmcs/ascendant/@degree_ut" /> <xsl:value-of select="/chartinfo/ascmcs/ascendant/@degree_ut" />
</xsl:when> </xsl:when>
<xsl:when test="$planet2='GSWE_PLANET_MC'"> <xsl:when test="$planet2='GSWE_PLANET_MC'">
@ -650,7 +650,7 @@
<xsl:variable name="planet1" select="@body1"/> <xsl:variable name="planet1" select="@body1"/>
<xsl:variable name="deg1"> <xsl:variable name="deg1">
<xsl:choose> <xsl:choose>
<xsl:when test="$planet1='GSWE_PLANET_ASCENDENT'"> <xsl:when test="$planet1='GSWE_PLANET_ASCENDANT'">
<xsl:value-of select="/chartinfo/ascmcs/ascendant/@degree_ut" /> <xsl:value-of select="/chartinfo/ascmcs/ascendant/@degree_ut" />
</xsl:when> </xsl:when>
<xsl:when test="$planet1='GSWE_PLANET_MC'"> <xsl:when test="$planet1='GSWE_PLANET_MC'">
@ -671,7 +671,7 @@
<xsl:variable name="planet2" select="@body2"/> <xsl:variable name="planet2" select="@body2"/>
<xsl:variable name="deg2"> <xsl:variable name="deg2">
<xsl:choose> <xsl:choose>
<xsl:when test="$planet2='GSWE_PLANET_ASCENDENT'"> <xsl:when test="$planet2='GSWE_PLANET_ASCENDANT'">
<xsl:value-of select="/chartinfo/ascmcs/ascendant/@degree_ut" /> <xsl:value-of select="/chartinfo/ascmcs/ascendant/@degree_ut" />
</xsl:when> </xsl:when>
<xsl:when test="$planet2='GSWE_PLANET_MC'"> <xsl:when test="$planet2='GSWE_PLANET_MC'">

1
libgd

@ -1 +0,0 @@
Subproject commit 62f9b8b92599b38d986bd26d5780edd400d318c9

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: astrognome master\n" "Project-Id-Version: astrognome master\n"
"Report-Msgid-Bugs-To: gergely@polonkai.eu\n" "Report-Msgid-Bugs-To: gergely@polonkai.eu\n"
"POT-Creation-Date: 2013-09-21 22:17+0200\n" "POT-Creation-Date: 2014-03-30 17:25+0200\n"
"PO-Revision-Date: 2013-09-21 20:17+0200\n" "PO-Revision-Date: 2013-09-21 20:17+0200\n"
"Last-Translator: Gergely Polonkai <gergely@polonkai.eu>\n" "Last-Translator: Gergely Polonkai <gergely@polonkai.eu>\n"
"Language-Team: Hungarian <gergely@polonkai.eu>\n" "Language-Team: Hungarian <gergely@polonkai.eu>\n"
@ -18,7 +18,7 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. i18n: Please don't translate "Astrognome" (it's marked as translatable for transliteration only #. i18n: Please don't translate "Astrognome" (it's marked as translatable for transliteration only
#: ../data/astrognome.desktop.in.in.h:1 ../src/ag-app.c:85 ../src/ag-app.c:273 #: ../data/astrognome.desktop.in.in.h:1 ../src/ag-app.c:85 ../src/ag-app.c:312
msgid "Astrognome" msgid "Astrognome"
msgstr "Astrognome" msgstr "Astrognome"
@ -46,87 +46,111 @@ msgstr "Asztrológiai szoftver a GNOME-hoz"
msgid "Astrognome Website" msgid "Astrognome Website"
msgstr "Astrognome weboldal" msgstr "Astrognome weboldal"
#: ../src/ag-app.c:131 #: ../src/ag-app.c:136
msgid "Select charts" msgid "Select charts"
msgstr "Válasszon ki mentett képleteket" msgstr "Válasszon ki mentett képleteket"
#: ../src/ag-window.c:103 #: ../src/ag-app.c:139 ../src/ag-window.c:118
msgid "_Cancel"
msgstr "_Mégsem"
#: ../src/ag-app.c:140
msgid "_Open"
msgstr "M_egnyitás"
#: ../src/ag-window.c:89
msgid "Chart cannot be calculated."
msgstr ""
#: ../src/ag-window.c:104
msgid "You must enter a name before saving a chart."
msgstr ""
#: ../src/ag-window.c:115
msgid "Save Chart" msgid "Save Chart"
msgstr "Képlet mentése" msgstr "Képlet mentése"
#: ../src/ag-window.c:363 #: ../src/ag-window.c:119
msgid "_Save"
msgstr "M_entés"
#: ../src/ag-window.c:386
msgid "Name" msgid "Name"
msgstr "Név" msgstr "Név"
#: ../src/ag-window.c:369 #: ../src/ag-window.c:392
msgid "Country" msgid "Country"
msgstr "Ország" msgstr "Ország"
#: ../src/ag-window.c:372 #: ../src/ag-window.c:395
msgid "City" msgid "City"
msgstr "Város" msgstr "Város"
#: ../src/ag-window.c:375 #: ../src/ag-window.c:398
msgid "Latitude" msgid "Latitude"
msgstr "Szélességi fok" msgstr "Szélességi fok"
#: ../src/ag-window.c:378 #: ../src/ag-window.c:401
msgid "North" msgid "North"
msgstr "Észak" msgstr "Észak"
#: ../src/ag-window.c:381 #: ../src/ag-window.c:404
msgid "South" msgid "South"
msgstr "Dél" msgstr "Dél"
#: ../src/ag-window.c:388 #: ../src/ag-window.c:411
msgid "Longitude" msgid "Longitude"
msgstr "Hosszúsági fok" msgstr "Hosszúsági fok"
#: ../src/ag-window.c:391 #: ../src/ag-window.c:414
msgid "East" msgid "East"
msgstr "Kelet" msgstr "Kelet"
#: ../src/ag-window.c:394 #: ../src/ag-window.c:417
msgid "West" msgid "West"
msgstr "Nyugat" msgstr "Nyugat"
#: ../src/ag-window.c:401 #: ../src/ag-window.c:424
msgid "Year" msgid "Year"
msgstr "Év" msgstr "Év"
#: ../src/ag-window.c:409 #: ../src/ag-window.c:432
msgid "Month" msgid "Month"
msgstr "Hónap" msgstr "Hónap"
#: ../src/ag-window.c:416 #: ../src/ag-window.c:439
msgid "Day" msgid "Day"
msgstr "Nap" msgstr "Nap"
#: ../src/ag-window.c:423 #: ../src/ag-window.c:446
msgid "Hour" msgid "Hour"
msgstr "Óra" msgstr "Óra"
#: ../src/ag-window.c:430 #: ../src/ag-window.c:453
msgid "Minute" msgid "Minute"
msgstr "Perc" msgstr "Perc"
#: ../src/ag-window.c:437 #: ../src/ag-window.c:460
msgid "Second" msgid "Second"
msgstr "Másodperc" msgstr "Másodperc"
#: ../src/ag-window.c:480 #: ../src/ag-window.c:467
msgid "Timezone"
msgstr ""
#: ../src/ag-window.c:516
msgid "Edit" msgid "Edit"
msgstr "Szerkesztés" msgstr "Szerkesztés"
#: ../src/ag-window.c:484 #: ../src/ag-window.c:520
msgid "Chart" msgid "Chart"
msgstr "Képlet" msgstr "Képlet"
#: ../src/ag-window.c:492 #: ../src/ag-window.c:529
msgid "Aspects" msgid "Aspects"
msgstr "Fényszögek" msgstr "Fényszögek"
#: ../src/ag-window.c:495 #: ../src/ag-window.c:532
msgid "Points" msgid "Points"
msgstr "Pont-táblázatok" msgstr "Pont-táblázatok"

View File

@ -29,9 +29,9 @@ AM_CPPFLAGS = -DG_LOG_DOMAIN=\"Astrognome\" -DLOCALEDIR=\"$(localedir)\" -DPKGDA
bin_PROGRAMS = astrognome bin_PROGRAMS = astrognome
astrognome_SOURCES = $(astrognome_source_files) $(BUILT_SOURCES) astrognome_SOURCES = $(astrognome_source_files) $(BUILT_SOURCES)
astrognome_LDADD = $(SWE_GLIB_LIBS) $(GTK_LIBS) $(LIBXML_LIBS) $(LIBXSLT_LIBS) $(WEBKIT_LIBS) $(top_builddir)/libgd/libgd.la astrognome_LDADD = $(SWE_GLIB_LIBS) $(GTK_LIBS) $(LIBXML_LIBS) $(LIBXSLT_LIBS) $(WEBKIT_LIBS)
astrognome_LDFLAGS = -rdynamic astrognome_LDFLAGS = -rdynamic
astrognome_CFLAGS = $(SWE_GLIB_CFLAGS) $(CFLAGS) $(GTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBXSLT_CFLAGS) $(WEBKIT_CFLAGS) -Wall -I$(top_srcdir)/libgd astrognome_CFLAGS = $(SWE_GLIB_CFLAGS) $(CFLAGS) $(GTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBXSLT_CFLAGS) $(WEBKIT_CFLAGS) -Wall
guidir = $(pkgdatadir) guidir = $(pkgdatadir)
gui_DATA = astrognome.ui gui_DATA = astrognome.ui

View File

@ -6,9 +6,6 @@
#include "config.h" #include "config.h"
#include "astrognome.h" #include "astrognome.h"
struct _AgAppPrivate {
};
G_DEFINE_TYPE(AgApp, ag_app, GTK_TYPE_APPLICATION); G_DEFINE_TYPE(AgApp, ag_app, GTK_TYPE_APPLICATION);
GtkWindow * GtkWindow *
@ -113,7 +110,12 @@ ag_app_open_chart(AgApp *app, GFile *file)
GError *err = NULL; GError *err = NULL;
gchar *uri; gchar *uri;
chart = ag_chart_load_from_file(file, &err); if ((chart = ag_chart_load_from_file(file, &err)) == NULL) {
g_print("Error: '%s'\n", err->message);
return;
}
window = ag_app_create_window(app); window = ag_app_create_window(app);
ag_window_set_chart(AG_WINDOW(window), chart); ag_window_set_chart(AG_WINDOW(window), chart);
ag_window_update_from_chart(AG_WINDOW(window)); ag_window_update_from_chart(AG_WINDOW(window));
@ -132,8 +134,8 @@ open_cb(GSimpleAction *action, GVariant *parameter, gpointer user_data)
fs = gtk_file_chooser_dialog_new(_("Select charts"), fs = gtk_file_chooser_dialog_new(_("Select charts"),
NULL, NULL,
GTK_FILE_CHOOSER_ACTION_OPEN, GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, _("_Cancel"), GTK_RESPONSE_CANCEL,
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, _("_Open"), GTK_RESPONSE_ACCEPT,
NULL); NULL);
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fs), filter_all); 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_add_filter(GTK_FILE_CHOOSER(fs), filter_chart);
@ -197,7 +199,11 @@ show_help(const gchar *topic, GtkWindow *parent)
} }
if (!gtk_show_uri(screen, uri, gtk_get_current_event_time(), &err)) { if (!gtk_show_uri(screen, uri, gtk_get_current_event_time(), &err)) {
g_warning("Unable to display help: %s", err->message); GtkWidget *dialog;
dialog = gtk_message_dialog_new(parent, GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, "Unable to display help: %s", err->message);
gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
} }
g_free(uri); g_free(uri);

View File

@ -16,11 +16,9 @@ G_BEGIN_DECLS
typedef struct _AgApp AgApp; typedef struct _AgApp AgApp;
typedef struct _AgAppClass AgAppClass; typedef struct _AgAppClass AgAppClass;
typedef struct _AgAppPrivate AgAppPrivate;
struct _AgApp { struct _AgApp {
GtkApplication parent_instance; GtkApplication parent_instance;
AgAppPrivate *priv;
}; };
struct _AgAppClass { struct _AgAppClass {

View File

@ -16,6 +16,7 @@ struct _AgChartPrivate {
gchar *country; gchar *country;
gchar *city; gchar *city;
gchar *save_buffer; gchar *save_buffer;
GList *planet_list;
}; };
enum { enum {
@ -33,9 +34,8 @@ typedef enum {
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); G_DEFINE_TYPE_WITH_PRIVATE(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) \ #define ag_g_variant_unref(v) \
if ((v) != NULL) { \ if ((v) != NULL) { \
g_variant_unref((v)); \ g_variant_unref((v)); \
@ -56,8 +56,6 @@ ag_chart_class_init(AgChartClass *klass)
{ {
GObjectClass *gobject_class = G_OBJECT_CLASS(klass); GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
g_type_class_add_private(klass, sizeof(AgChartPrivate));
gobject_class->set_property = ag_chart_set_property; gobject_class->set_property = ag_chart_set_property;
gobject_class->get_property = ag_chart_get_property; gobject_class->get_property = ag_chart_get_property;
gobject_class->finalize = ag_chart_finalize; gobject_class->finalize = ag_chart_finalize;
@ -70,11 +68,12 @@ ag_chart_class_init(AgChartClass *klass)
static void static void
ag_chart_init(AgChart *chart) ag_chart_init(AgChart *chart)
{ {
chart->priv = GET_PRIVATE(chart); chart->priv = ag_chart_get_instance_private(chart);
chart->priv->name = NULL; chart->priv->name = NULL;
chart->priv->country = NULL; chart->priv->country = NULL;
chart->priv->city = NULL; chart->priv->city = NULL;
chart->priv->save_buffer = NULL; chart->priv->save_buffer = NULL;
chart->priv->planet_list = NULL;
} }
static void static void
@ -142,6 +141,79 @@ ag_chart_finalize(GObject *gobject)
} }
} }
void
ag_chart_add_planets(AgChart *chart)
{
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_CHARIKLO, NULL);
chart->priv->planet_list = g_list_prepend(chart->priv->planet_list, GINT_TO_POINTER(GSWE_PLANET_CHARIKLO));
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_VESTA, NULL);
chart->priv->planet_list = g_list_prepend(chart->priv->planet_list, GINT_TO_POINTER(GSWE_PLANET_VESTA));
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_JUNO, NULL);
chart->priv->planet_list = g_list_prepend(chart->priv->planet_list, GINT_TO_POINTER(GSWE_PLANET_JUNO));
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_PALLAS, NULL);
chart->priv->planet_list = g_list_prepend(chart->priv->planet_list, GINT_TO_POINTER(GSWE_PLANET_PALLAS));
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_CERES, NULL);
chart->priv->planet_list = g_list_prepend(chart->priv->planet_list, GINT_TO_POINTER(GSWE_PLANET_CERES));
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_NESSUS, NULL);
chart->priv->planet_list = g_list_prepend(chart->priv->planet_list, GINT_TO_POINTER(GSWE_PLANET_NESSUS));
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_PHOLUS, NULL);
chart->priv->planet_list = g_list_prepend(chart->priv->planet_list, GINT_TO_POINTER(GSWE_PLANET_PHOLUS));
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_CHIRON, NULL);
chart->priv->planet_list = g_list_prepend(chart->priv->planet_list, GINT_TO_POINTER(GSWE_PLANET_CHIRON));
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_MOON_APOGEE, NULL);
chart->priv->planet_list = g_list_prepend(chart->priv->planet_list, GINT_TO_POINTER(GSWE_PLANET_MOON_APOGEE));
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_MOON_NODE, NULL);
chart->priv->planet_list = g_list_prepend(chart->priv->planet_list, GINT_TO_POINTER(GSWE_PLANET_MOON_NODE));
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_PLUTO, NULL);
chart->priv->planet_list = g_list_prepend(chart->priv->planet_list, GINT_TO_POINTER(GSWE_PLANET_PLUTO));
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_NEPTUNE, NULL);
chart->priv->planet_list = g_list_prepend(chart->priv->planet_list, GINT_TO_POINTER(GSWE_PLANET_NEPTUNE));
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_URANUS, NULL);
chart->priv->planet_list = g_list_prepend(chart->priv->planet_list, GINT_TO_POINTER(GSWE_PLANET_URANUS));
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_SATURN, NULL);
chart->priv->planet_list = g_list_prepend(chart->priv->planet_list, GINT_TO_POINTER(GSWE_PLANET_SATURN));
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_JUPITER, NULL);
chart->priv->planet_list = g_list_prepend(chart->priv->planet_list, GINT_TO_POINTER(GSWE_PLANET_JUPITER));
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_MARS, NULL);
chart->priv->planet_list = g_list_prepend(chart->priv->planet_list, GINT_TO_POINTER(GSWE_PLANET_MARS));
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_VENUS, NULL);
chart->priv->planet_list = g_list_prepend(chart->priv->planet_list, GINT_TO_POINTER(GSWE_PLANET_VENUS));
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_MERCURY, NULL);
chart->priv->planet_list = g_list_prepend(chart->priv->planet_list, GINT_TO_POINTER(GSWE_PLANET_MERCURY));
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_MOON, NULL);
chart->priv->planet_list = g_list_prepend(chart->priv->planet_list, GINT_TO_POINTER(GSWE_PLANET_MOON));
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_SUN, NULL);
chart->priv->planet_list = g_list_prepend(chart->priv->planet_list, GINT_TO_POINTER(GSWE_PLANET_SUN));
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_VERTEX, NULL);
chart->priv->planet_list = g_list_prepend(chart->priv->planet_list, GINT_TO_POINTER(GSWE_PLANET_VERTEX));
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_ASCENDANT, NULL);
chart->priv->planet_list = g_list_prepend(chart->priv->planet_list, GINT_TO_POINTER(GSWE_PLANET_ASCENDANT));
gswe_moment_add_planet(GSWE_MOMENT(chart), GSWE_PLANET_MC, NULL);
chart->priv->planet_list = g_list_prepend(chart->priv->planet_list, GINT_TO_POINTER(GSWE_PLANET_MC));
}
AgChart * AgChart *
ag_chart_new_full(GsweTimestamp *timestamp, gdouble longitude, gdouble latitude, gdouble altitude, GsweHouseSystem house_system) ag_chart_new_full(GsweTimestamp *timestamp, gdouble longitude, gdouble latitude, gdouble altitude, GsweHouseSystem house_system)
{ {
@ -160,7 +232,7 @@ ag_chart_new_full(GsweTimestamp *timestamp, gdouble longitude, gdouble latitude,
g_free(coords); g_free(coords);
gswe_moment_add_all_planets(GSWE_MOMENT(chart)); ag_chart_add_planets(chart);
return chart; return chart;
} }
@ -293,7 +365,7 @@ get_by_xpath(xmlXPathContextPtr xpath_context, const gchar *uri, const gchar *xp
switch (type) { switch (type) {
case XML_CONVERT_STRING: case XML_CONVERT_STRING:
ret = g_variant_new_string(text); ret = g_variant_new("ms", text);
break; break;
@ -334,9 +406,10 @@ ag_chart_load_from_file(GFile *file, GError **err)
AgChart *chart = NULL; AgChart *chart = NULL;
gchar *uri; gchar *uri;
gchar *xml = NULL; gchar *xml = NULL;
gchar *name;
gchar *country_name; gchar *country_name;
gchar *city_name; gchar *city_name;
guint length; gsize length;
xmlDocPtr doc; xmlDocPtr doc;
xmlXPathContextPtr xpath_context; xmlXPathContextPtr xpath_context;
GVariant *chart_name; GVariant *chart_name;
@ -477,8 +550,10 @@ ag_chart_load_from_file(GFile *file, GError **err)
g_variant_unref(latitude); g_variant_unref(latitude);
g_variant_unref(altitude); g_variant_unref(altitude);
ag_chart_set_name(chart, g_variant_get_string(chart_name, NULL)); g_variant_get(chart_name, "ms", &name);
g_variant_unref(chart_name); g_variant_unref(chart_name);
ag_chart_set_name(chart, name);
g_free(name);
g_variant_get(country, "ms", &country_name); g_variant_get(country, "ms", &country_name);
g_variant_unref(country); g_variant_unref(country);
@ -609,7 +684,7 @@ ag_chart_save_to_file(AgChart *chart, GFile *file, GError **err)
} }
gchar * gchar *
ag_chart_create_svg(AgChart *chart, GError **err) ag_chart_create_svg(AgChart *chart, gsize *length, GError **err)
{ {
xmlDocPtr doc = create_save_doc(chart); xmlDocPtr doc = create_save_doc(chart);
xmlDocPtr xslt_doc; xmlDocPtr xslt_doc;
@ -633,8 +708,8 @@ ag_chart_create_svg(AgChart *chart, GError **err)
GList *planet; GList *planet;
GList *aspect; GList *aspect;
GList *antiscion; GList *antiscion;
const GswePlanetData *planet_data; GswePlanetData *planet_data;
const GsweAspectData *aspect_data; GsweAspectData *aspect_data;
GEnumClass *planets_class; GEnumClass *planets_class;
GEnumClass *aspects_class; GEnumClass *aspects_class;
GEnumClass *antiscia_class; GEnumClass *antiscia_class;
@ -654,9 +729,9 @@ ag_chart_create_svg(AgChart *chart, GError **err)
node = xmlNewChild(ascmcs_node, NULL, BAD_CAST "ascendant", NULL); node = xmlNewChild(ascmcs_node, NULL, BAD_CAST "ascendant", NULL);
planet_data = gswe_moment_get_planet(GSWE_MOMENT(chart), GSWE_PLANET_ASCENDENT, NULL); planet_data = gswe_moment_get_planet(GSWE_MOMENT(chart), GSWE_PLANET_ASCENDANT, NULL);
value = g_malloc0(12); value = g_malloc0(12);
g_ascii_dtostr(value, 12, planet_data->position); g_ascii_dtostr(value, 12, gswe_planet_data_get_position(planet_data));
xmlNewProp(node, BAD_CAST "degree_ut", BAD_CAST value); xmlNewProp(node, BAD_CAST "degree_ut", BAD_CAST value);
g_free(value); g_free(value);
@ -664,7 +739,7 @@ ag_chart_create_svg(AgChart *chart, GError **err)
planet_data = gswe_moment_get_planet(GSWE_MOMENT(chart), GSWE_PLANET_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); g_ascii_dtostr(value, 12, gswe_planet_data_get_position(planet_data));
xmlNewProp(node, BAD_CAST "degree_ut", BAD_CAST value); xmlNewProp(node, BAD_CAST "degree_ut", BAD_CAST value);
g_free(value); g_free(value);
@ -672,7 +747,7 @@ ag_chart_create_svg(AgChart *chart, GError **err)
planet_data = gswe_moment_get_planet(GSWE_MOMENT(chart), GSWE_PLANET_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); g_ascii_dtostr(value, 12, gswe_planet_data_get_position(planet_data));
xmlNewProp(node, BAD_CAST "degree_ut", BAD_CAST value); xmlNewProp(node, BAD_CAST "degree_ut", BAD_CAST value);
g_free(value); g_free(value);
@ -686,12 +761,12 @@ ag_chart_create_svg(AgChart *chart, GError **err)
node = xmlNewChild(houses_node, NULL, BAD_CAST "house", NULL); node = xmlNewChild(houses_node, NULL, BAD_CAST "house", NULL);
value = g_malloc0(3); value = g_malloc0(3);
g_ascii_dtostr(value, 3, house_data->house); g_ascii_dtostr(value, 3, gswe_house_data_get_house(house_data));
xmlNewProp(node, BAD_CAST "number", BAD_CAST value); xmlNewProp(node, BAD_CAST "number", BAD_CAST value);
g_free(value); g_free(value);
value = g_malloc0(12); value = g_malloc0(12);
g_ascii_dtostr(value, 12, house_data->cusp_position); g_ascii_dtostr(value, 12, gswe_house_data_get_cusp_position(house_data));
xmlNewProp(node, BAD_CAST "degree", BAD_CAST value); xmlNewProp(node, BAD_CAST "degree", BAD_CAST value);
g_free(value); g_free(value);
} }
@ -707,20 +782,20 @@ ag_chart_create_svg(AgChart *chart, GError **err)
GEnumValue *enum_value; GEnumValue *enum_value;
if ( if (
(planet_data->planet_id == GSWE_PLANET_ASCENDENT) || (gswe_planet_data_get_planet(planet_data) == GSWE_PLANET_ASCENDANT) ||
(planet_data->planet_id == GSWE_PLANET_MC) || (gswe_planet_data_get_planet(planet_data) == GSWE_PLANET_MC) ||
(planet_data->planet_id == GSWE_PLANET_VERTEX) (gswe_planet_data_get_planet(planet_data) == GSWE_PLANET_VERTEX)
) { ) {
continue; continue;
} }
node = xmlNewChild(bodies_node, NULL, BAD_CAST "body", NULL); node = xmlNewChild(bodies_node, NULL, BAD_CAST "body", NULL);
enum_value = g_enum_get_value(G_ENUM_CLASS(planets_class), planet_data->planet_id); enum_value = g_enum_get_value(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_name);
value = g_malloc0(12); value = g_malloc0(12);
g_ascii_dtostr(value, 12, planet_data->position); g_ascii_dtostr(value, 12, gswe_planet_data_get_position(planet_data));
xmlNewProp(node, BAD_CAST "degree", BAD_CAST value); xmlNewProp(node, BAD_CAST "degree", BAD_CAST value);
g_free(value); g_free(value);
} }
@ -732,22 +807,26 @@ ag_chart_create_svg(AgChart *chart, GError **err)
aspects_class = g_type_class_ref(GSWE_TYPE_ASPECT); aspects_class = g_type_class_ref(GSWE_TYPE_ASPECT);
for (aspect = gswe_moment_get_all_aspects(GSWE_MOMENT(chart)); aspect; aspect = g_list_next(aspect)) { for (aspect = gswe_moment_get_all_aspects(GSWE_MOMENT(chart)); aspect; aspect = g_list_next(aspect)) {
GswePlanetData *planet_data;
GEnumValue *enum_value; GEnumValue *enum_value;
aspect_data = aspect->data; aspect_data = aspect->data;
if (aspect_data->aspect == GSWE_ASPECT_NONE) { if (gswe_aspect_data_get_aspect(aspect_data) == GSWE_ASPECT_NONE) {
continue; continue;
} }
node = xmlNewChild(aspects_node, NULL, BAD_CAST "aspect", NULL); node = xmlNewChild(aspects_node, NULL, BAD_CAST "aspect", NULL);
enum_value = g_enum_get_value(G_ENUM_CLASS(planets_class), aspect_data->planet1->planet_id); planet_data = gswe_aspect_data_get_planet1(aspect_data);
enum_value = g_enum_get_value(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_name);
enum_value = g_enum_get_value(G_ENUM_CLASS(planets_class), aspect_data->planet2->planet_id); 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_name);
enum_value = g_enum_get_value(G_ENUM_CLASS(aspects_class), aspect_data->aspect); enum_value = g_enum_get_value(G_ENUM_CLASS(aspects_class), gswe_aspect_data_get_aspect(aspect_data));
xmlNewProp(node, BAD_CAST "type", BAD_CAST enum_value->value_name); xmlNewProp(node, BAD_CAST "type", BAD_CAST enum_value->value_name);
} }
@ -759,22 +838,25 @@ ag_chart_create_svg(AgChart *chart, GError **err)
antiscia_class = g_type_class_ref(GSWE_TYPE_ANTISCION_AXIS); 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)) { for (antiscion = gswe_moment_get_all_antiscia(GSWE_MOMENT(chart)); antiscion; antiscion = g_list_next(antiscion)) {
GswePlanetData *planet_data;
GsweAntiscionData *antiscion_data = antiscion->data; GsweAntiscionData *antiscion_data = antiscion->data;
GEnumValue *enum_value; GEnumValue *enum_value;
if (antiscion_data->axis == GSWE_ANTISCION_AXIS_NONE) { if (gswe_antiscion_data_get_axis(antiscion_data) == GSWE_ANTISCION_AXIS_NONE) {
continue; continue;
} }
node = xmlNewChild(antiscia_node, NULL, BAD_CAST "antiscia", NULL); node = xmlNewChild(antiscia_node, NULL, BAD_CAST "antiscia", NULL);
enum_value = g_enum_get_value(G_ENUM_CLASS(planets_class), antiscion_data->planet1->planet_id); planet_data = gswe_antiscion_data_get_planet1(antiscion_data);
enum_value = g_enum_get_value(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_name);
enum_value = g_enum_get_value(G_ENUM_CLASS(planets_class), antiscion_data->planet2->planet_id); 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_name);
enum_value = g_enum_get_value(G_ENUM_CLASS(antiscia_class), antiscion_data->axis); 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_name);
} }
@ -842,6 +924,28 @@ ag_chart_create_svg(AgChart *chart, GError **err)
xmlDocDumpFormatMemoryEnc(svg_doc, (xmlChar **)&save_content, &save_length, "UTF-8", 1); xmlDocDumpFormatMemoryEnc(svg_doc, (xmlChar **)&save_content, &save_length, "UTF-8", 1);
xmlFreeDoc(svg_doc); xmlFreeDoc(svg_doc);
if (length != NULL) {
*length = save_length;
}
return save_content; return save_content;
} }
GList *
ag_chart_get_planets(AgChart *chart)
{
return chart->priv->planet_list;
}
void
ag_chart_export_svg_to_file(AgChart *chart, GFile *file, GError **err)
{
gchar *svg;
gsize length;
if ((svg = ag_chart_create_svg(chart, &length, err)) == NULL) {
return;
}
g_file_replace_contents(file, (const gchar *)svg, length, NULL, FALSE, G_FILE_CREATE_NONE, NULL, NULL, err);
}

View File

@ -43,6 +43,10 @@ void ag_chart_save_to_file(AgChart *chart,
GFile *file, GFile *file,
GError **err); GError **err);
void ag_chart_export_svg_to_file(AgChart *chart,
GFile *file,
GError **err);
void ag_chart_set_name(AgChart *chart, void ag_chart_set_name(AgChart *chart,
const gchar *name); const gchar *name);
gchar *ag_chart_get_name(AgChart *chart); gchar *ag_chart_get_name(AgChart *chart);
@ -53,7 +57,9 @@ void ag_chart_set_city(AgChart *chart,
const gchar *city); const gchar *city);
gchar *ag_chart_get_city(AgChart *chart); gchar *ag_chart_get_city(AgChart *chart);
gchar *ag_chart_create_svg(AgChart *chart, gchar *ag_chart_create_svg(AgChart *chart,
gsize *length,
GError **err); GError **err);
GList *ag_chart_get_planets(AgChart *chart);
#define AG_CHART_ERROR (ag_chart_error_quark()) #define AG_CHART_ERROR (ag_chart_error_quark())
GQuark ag_chart_error_quark(void); GQuark ag_chart_error_quark(void);

View File

@ -1,9 +1,5 @@
#include "ag-settings.h" #include "ag-settings.h"
G_DEFINE_TYPE(AgSettings, ag_settings, G_TYPE_OBJECT);
#define AG_SETTINGS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), AG_TYPE_SETTINGS, AgSettingsPrivate))
#define SETTINGS_SCHEMA_ID_WINDOW "eu.polonkai.gergely.Astrognome.state.window" #define SETTINGS_SCHEMA_ID_WINDOW "eu.polonkai.gergely.Astrognome.state.window"
#define SETTINGS_SCHEMA_ID_CHART "eu.polonkai.gergely.Astrognome.state.chart" #define SETTINGS_SCHEMA_ID_CHART "eu.polonkai.gergely.Astrognome.state.chart"
@ -14,10 +10,12 @@ struct _AgSettingsPrivate {
GSettings *settings_chart; GSettings *settings_chart;
}; };
G_DEFINE_TYPE_WITH_PRIVATE(AgSettings, ag_settings, G_TYPE_OBJECT);
static void static void
ag_settings_init(AgSettings *settings) ag_settings_init(AgSettings *settings)
{ {
settings->priv = AG_SETTINGS_GET_PRIVATE(settings); settings->priv = ag_settings_get_instance_private(settings);
settings->priv->settings_window = g_settings_new(SETTINGS_SCHEMA_ID_WINDOW); settings->priv->settings_window = g_settings_new(SETTINGS_SCHEMA_ID_WINDOW);
settings->priv->settings_chart = g_settings_new(SETTINGS_SCHEMA_ID_CHART); settings->priv->settings_chart = g_settings_new(SETTINGS_SCHEMA_ID_CHART);
} }
@ -45,7 +43,6 @@ ag_settings_class_init(AgSettingsClass *klass)
{ {
GObjectClass *gobject_class = G_OBJECT_CLASS(klass); GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
g_type_class_add_private(gobject_class, sizeof(AgSettingsPrivate));
gobject_class->dispose = ag_settings_dispose; gobject_class->dispose = ag_settings_dispose;
gobject_class->finalize = ag_settings_finalize; gobject_class->finalize = ag_settings_finalize;
} }

View File

@ -1,6 +1,6 @@
#include <math.h>
#include <string.h> #include <string.h>
#include <glib/gi18n.h> #include <glib/gi18n.h>
#include <libgd/gd.h>
#include <libxml/parser.h> #include <libxml/parser.h>
#include <libxml/tree.h> #include <libxml/tree.h>
#include <webkit/webkit.h> #include <webkit/webkit.h>
@ -30,6 +30,7 @@ struct _AgWindowPrivate {
GtkWidget *hour; GtkWidget *hour;
GtkWidget *minute; GtkWidget *minute;
GtkWidget *second; GtkWidget *second;
GtkWidget *timezone;
GtkBuilder *builder; GtkBuilder *builder;
GtkWidget *tab_chart; GtkWidget *tab_chart;
@ -41,13 +42,12 @@ struct _AgWindowPrivate {
AgSettings *settings; AgSettings *settings;
AgChart *chart; AgChart *chart;
gchar *uri; gchar *uri;
gboolean aspect_table_populated;
}; };
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); G_DEFINE_TYPE_WITH_PRIVATE(AgWindow, ag_window, GTK_TYPE_APPLICATION_WINDOW);
#define GET_PRIVATE(instance) (G_TYPE_INSTANCE_GET_PRIVATE((instance), AG_TYPE_WINDOW, AgWindowPrivate))
static void recalculate_chart(AgWindow *window); static void recalculate_chart(AgWindow *window);
@ -83,6 +83,11 @@ ag_window_save_as(AgWindow *window, GError **err)
// We should never enter here, but who knows... // We should never enter here, but who knows...
if (window->priv->chart == NULL) { if (window->priv->chart == NULL) {
GtkWidget *dialog;
dialog = gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Chart cannot be calculated."));
gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
g_set_error(err, AG_WINDOW_ERROR, AG_WINDOW_ERROR_EMPTY_CHART, "Chart is empty"); g_set_error(err, AG_WINDOW_ERROR, AG_WINDOW_ERROR_EMPTY_CHART, "Chart is empty");
return; return;
@ -91,7 +96,13 @@ ag_window_save_as(AgWindow *window, GError **err)
name = ag_chart_get_name(window->priv->chart); name = ag_chart_get_name(window->priv->chart);
if ((name == NULL) || (*name == 0)) { if ((name == NULL) || (*name == 0)) {
GtkWidget *dialog;
g_free(name); g_free(name);
dialog = gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("You must enter a name before saving a chart."));
gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
g_set_error(err, AG_WINDOW_ERROR, AG_WINDOW_ERROR_NO_NAME, "No name specified"); g_set_error(err, AG_WINDOW_ERROR, AG_WINDOW_ERROR_NO_NAME, "No name specified");
return; return;
@ -103,8 +114,8 @@ ag_window_save_as(AgWindow *window, GError **err)
fs = gtk_file_chooser_dialog_new(_("Save Chart"), fs = gtk_file_chooser_dialog_new(_("Save Chart"),
GTK_WINDOW(window), GTK_WINDOW(window),
GTK_FILE_CHOOSER_ACTION_SAVE, GTK_FILE_CHOOSER_ACTION_SAVE,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, _("_Cancel"), GTK_RESPONSE_CANCEL,
GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, _("_Save"), GTK_RESPONSE_ACCEPT,
NULL); NULL);
gtk_dialog_set_default_response(GTK_DIALOG(fs), GTK_RESPONSE_ACCEPT); 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_local_only(GTK_FILE_CHOOSER(fs), FALSE);
@ -158,20 +169,171 @@ ag_window_save_as_action(GSimpleAction *action, GVariant *parameter, gpointer us
// TODO: Check err! // TODO: Check err!
} }
static void
ag_window_export_svg(AgWindow *window, GError **err)
{
gchar *name;
gchar *file_name;
GtkWidget *fs;
gint response;
recalculate_chart(window);
// We should never enter here, but who knows...
if (window->priv->chart == NULL) {
GtkWidget *dialog;
dialog = gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Chart cannot be calculated."));
gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
g_set_error(err, AG_WINDOW_ERROR, AG_WINDOW_ERROR_EMPTY_CHART, "Chart is empty");
return;
}
name = ag_chart_get_name(window->priv->chart);
if ((name == NULL) || (*name == 0)) {
GtkWidget *dialog;
g_free(name);
dialog = gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("You must enter a name before saving a chart."));
gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
g_set_error(err, AG_WINDOW_ERROR, AG_WINDOW_ERROR_NO_NAME, "No name specified");
return;
}
file_name = g_strdup_printf("%s.svg", name);
g_free(name);
fs = gtk_file_chooser_dialog_new(_("Export Chart as SVG"),
GTK_WINDOW(window),
GTK_FILE_CHOOSER_ACTION_SAVE,
_("_Cancel"), GTK_RESPONSE_CANCEL,
_("_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);
gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(fs), file_name);
g_free(file_name);
response = gtk_dialog_run(GTK_DIALOG(fs));
gtk_widget_hide(fs);
if (response == GTK_RESPONSE_ACCEPT) {
GFile *file = gtk_file_chooser_get_file(GTK_FILE_CHOOSER(fs));
ag_chart_export_svg_to_file(window->priv->chart, file, err);
}
gtk_widget_destroy(fs);
}
static void
ag_window_export_svg_action(GSimpleAction *action, GVariant *parameter, gpointer user_data)
{
AgWindow *window = AG_WINDOW(user_data);
GError *err = NULL;
ag_window_export_svg(window, &err);
// TODO: Check err!
}
void void
ag_window_redraw_chart(AgWindow *window) ag_window_redraw_chart(AgWindow *window)
{ {
GError *err = NULL; GError *err = NULL;
gchar *svg_content; gchar *svg_content;
GList *planet_list,
*planet1,
*planet2;
guint i,
j;
svg_content = ag_chart_create_svg(window->priv->chart, &err); svg_content = ag_chart_create_svg(window->priv->chart, NULL, &err);
if (svg_content == NULL) { if (svg_content == NULL) {
g_warning("%s", err->message); GtkWidget *dialog;
dialog = gtk_message_dialog_new(GTK_WINDOW(window), 0, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, "Unable to draw chart: %s", err->message);
gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
} else { } else {
webkit_web_view_load_string(WEBKIT_WEB_VIEW(window->priv->tab_chart), svg_content, "image/svg+xml", "UTF-8", "file://"); webkit_web_view_load_string(WEBKIT_WEB_VIEW(window->priv->tab_chart), svg_content, "image/svg+xml", "UTF-8", "file://");
g_free(svg_content); g_free(svg_content);
} }
planet_list = ag_chart_get_planets(window->priv->chart);
if (window->priv->aspect_table_populated == FALSE) {
GList *planet;
guint i;
for (planet = planet_list, i = 0; planet; planet = g_list_next(planet), i++) {
GtkWidget *label_hor,
*label_ver;
GswePlanet planet_id;
GswePlanetData *planet_data;
GswePlanetInfo *planet_info;
planet_id = GPOINTER_TO_INT(planet->data);
planet_data = gswe_moment_get_planet(GSWE_MOMENT(window->priv->chart), planet_id, NULL);
planet_info = gswe_planet_data_get_planet_info(planet_data);
label_hor = gtk_label_new(gswe_planet_info_get_name(planet_info));
gtk_grid_attach(GTK_GRID(window->priv->tab_aspects), label_hor, i + 1, i, 1, 1);
if (i > 0) {
label_ver = gtk_label_new(gswe_planet_info_get_name(planet_info));
gtk_grid_attach(GTK_GRID(window->priv->tab_aspects), label_ver, 0, i, 1, 1);
}
}
window->priv->aspect_table_populated = TRUE;
}
for (planet1 = planet_list, i = 0; planet1; planet1 = g_list_next(planet1), i++) {
for (planet2 = planet_list, j = 0; planet2; planet2 = g_list_next(planet2), j++) {
GsweAspectData *aspect;
GError *err = NULL;
if (GPOINTER_TO_INT(planet1->data) == GPOINTER_TO_INT(planet2->data)) {
break;
}
if ((aspect = gswe_moment_get_aspect_by_planets(GSWE_MOMENT(window->priv->chart), GPOINTER_TO_INT(planet1->data), GPOINTER_TO_INT(planet2->data), &err)) != NULL) {
GsweAspectInfo *aspect_info;
GtkWidget *aspect_label;
aspect_info = gswe_aspect_data_get_aspect_info(aspect);
aspect_label = gtk_grid_get_child_at(GTK_GRID(window->priv->tab_aspects), j + 1, i);
if (gswe_aspect_data_get_aspect(aspect) == GSWE_ASPECT_NONE) {
if (aspect_label != NULL) {
gtk_container_remove(GTK_CONTAINER(window->priv->tab_aspects), aspect_label);
}
} else {
if (aspect_label == NULL) {
aspect_label = gtk_label_new(gswe_aspect_info_get_name(aspect_info));
gtk_grid_attach(GTK_GRID(window->priv->tab_aspects), aspect_label, j + 1, i, 1, 1);
} else {
gtk_label_set_label(GTK_LABEL(aspect_label), gswe_aspect_info_get_name(aspect_info));
}
}
} else if (err) {
g_warning("%s\n", err->message);
} else {
g_error("No aspect is returned between two planets. This is a bug in SWE-GLib!\n");
}
}
}
gtk_widget_show_all(window->priv->tab_aspects);
} }
void void
@ -189,8 +351,19 @@ ag_window_update_from_chart(AgWindow *window)
gtk_spin_button_set_value(GTK_SPIN_BUTTON(window->priv->hour), gswe_timestamp_get_gregorian_hour(timestamp, NULL)); gtk_spin_button_set_value(GTK_SPIN_BUTTON(window->priv->hour), gswe_timestamp_get_gregorian_hour(timestamp, NULL));
gtk_spin_button_set_value(GTK_SPIN_BUTTON(window->priv->minute), gswe_timestamp_get_gregorian_minute(timestamp, NULL)); gtk_spin_button_set_value(GTK_SPIN_BUTTON(window->priv->minute), gswe_timestamp_get_gregorian_minute(timestamp, NULL));
gtk_spin_button_set_value(GTK_SPIN_BUTTON(window->priv->second), gswe_timestamp_get_gregorian_second(timestamp, NULL)); gtk_spin_button_set_value(GTK_SPIN_BUTTON(window->priv->second), gswe_timestamp_get_gregorian_second(timestamp, NULL));
gtk_spin_button_set_value(GTK_SPIN_BUTTON(window->priv->longitude), coordinates->longitude); gtk_spin_button_set_value(GTK_SPIN_BUTTON(window->priv->timezone), gswe_timestamp_get_gregorian_timezone(timestamp));
gtk_spin_button_set_value(GTK_SPIN_BUTTON(window->priv->latitude), coordinates->latitude); gtk_spin_button_set_value(GTK_SPIN_BUTTON(window->priv->longitude), fabs(coordinates->longitude));
if (coordinates->longitude < 0.0) {
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(window->priv->west_long), TRUE);
}
gtk_spin_button_set_value(GTK_SPIN_BUTTON(window->priv->latitude), fabs(coordinates->latitude));
if (coordinates->latitude < 0.0) {
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(window->priv->south_lat), TRUE);
}
gtk_entry_set_text(GTK_ENTRY(window->priv->name), ag_chart_get_name(window->priv->chart)); gtk_entry_set_text(GTK_ENTRY(window->priv->name), ag_chart_get_name(window->priv->chart));
g_free(coordinates); g_free(coordinates);
@ -244,19 +417,19 @@ recalculate_chart(AgWindow *window)
// TODO: make house system configurable // TODO: make house system configurable
window->priv->chart = ag_chart_new_full(timestamp, longitude, latitude, 380.0, GSWE_HOUSE_SYSTEM_PLACIDUS); window->priv->chart = ag_chart_new_full(timestamp, longitude, latitude, 380.0, GSWE_HOUSE_SYSTEM_PLACIDUS);
g_signal_connect(window->priv->chart, "changed", G_CALLBACK(chart_changed), window); g_signal_connect(window->priv->chart, "changed", G_CALLBACK(chart_changed), window);
ag_window_redraw_chart(window);
} else { } else {
timestamp = gswe_moment_get_timestamp(GSWE_MOMENT(window->priv->chart)); timestamp = gswe_moment_get_timestamp(GSWE_MOMENT(window->priv->chart));
gswe_timestamp_set_gregorian_full(timestamp, year, month, day, hour, minute, second, 0, 1.0, NULL); gswe_timestamp_set_gregorian_full(timestamp, year, month, day, hour, minute, second, 0, 1.0, NULL);
} }
ag_chart_set_name(window->priv->chart, gtk_entry_get_text(GTK_ENTRY(window->priv->name))); ag_chart_set_name(window->priv->chart, gtk_entry_get_text(GTK_ENTRY(window->priv->name)));
ag_window_redraw_chart(window);
} }
static void static void
tab_changed_cb(GdStack *stack, GParamSpec *pspec, AgWindow *window) tab_changed_cb(GtkStack *stack, GParamSpec *pspec, AgWindow *window)
{ {
const gchar *active_tab_name = gd_stack_get_visible_child_name(stack); const gchar *active_tab_name = gtk_stack_get_visible_child_name(stack);
GtkWidget *active_tab; GtkWidget *active_tab;
g_debug("Active tab changed: %s", active_tab_name); g_debug("Active tab changed: %s", active_tab_name);
@ -265,13 +438,18 @@ tab_changed_cb(GdStack *stack, GParamSpec *pspec, AgWindow *window)
return; return;
} }
active_tab = gd_stack_get_visible_child(stack); active_tab = gtk_stack_get_visible_child(stack);
if (strcmp("chart", active_tab_name) == 0) { if (strcmp("chart", active_tab_name) == 0) {
gtk_widget_set_size_request(active_tab, 600, 600); gtk_widget_set_size_request(active_tab, 600, 600);
} }
// Note that priv->current_tab is actually the previously selected tab, not the real active one! // If we are coming from the Edit tab, lets assume the chart data has
// changed. This is a bad idea, though, it should be checked instead!
// (TODO)
// Note that priv->current_tab is actually the previously selected tab, not
// the real active one!
if (window->priv->current_tab == window->priv->tab_edit) { if (window->priv->current_tab == window->priv->tab_edit) {
recalculate_chart(window); recalculate_chart(window);
} }
@ -285,7 +463,7 @@ ag_window_change_tab_action(GSimpleAction *action, GVariant *parameter, gpointer
AgWindow *window = user_data; AgWindow *window = user_data;
const gchar *target_tab = g_variant_get_string(parameter, NULL); const gchar *target_tab = g_variant_get_string(parameter, NULL);
gd_stack_set_visible_child_name(GD_STACK(window->priv->stack), target_tab); gtk_stack_set_visible_child_name(GTK_STACK(window->priv->stack), target_tab);
g_action_change_state(G_ACTION(action), parameter); g_action_change_state(G_ACTION(action), parameter);
} }
@ -293,6 +471,7 @@ static GActionEntry win_entries[] = {
{ "close", ag_window_close_action, NULL, NULL, NULL }, { "close", ag_window_close_action, NULL, NULL, NULL },
{ "save", ag_window_save_action, NULL, NULL, NULL }, { "save", ag_window_save_action, NULL, NULL, NULL },
{ "save-as", ag_window_save_as_action, NULL, NULL, NULL }, { "save-as", ag_window_save_as_action, NULL, NULL, NULL },
{ "export-svg", ag_window_export_svg_action, NULL, NULL, NULL },
{ "gear-menu", ag_window_gear_menu_action, NULL, "false", NULL }, { "gear-menu", ag_window_gear_menu_action, NULL, "false", NULL },
{ "change-tab", ag_window_change_tab_action, "s", "'edit'", NULL }, { "change-tab", ag_window_change_tab_action, "s", "'edit'", NULL },
}; };
@ -304,7 +483,7 @@ ag_window_init(AgWindow *window)
GtkAccelGroup *accel_group; GtkAccelGroup *accel_group;
GError *err = NULL; GError *err = NULL;
window->priv = priv = GET_PRIVATE(window); window->priv = priv = ag_window_get_instance_private(window);
priv->chart = NULL; priv->chart = NULL;
priv->uri = NULL; priv->uri = NULL;
@ -347,7 +526,6 @@ ag_window_class_init(AgWindowClass *klass)
{ {
GObjectClass *gobject_class = G_OBJECT_CLASS(klass); GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
g_type_class_add_private(klass, sizeof(AgWindowPrivate));
gobject_class->dispose = ag_window_dispose; gobject_class->dispose = ag_window_dispose;
} }
@ -441,6 +619,14 @@ notebook_edit(AgWindow *window)
gtk_spin_button_set_digits(GTK_SPIN_BUTTON(priv->second), 0); gtk_spin_button_set_digits(GTK_SPIN_BUTTON(priv->second), 0);
gtk_grid_attach(GTK_GRID(grid), priv->second, 6, 4, 1, 1); gtk_grid_attach(GTK_GRID(grid), priv->second, 6, 4, 1, 1);
label = gtk_label_new(_("Timezone"));
gtk_grid_attach(GTK_GRID(grid), label, 4, 5, 1, 1);
priv->timezone = gtk_spin_button_new_with_range(-12.0, 12.0, 1.0);
gtk_spin_button_set_digits(GTK_SPIN_BUTTON(priv->timezone), 1);
gtk_spin_button_set_value(GTK_SPIN_BUTTON(priv->timezone), 0.0);
gtk_grid_attach(GTK_GRID(grid), priv->timezone, 5, 5, 1, 1);
gtk_widget_show_all(grid); gtk_widget_show_all(grid);
return grid; return grid;
@ -456,56 +642,60 @@ static void
window_populate(AgWindow *window) window_populate(AgWindow *window)
{ {
AgWindowPrivate *priv = window->priv; AgWindowPrivate *priv = window->priv;
GtkWidget *menu_button; GtkWidget *menu_button,
GtkWidget *scroll; *scroll;
GObject *menu; GObject *menu;
priv->header_bar = gd_header_bar_new(); priv->header_bar = gtk_header_bar_new();
gtk_widget_set_hexpand(priv->header_bar, TRUE); gtk_widget_set_hexpand(priv->header_bar, TRUE);
menu_button = gd_header_menu_button_new(); menu_button = gtk_menu_button_new();
gd_header_button_set_symbolic_icon_name(GD_HEADER_BUTTON(menu_button), "emblem-system-symbolic");
gtk_actionable_set_action_name(GTK_ACTIONABLE(menu_button), "win.gear-menu"); gtk_actionable_set_action_name(GTK_ACTIONABLE(menu_button), "win.gear-menu");
gd_header_bar_pack_end(GD_HEADER_BAR(priv->header_bar), menu_button); gtk_header_bar_pack_end(GTK_HEADER_BAR(priv->header_bar), menu_button);
gtk_grid_attach(GTK_GRID(priv->grid), priv->header_bar, 0, 0, 1, 1); gtk_grid_attach(GTK_GRID(priv->grid), priv->header_bar, 0, 0, 1, 1);
menu = gtk_builder_get_object(priv->builder, "window-menu"); menu = gtk_builder_get_object(priv->builder, "window-menu");
gtk_menu_button_set_menu_model(GTK_MENU_BUTTON(menu_button), G_MENU_MODEL(menu)); gtk_menu_button_set_menu_model(GTK_MENU_BUTTON(menu_button), G_MENU_MODEL(menu));
priv->stack = gd_stack_new(); priv->stack = gtk_stack_new();
gtk_widget_set_hexpand(priv->stack, TRUE); gtk_widget_set_hexpand(priv->stack, TRUE);
gtk_widget_set_vexpand(priv->stack, TRUE); gtk_widget_set_vexpand(priv->stack, TRUE);
gtk_grid_attach(GTK_GRID(priv->grid), priv->stack, 0, 1, 1, 1); gtk_grid_attach(GTK_GRID(priv->grid), priv->stack, 0, 1, 1, 1);
g_signal_connect(priv->stack, "notify::visible-child", G_CALLBACK(tab_changed_cb), window); g_signal_connect(priv->stack, "notify::visible-child", G_CALLBACK(tab_changed_cb), window);
priv->stack_switcher = gd_stack_switcher_new(); priv->stack_switcher = gtk_stack_switcher_new();
gd_stack_switcher_set_stack(GD_STACK_SWITCHER(priv->stack_switcher), GD_STACK(priv->stack)); gtk_stack_switcher_set_stack(GTK_STACK_SWITCHER(priv->stack_switcher), GTK_STACK(priv->stack));
priv->tab_edit = notebook_edit(window); priv->tab_edit = notebook_edit(window);
gd_stack_add_titled(GD_STACK(priv->stack), priv->tab_edit, "edit", _("Edit")); gtk_stack_add_titled(GTK_STACK(priv->stack), priv->tab_edit, "edit", _("Edit"));
scroll = gtk_scrolled_window_new(NULL, NULL); scroll = gtk_scrolled_window_new(NULL, NULL);
g_object_set(scroll, "shadow-type", GTK_SHADOW_IN, NULL); g_object_set(scroll, "shadow-type", GTK_SHADOW_IN, NULL);
gd_stack_add_titled(GD_STACK(priv->stack), scroll, "chart", _("Chart")); gtk_stack_add_titled(GTK_STACK(priv->stack), scroll, "chart", _("Chart"));
priv->tab_chart = webkit_web_view_new(); priv->tab_chart = webkit_web_view_new();
g_signal_connect(priv->tab_chart, "context-menu", G_CALLBACK(ag_window_chart_context_cb), NULL); g_signal_connect(priv->tab_chart, "context-menu", G_CALLBACK(ag_window_chart_context_cb), NULL);
gtk_container_add(GTK_CONTAINER(scroll), priv->tab_chart); gtk_container_add(GTK_CONTAINER(scroll), priv->tab_chart);
// TODO: Although this is never shown to the user, it should be translatable!
webkit_web_view_load_string(WEBKIT_WEB_VIEW(priv->tab_chart), "<html><head><title>No Chart</title></head><body><h1>No Chart</h1><p>No chart is loaded. Create one on the edit view, or open one from the application menu!</p></body></html>", "text/html", "UTF-8", NULL); webkit_web_view_load_string(WEBKIT_WEB_VIEW(priv->tab_chart), "<html><head><title>No Chart</title></head><body><h1>No Chart</h1><p>No chart is loaded. Create one on the edit view, or open one from the application menu!</p></body></html>", "text/html", "UTF-8", NULL);
gtk_widget_set_size_request(priv->tab_chart, 600, 600); gtk_widget_set_size_request(priv->tab_chart, 600, 600);
priv->tab_aspects = gtk_label_new("PLACEHOLDER FOR THE ASPECTS TABLE"); scroll = gtk_scrolled_window_new(NULL, NULL);
gd_stack_add_titled(GD_STACK(priv->stack), priv->tab_aspects, "aspects", _("Aspects")); g_object_set(scroll, "shadow-type", GTK_SHADOW_NONE, NULL);
gtk_stack_add_titled(GTK_STACK(priv->stack), scroll, "aspects", _("Aspects"));
priv->tab_aspects = gtk_grid_new();
gtk_container_add(GTK_CONTAINER(scroll), priv->tab_aspects);
priv->tab_points = gtk_label_new("PLACEHOLDER FOR THE POINTS TABLES"); priv->tab_points = gtk_label_new("PLACEHOLDER FOR THE POINTS TABLES");
gd_stack_add_titled(GD_STACK(priv->stack), priv->tab_points, "points", _("Points")); gtk_stack_add_titled(GTK_STACK(priv->stack), priv->tab_points, "points", _("Points"));
/* TODO: change to the Chart tab if we are opening an existing chart! */ /* TODO: change to the Chart tab if we are opening an existing chart! */
gd_stack_set_visible_child_name(GD_STACK(priv->stack), "edit"); gtk_stack_set_visible_child_name(GTK_STACK(priv->stack), "edit");
priv->current_tab = priv->tab_edit; priv->current_tab = priv->tab_edit;
gd_header_bar_set_custom_title(GD_HEADER_BAR(priv->header_bar), priv->stack_switcher); gtk_header_bar_set_custom_title(GTK_HEADER_BAR(priv->header_bar), priv->stack_switcher);
gtk_widget_show_all(priv->grid); gtk_widget_show_all(priv->grid);
} }

View File

@ -8,10 +8,10 @@
#include <libxslt/transform.h> #include <libxslt/transform.h>
#include <libexslt/exslt.h> #include <libexslt/exslt.h>
#include <libgd/gd.h>
#include <swe-glib.h> #include <swe-glib.h>
#include "config.h"
#include "ag-app.h" #include "ag-app.h"
#include "ag-window.h" #include "ag-window.h"

View File

@ -46,6 +46,12 @@
<attribute name="accel">&lt;Primary&gt;&lt;Shift&gt;s</attribute> <attribute name="accel">&lt;Primary&gt;&lt;Shift&gt;s</attribute>
</item> </item>
</section> </section>
<section>
<item>
<attribute name="label" translatable="yes">Export as SVG</attribute>
<attribute name="action">win.export-svg</attribute>
</item>
</section>
<section> <section>
<item> <item>
<attribute name="label" translatable="yes">Close</attribute> <attribute name="label" translatable="yes">Close</attribute>